前端性能优化之路——图片篇。
本人是一名前端开发者,在公司负责目前负责信息流服务,为五大手机厂商和各大App提供服务,每天的请求就是以亿计算,加上我们又做了SSP和DSP,就是类似于百度广告联盟,腾讯广点通这种。接触过的应该知道,所以前端优化一直是我头痛的问题,不仅要注重用户体验,同时要兼顾收益,有时候必须牺牲一些用户体验,但是作为一名有思想的前端,还是努力规避掉,希望能和从事相同业务的同学一起学习交流一下,话不多说,就来分享我的性能优化之路,有什么不对的知识点,麻烦大家指出批评。
- 先附上基本的yahoo军规——yahoo前端性能团队总结的35条黄金定律
- web前端优化之图片优化
Media Queries 调用高清背景图
国内手机发展迅速,用 retina显示屏的越来越多,假如现在有一张图片,有两部手机,一部是普通显示屏,一部是高清显示屏,在同样大小的屏幕上,高清显示屏中的位图会被放大,图片会变得模糊。
通过 devicePixelRatio的值,就可以区分普通显示屏和高清屏,当devicePixelRatio值等于1时(也就是最小值),那么它普通显示屏,当devicePixelRatio值大于1(通常是1.5、2.0),那么它就是高清显示屏。这时候我们可以让UI准备2套图片,甚至是3套图片,不同像素的图利用媒体查询结合 devicePixelRatio 可以区分普通显示屏和高清显示屏,并给出了如下CSS设计方案:
.css{/* 普通显示屏(设备像素比例小于等于1.3)使用1倍的图 */ background-image: url(img_1x.png); } @media only screen and (-webkit-min-device-pixel-ratio:1.5){ .css{/* 高清显示屏(设备像素比例大于等于1.5)使用2倍图 */ background-image: url(img_2x.png); } }
也可以用less或者sass
bg-image($url) background-image: url($url + "@2x.png") @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) background-image: url($url + "@3x.png")
如果省时间通用性高,就像我们是服务端用nginx对图片进行处理,想要什么样尺寸的图片自己裁切,我们提供了按比例缩放和自定尺寸的裁切方法,地址后拼接字符串就行。
http://image.uczzd.cn/12046251381056834816.jpg?id=0&from=export&width=800&height=600
- 使用更小更快更强,新一代图片格式 WebP
WebP是谷歌在10年推出一种新型图片格式,最早也是应用在谷歌产品中,谷歌发布的Android Studio 2.3正式版中就包括对WebP支持的更新,在实测中,webp 格式比 jpg 格式减小约 20%。这对优化用户体验,减少CDN带宽消耗有很好的效果,但并不是所有浏览器都支持 webp ,所以为了使用 webp,需要做一点兼容性的工作。
与其他图片格式相比,在肉眼无法分辨图片质量差异的情况下,WebP的空间占用是最小的,目前国内外各大互联网公司都已经开始应用这一图片格式。比如美团
想实现首先是判断,即识别单次访问的来源浏览器是否支持 webp 格式,其次是执行,如果该浏览器支持,则将原图替换为 webp 格式,并返回。如果不支持,则显示原格式图片。http://caniuse.mojijs.com/Hom...
在识别阶段,我们有两种方法:
1. Server 处理
- 通过 UAString 判断浏览器支持情况
只要有请求,服务端就能拿到你的User-Agent信息,通过对浏览器进行分类,支持webp放在白名单里,不支持的则为黑名单。判断为白名单,则直接调用,返回webp格式图片;反之,则显示原图。这种方式的优点在于,只需定期维护白名单即可,逻辑简单;缺点则在于不可扩展、不可测试、UA判断会出现不准确的情况。
- 读取 JavaScript 种下的 cookie 判断浏览器支持情况
Server处理中的另一种方式是通过读取 JavaScript 种下的 cookie来实现判断。这种方式的优点是表现稳定,访问速度更快,切换无压力。但缺点是,页面静态化会导致用户切换浏览器时不能自主更新,图片服务失效。比如用户用支持webp的浏览器A请求页面,这时缓存的静态页面均使用webp图片,但当该用户使用不支持webp的浏览器B时,访问网页则会出现请求不到图片的报错。
- Client 处理
Client 处理,是美团云为美团主站提供的处理方式。在这种处理方式中,浏览器端发送的beacon webp 请求后,通过检测其加载情况来判定 webp 支持情况,然后浏览器写一个cookie。之后通过读取浏览器cookie判断是否支持webp,就可以进行下一步替换操作了。
2.替换图片过程中也是有两种处理方式:
- Server 处理
在 server 端处理的优点是对下游开发者透明,缺点是静态页面的缓存数量会翻倍。
替换方式如下:
- 生成 URL 的函数( 比如 $deal->getImageUrl ) ,通过运行函数中直接实现替换.
- 对 varnish静态化的页面,首先识别浏览器请求头类型,然后将webp 和传统 jpg 的各缓存一份两份待处理。然后在生成 URL的地方做替换。
- Client 处理
在 client 端处理可以比较好地应对页面静态化的情况,主要针对懒加载(非首屏)的图片进行处理,直接通过修改懒加载器来实现。对非懒加载的图片暂时没有特别好的办法。目前,可用替换路径的方式来处理。
Client 处理实际上效果也是不错的,美团页面里90%以上的图片都是懒加载的,基本上都可以满足需求。对于大多数用户来说,采用Client 处理实现webp转换是个不错的选择。
tracking Pixel(像素追踪)精准追踪数据
既然提到图片这一块,我有忍不住想扯写些题外的tracking Pixel(像素追踪),几乎所有网站都会做数据的采集,上报统计。特别是我们做SSP、DSP广告这块需要获取例如
- 用户使用的浏览器、操作系统、分辨率等。
- 用户浏览行为记录,比如用户网站上的点击行为、购买行为等。
- 用户在APP、WEB中停留时间、是否活跃等
数据永远说的是实话,数据证明一切可能。如facebook广告投放的跨境电商朋友都会使用facebook Pixel(像素追踪)以获得各环节的精准数据。这样追踪数据后,我们才能投放广告后销量上去了,哪个才是效果最好的,哪个效果不好,进而通过多个数据对比,对广告进行合理的调整优化。
国内搜狗、百度、360、新浪都是用这种tracking Pixel方法,实际就是利用1px 的图片,在图片地址后缀拼接你需要的信息参数,浏览器在请求任何资源的时候会发送当前系统的数据,比如浏览器信息,操作系统信息,作为http请求头送过去,他们就能统计了。
- 为什么不用js请求统计?
并不是所有的页面都支持JS的!NoJSStats的实现机制就是网站分析中点击流数据获取的方式之一——Web Beacons,即在页面中嵌入一个1像素的透明图片,当该页面被浏览时,图片就会被请求加载,于是在后端的服务器日志中就会记录该图片的请求日志,这样就可以获得日志记录。
例如百度:
这是百度1px图片地址: http://wn.pos.baidu.com/adx.php?
var url = ["//eclick.baidu.com/se.jpg?", "type=fatalError", "data=1220", "mes=" + encodeURIComponent(e)].join("&"), img = new Image; img.src = url 百度在地址栏后拼接了很多参数,后端按照图片后缀名生成对应的数据报表。
本文引用@美团云 提供的webP方法,感谢。