本文来自尚妆前端团队南洋

发表于尚妆博客,欢迎订阅。

图片流量优化

刷新一个页面消耗的流量除了脚本样式文件以外,大头其实在下载的图片。一张图片动辄几十kb,想尽办法优化样式、脚本文件所优化的图片流量其实还不如一张图片大。

本文从两个角度介绍如何对图片流量进行优化。本文进行图片流量优化的前提都是对于移动端而言。

webp

首先从图片格式方面着手,webp(google官方网址)是谷歌推出的一种图片格式,优点在于同等画面质量下,体积比jpg、png少了25%以上。以两张jpg、png图片为例:

  1. JPG cdn1.showjoy.com/images/c9/c…

  2. PNG cdn1.showjoy.com/images/bb/b…

size JPG PNG
无压缩 165kb 55kb
tinypng压缩 75kb 20kb
webp转换 54kb 6.1kb

由表格的罗列可知,将图片转换为webp格式,图片的体积比tinypng压缩完后的体积还要小,且图片质量甚至还要高于tinypng压缩。

虽然webp格式的图片相对于png和jpg体积小质量高,但是目前的兼容性在全球范围只达到了70%左右。(caniuse截止20160911)

根据caniuse,目前在移动端安卓机型4.4以上全部支持,但是ios全军覆灭。我司用户ios、安卓55分成,支持了webp至少能为一半用户提供更小体积的图片体验。而且据说ios10系统将支持webp,这样一来我司产品的webp支持度将会更高。ios10有望支持webp

图片服务器支持webp转换

我司原本就有基于nginx+lua+graphicsmagick的图片缩略图功能,具体使用方法类似

http://cdn1.shwojoy.com/images/34/xxxxx.png

http://cdn1.shwojoy.com/images/34/xxxxx.png.300x300.png

为了支持webp转换需要修改原先的lua脚本,添加对.webp后缀的识别。使之能对类似xxxxx.png.300x300.png.webp或者xxxxx.png.webp这样的域名进行识别并转换。

nginx+lua+graphicsmagick这套方案其实做的事情就是nginx对域名进行拦截,lua脚本进行域名后缀规则的匹配,比如说300x300.png/.webp类似的后缀,匹配完成后再在lua里调用graphicsmagick的命令,进行一些图片转换、裁剪等工作。

lua脚本片段

if table.isLegal(size_list) and extend == "webp" thencommand = [[/usr/local/GraphicsMagick-1.3.25/bin/gm convert -quality 75 -density 72 +profile "*"  ]] .. ngx.var.image_root ..  originalUri  .. " -geometry " .. area .. " " .. ngx.var.file;os.execute(command);
end复制代码

值得注意的是graphicsmagick版本在1.3.20及以上才支持webp download

graphicsmagick能做到转换webp还需要下载编译libwebp。graphicsmagick支持webp教程

图片服务器支持webp转换后,就能实时转化webp格式的图片了,为接下来的webp兼容方案提供了技术支持。

  • cdn1.showjoy.com/images/c9/c…
  • cdn1.showjoy.com/images/c9/c…

webp兼容方案

目前在浏览器端判断是否支持webp最好的方法就是特性检测法。根据检测结果将是否支持webp的值存入cookie,供之后需要判断webp兼容性的地方使用。

特性检测脚本:(参考)

;(function(doc) {// 给html根节点加上webps类名function addRootTag() {doc.documentElement.className += " webpa";}// 判断是否有webp_showjoy=available这个cookieif (!/webp_showjoy=available/.test(document.cookie)) {var image = new Image();// 图片加载完成时候的操作image.onload = function() {// 图片加载成功且宽度为1,那么就代表支持webp了,因为这张base64图是webp格式。如果不支持会触发image.error方法if (image.width == 1) {// html根节点添加class,并且埋入cookieaddRootTag();document.cookie = "webp_showjoy=available; max-age=31536000; domain=";}};// 一张支持alpha透明度的webp的图片,使用base64编码image.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==';} else {addRootTag();}}(document));复制代码

如果浏览器支持webp格式的图片则在cookie中设置标志,并且在html标签上设置webpaclassName,这个classname的作用是在less文件中兼容webp图片。

less文件中的webp兼容

.webpbg(@url) {background-image: url(@url);.webpa & {background-image: url('@{url}.webp');}
}复制代码

这段less取代了原先在less文件中描述背景图片的代码。

比如原先定义背景图片

div {background-image: url(xx);
}复制代码

现在使用兼容方案则为:

div {webpbg(xxx);
}复制代码

html文件中的webp图片兼容

我司目前html部分通过java的velocity编写,对于同步传递到页面上的图片webp将通过如下方式兼容。

<img class="slider-img" src="$!{banner.recordMap.get('图片地址').value}.750x448.jpg$!{isWebp}">复制代码

$!{isWebp} 变量是后台通过判断浏览器请求的cookie中是否有之前定义的webp_showjoy=available,有则返回.webp后缀,无则返回空。

这样有个问题是用户第一次浏览产品页面时后台判断cookie永远是false,所以用户第一次浏览是不可能返回.webp后缀的图片的。

还有一种情况是图片大量使用的时候我们会使用懒加载进行图片的延迟加载。这时就可以修改懒加载插件,在插件里动态兼容webp图片了。

/* 根据cookie返回图片是否webp的地址 */
function getwebpsrc (imgsrc) {var needwebp = false,src = '';if (/webp_showjoy=available/.test(document.cookie)) {needwebp = true;}src = needwebp ? imgsrc + '.webp' : imgsrc;return src;
}复制代码

到此就完成了移动端对webp格式图片的支持。这也是图片流量优化其中之一方案。

retina兼容图片流量优化

前端应该都了解在retina屏下应该使用@2x或者@3x等倍率的图片,才能保证图片的清晰度。但是为了切图方便,部分公司都会统一在切图阶段切出@2x的图片,不管浏览设备是retina屏还是普通屏,一律都使用@2x的图片。这样做有两个坏处,一是@2x的图片在非retina屏下会出现downsampled现象,虽然不会影响清晰度,但是会缺少一些锐利度。二是@2x的图片相比较@1x的图片,前者体积大于后者,这也就造成了流量的浪费以及影响页面打开性能。

所以正确处理方法是针对retina屏的是否采用不同尺寸的图片。图片裁剪已经在图片服务器上实现。在考虑retina时也需要加上webp的兼容,两者一起作用会大大减少图片的尺寸。

@2x http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png.300x300.png.webp
@1x http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png.150x150.png.webp复制代码

less文件兼容retina

.retinabg(@file-2x; @reg-2x; @reg-1x; @type) when (isstring(@reg-2x)) {background-image: url("@{file-2x}.@{reg-1x}.@{type}");.webpa & {background-image: url('@{file-2x}.@{reg-1x}.@{type}.webp');}@mediaonly screen and (-webkit-min-device-pixel-ratio: 2),only screen and (   min--moz-device-pixel-ratio: 2),only screen and (     -o-min-device-pixel-ratio: 2/1),only screen and (        min-device-pixel-ratio: 2),only screen and (                min-resolution: 192dpi),only screen and (                min-resolution: 2dppx) {background-image: url("@{file-2x}.@{reg-2x}.@{type}");.webpa & {background-image: url('@{file-2x}.@{reg-2x}.@{type}.webp');}}
}复制代码

当要代替原先书写时的background-image: url(),可以写成如下方式:

.retinabg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png; 300x300; 150x150; png)复制代码

html文件兼容retina

在html中本次方案准备使用html5特性srcset属性。

secset属性的目的在于允许开发者为某个图片的属性指定一系列的来源,其中这些图片的来源是要根据客户端显示屏的像素分辨率来设定的。

比如在volecity模板中定义图片资源:

<img class="pic" src="$!{newProduct.image}.300x300.png$!{isWebp}" srcset="$!{newProduct.image}.150x150.png$!{isWebp} 1x, $!{newProduct.image}.300x300.png$!{isWebp} 2x">复制代码

这段图片定义说明了在retina(2x)屏幕下使用300x300的图片来源,而在飞retina屏下(1x)下使用150x150的图。

html中懒加载的图片

由于懒加载的图片在插件中就会进行src赋值的操作,所以直接在懒加载插件中根据window.devicePixelRatio进行判断修改图片url。

/* 根据cookie返回图片是否webp的地址 */
/* 根据dpr返回不同尺寸的图片 */
function getwebpsrc (imgsrc) {var areaInfo = '';if (window.devicePixelRatio && window.devicePixelRatio <= 1) {var area = imgsrc.match(/[0-9]+x[0-9]+/);if (area) {var areaSplit = area[0].split('x');areaInfo = areaSplit[0] /2 + 'x' + areaSplit[1] /2;imgsrc = imgsrc.replace(/[0-9]+x[0-9]+/, areaInfo)}}var needwebp = false,src = '';if (/webp_showjoy=available/.test(document.cookie)) {needwebp = true;}src = needwebp ? imgsrc + '.webp' : imgsrc;return src;
}复制代码

在这个方案下所有图片的编写都必须要带上尺寸后缀(_num_x_num_),在我司图片服务器支持下还有一个特别的好处:图片服务器会对带有尺寸后缀的图片进行尺寸裁剪的同时进行图片压缩,遇到不支持webp格式的浏览器上就会顺带对图片进行压缩,尽力地减小图片体积。

srcset属性目前在移动端的兼容性十分不错,安卓4.x版本不支持。

总结

一共两点图片流量优化方案,一是针对webp图片格式,二是针对retina。最后总结下来的编写图片代码的情景就为3种:

1.html同步图片编写

<img class="pic" src="$!{newProduct.image}.300x300.png$!{isWebp}" srcset="$!{newProduct.image}.150x150.png$!{isWebp} 1x, $!{newProduct.image}.300x300.png$!{isWebp} 2x">复制代码

2.懒加载图片编写

<img class="goods-pic j_Lazyload" data-original="{{$value.image}}.300x300.png" src="http://cdn1.showjoy.com/images/a5/a560e106324d4670acd11b69aee0f11f.png">复制代码

3.less

.retinabg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png; 300x300; 150x150; png)webpbg(http://cdn1.showjoy.com/images/bb/bb1c8b0d275e4ba2903dc822a03add50.png);复制代码

对我以上的理解有疑问和意见的欢迎找我私聊~微博-写前端的暹罗

「前端」webp图片适配流量优化 1相关推荐

  1. 「前端」webp图片适配流量优化

    本文来自尚妆前端团队南洋 发表于尚妆博客,欢迎订阅. 图片流量优化 刷新一个页面消耗的流量除了脚本样式文件以外,大头其实在下载的图片.一张图片动辄几十kb,想尽办法优化样式.脚本文件所优化的图片流量其 ...

  2. webp图片适配流量优化

    转自这里写链接内容 图片流量优化 刷新一个页面消耗的流量除了脚本样式文件以外,大头其实在下载的图片.一张图片动辄几十kb,想尽办法优化样式.脚本文件所优化的图片流量其实还不如一张图片大. 本文从两个角 ...

  3. 「ImageMagick」- 在图片上添加文字(批量操作) @20210401

    问题描述 我们有百张图片,需要将文件名添加到图片上,那实际上就是如何向多张图片添加文字.我们并不懂得 Photoshop 之类的图片处理软件该如何操作. 该笔记将记录:如何通过命令行批量为文件添加文本 ...

  4. 「前端」微信获取openId,静默授权与非静默授权

    首先了解一下静默与非静默授权的区别 静默授权「snsapi_base」 以 snsapi_base 为 scope 发起的网页授权,不用用户手动授权,跳转授权回到回调页面,只能获取用户openId 非 ...

  5. 「前端」History API与浏览器历史堆栈管理

    本文由尚妆前端开发工程师欲休撰写 本文发表于尚妆博客,欢迎订阅! 移动端开发在某些场景中有着特殊需求,如为了提高用户体验和加快响应速度,常常在部分工程采用SPA架构.传统的单页应用基于url的hash ...

  6. 「前端」看懂前端脚手架你需要这篇webpack

    本文来自尚妆前端团队南洋 发表于尚妆github博客,欢迎订阅. 分割webpack配置文件的多种方法 (一) 将你的配置信息写到多个分散的文件中去,然后在执行webpack的时候利用--config ...

  7. pandas 读取csv_「技巧」Pandas常见的性能优化方法

    来源: Datawhale 作者: 阿水 Pandas是数据科学和数据竞赛中常见的库,我们使用Pandas可以进行快速读取数据.分析数据.构造特征.但Pandas在使用上有一些技巧和需要注意的地方,如 ...

  8. Study「Photoshop」:图片去噪点

    桌面壁纸好久没换了,于是乎网上找了张好看的图片,可惜图片噪点太多,就在网上学习了一下用 Photoshop 去除图片噪点,这里做一下简单记录,方便以后用到时回顾. 一.图片噪点 图像噪声(image ...

  9. 「APIO2010」 特别行动队 - 斜率优化Dp

    题目描述 你有一支由nnn名预备役士兵组成的部队,士兵从1到nnn编号,要将他们拆分成若干特别行动队调入战场.出于默契考虑,同一支特别行动队中队员的编号应该连续,即为形如(i,i+1,...,i+k) ...

最新文章

  1. 深度学习环境配置指南!(Windows、Mac、Ubuntu全讲解)
  2. 2019全球AI人才分布图:美国占44%,中国人才净流入
  3. python如何执行代码漏洞_织梦dedecms最新远程代码执行利用脚本(python)
  4. python写电脑程序_【初学者教程】在电脑上安装Python,写第一个程序
  5. linux更改桌面壁纸的脚本,自动更换桌面壁纸的脚本,支持Ubuntu 18.04系统
  6. 儿童的身高标准对照表_2020“儿童身高标准”出炉,10岁身高140,你家娃达标吗...
  7. MC新手入门(二十八)------ 顺序结构程序
  8. 10 亿产业基金加持,让精准定位在物联网应用中实现无限可能!
  9. intellij idea 在什么地方打开终端Terminal
  10. 怎样有效的学会php,十天学会PHP - 序2,有效的学习方法 (20180822-1)
  11. oracle 某一字段取反
  12. sql添加字段和字段说明
  13. SC-FDE 系统 基于导频的细小偏估计
  14. Pr视频剪辑出现红线
  15. 天地图和谷歌地图静态图像素坐标和经纬度坐标互转
  16. -webkit-内核兼容处理
  17. 【JZOJ3337】wyl8899的TLE
  18. 一起Talk Android吧(第三百一十七回:Android中的虚拟按键)
  19. 163企业邮箱申请,163企业邮箱注册方法
  20. MIT线性代数笔记九 线性无关,基和维度

热门文章

  1. csv文件和excel文件
  2. 应用先进的传感器和算法进行低成本运动跟踪---凯利讯半导体
  3. 浅析私有化即时通讯软件的功能
  4. 中e管家投资理财做好这六件事
  5. P2495 [SDOI2011]消耗战 虚树入门
  6. 淮北师范大学计算机科学与技术专业属于,淮北师范大学计算机科学与技术学院...
  7. IBM中高端阵列增加STEC MLC固态硬盘支持
  8. [LeetCode周赛复盘] 第 314 场周赛20221009
  9. codeforces 314 (Div 1) 题解
  10. Google创始人---谢尔盖-布林