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

news/2024/9/8 5:48:05/

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

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

图片流量优化

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

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

webp

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

  1. JPG http://cdn1.showjoy.com/image...

  2. PNG http://cdn1.showjoy.com/image...

sizeJPGPNG
无压缩165kb55kb
tinypng压缩75kb20kb
webp转换54kb6.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兼容方案提供了技术支持。

  • http://cdn1.showjoy.com/image...

  • http://cdn1.showjoy.com/image...

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);

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


http://www.ppmy.cn/news/145290.html

相关文章

IDEA(版本2020)启动错误

错误信息&#xff1a;在运行Java应用程序时&#xff0c;发现没有找到Java虚拟机(JVM)&#xff0c;并且需要手动设置JAVA_HOME环境变量。 idea启动时的提示如下&#xff1a; 解决方案如下&#xff1a; 确认已经安装了64位JDK&#xff0c;并且JDK的bin目录已经被添加到了系统的环…

如何对移动端的图片流量进行优化

刷新一个页面消耗的流量除了脚本样式文件以外&#xff0c;大头其实在下载的图片。一张图片动辄几十kb&#xff0c;想尽办法优化样式、脚本文件所优化的图片流量其实还不如一张图片大。 本文从两个角度介绍如何对图片流量进行优化。本文进行图片流量优化的前提都是对于移动端而言…

mysql jdbc resultset_JDBC——ResultSet结果集对象

ResultSet结果集对象&#xff0c;封装结果。它是怎么做到封装结果的呢&#xff1f; 游标&#xff0c;类似指针索引 最初指在“列名”上&#xff0c;要取到数据就需要让游标向下移动 移动后就指向了第一行数据&#xff0c;然后通过一些方法把第一行的每一列都取出来。 一次只能获…

CRBasic HTTP Digest authentication

CRBasic HTTP Digest authentication 最近在研究CRBasic&#xff0c;看了一下好像HTTP的digest digest authentication。试着进行书写。 CR6 Series DataloggerFor programming tips, copy this address to your browser search window:https://www.campbellsci.com/videos/da…

crash常用的调试命令

我的crash常用命令如下所示&#xff1a; log/dmesg: 打印出故障现场的kmsg缓冲区log_buf中的内容。 struct&#xff1a;展示结构体的定义&#xff0c;或者从指定的地址开始解析一个结构体。 union&#xff1a;与struct类似&#xff0c;但是用于union的展示 p&#xff1a;print…

未在此计算机上注册ActiveX控件{648A5600-2C6E-101B-82B6-000000000014}

1. 下载一个MSCOMM32.OCX放到C:\windows\system32下 2. 在命令行&#xff08;注意用管理员身份&#xff09;下进入到system32目录 3. 运行命令regsvr32 MSCOMM32.OCX 4. &#xff08;选做&#xff09;运行reg add "HKCR\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905…

Docker常用命令详解

帮助命令 #显示dcoker的版本信息 docker version #显示docker的系统信息&#xff0c;包括镜像和容器的数量 docker info #帮助命令 docker 命令 --help 镜像命令 docker images查看所有本地的主机上的镜像 [rootpractice ~]# docker imagesREPOSITORY TAG IMAGE I…

Fastjson blacklist

项目简介 Fastjson在1.2.42开始&#xff0c;把原本明文的黑名单改成了哈希过的黑名单&#xff0c;防止安全研究者对其进行研究。在 https://github.com/alibaba/fastjson/commit/eebea031d4d6f0a079c3d26845d96ad50c3aaccd这次commit中体现出来&#xff1a; Fastjson在1.2.61开…

关于跨线程操作GUI线程控件的疑问

单元测试能够帮助开发人员确保所开发的模块、类以及类中的方法等的正确性&#xff0c;在项目开发过程中&#xff0c;及时进行单元测试能够避免不必要的BUG以及提高测试效率。 在本文中&#xff0c;我们会分别来学习如何使用MSTest、xUnit以及NUnit这些流行的.NET测试框架来对.N…

cdr文字内容显示不出来_电脑装的字体cdr里面不显示怎么办

2020-04-30阅读(19) 本文主要为您介绍美国手机号注册微信没有钱包怎么办,内容包括国外手机号注册的微信没有钱包功能怎么办,国外手机号注册的微信没有钱包功能怎么处理,国外手机注册微信为什么没有钱包。微信在国内及国外布局有所不同,所以国外手机号码注册的账 2020-04-30…

笔记本计算机拆开视频,神州笔记本拆卸全过程图解

国内笔记本电脑市场中,有这样一个特立独行的品牌:对消费者而言,它总是以极具诱惑力的低价冲击着众人的眼球;而对其他品牌的厂商而言,由低价所产生的所谓极其优异的 性价比 被认为是整体销售市场中极其不协调的音符,这就是神舟系列笔记本电脑。下面就由学习啦小编跟大家分享神州…

python十六进制字符串转二进制_python2.7实现16进制转二进制数据

搜索ffd8ffdb找到了一个百度知道上的问题。 题主给出的16进制字符串如下 FFD8FFDB004300080404040404080404040808080808100C080808081410100C101814181818141818181C2420181C241C1818202C2024282828282818202C302C283024282828FFDB004301080808080808140C0C14281C181C28282828…

运维小白必学篇之基础篇第一集:Linux相关命令实验

Linux相关命令实验 实验者&#xff1a;胡 阳 命令提示符 【rootlocalhost ~】# 【当前登录系统的用户主机名 当前工作目录】提示符 &#xff08;# 表示 管理员&#xff09; &#xff08;&#xff04; 表示 普通用户&#xff09; 基本格式&#xff1a;命令 【选项】 【…

《菜狗商城》Springboot+Vue电商项目

菜狗商城 一 介绍 菜狗商城 一款SpringbootVue前后端分离架构的网络电商平台购物系统&#xff0c;包括用户登录&#xff0c;商品推荐&#xff0c;商品搜索&#xff0c;用户评价&#xff0c;购物车&#xff0c;添加订单&#xff0c;收货地址及微信支付等功能。 涉及技术&#xf…

SimpleITK使用——4. 奇怪的问题

文章目录 1. 数据dtype类型问题1.1 确定原因1.2 numpy中默认dtype类型1.3 itk-snap打开int64格式的问题2. 修改numpy array的dtype1. 数据dtype类型问题 1.1 确定原因 现象描述 windows下使用numpy处理Nifti图像并保存, 得到的图像是49KBITK-Snap可以打开linux下使用相同代码…

朋友们求助一个相关实际操作中的设计的问题

令狐冲在华山学艺时&#xff0c;虽然勤学苦练&#xff0c;但是终不得法&#xff0c;在机缘巧合之下&#xff0c;得到风清扬老前辈的真传&#xff0c;练成独孤九剑之后&#xff0c;才名震江湖。虽然笑傲江湖的故事情节是虚构的&#xff0c;但从令狐冲蜕变的过程可以看出&#xf…

饿了么太狠:面个高级Java,抖这多硬活、狠活(饿了么面试真题)

前言&#xff1a; 在40岁老架构师尼恩的&#xff08;50&#xff09;读者社群中&#xff0c;经常有小伙伴需要面试饿了么、 头条、美团、阿里、京东等大厂。有很多的小伙伴&#xff0c;完成了人生的逆袭&#xff0c;拿到了高端的offer。 最近一个6年经验的小伙伴&#xff0c;年…

Python编程面试题及答案(20例)

以下是一些常见的Python编程面试题以及它们的答案&#xff1a; 1.解释Python中的 GIL&#xff08;全局解释器锁&#xff09;是什么&#xff0c;它对多线程编程有什么影响&#xff1f; 答案&#xff1a;GIL是Python解释器中的一个机制&#xff0c;它确保在任何给定时间只有一个…

信道的数学模型

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 信道的数学模型广义…

俞浩“死磕”抖音,追觅科技618面临三变数

​文 | 智能相对论 作者 | 渡过 智能清洁“新秀”追觅科技来势汹汹。 创始人俞浩曾向媒体表示&#xff0c;“追觅科技……2023年做到行业技术第一&#xff0c;2024年做到行业市占率第一&#xff0c;2025年做到行业利润第一。” 具体到市场上&#xff0c;能拱火热度的电商节…