阿里无线前端性能优化指南 (Pt.1 加载期优化)
前言
阿里无线前端团队在过去一年对所负责业务进行了全面的性能优化。以下是我们根据实际经验总结的优化指南,希望对大家有所帮助。
第一部分仅包括数据加载期优化。
图片控制
对于网页特别是电商类页面来说,图片通常会占据了大量的视觉空间,是页面中最为重要的展现内容,并且占据网页传输字节的大部分。因此,对图片的优化是我们性能优化的重点.
启用WebP
WebP是一种支持有损压缩和无损压缩的图片文件格式,派生自视频编码格式 VP8。根据 Google 官方的数据,无损压缩后的 WebP 比 PNG 文件少了 26% 的文件大小,有损压缩在具有同等SSIM索引的情况下WebP 比 JPEG 文件少25-34%的文件大小。WebP支持无损透明度(也叫做alpha通道),支持动画格式Animated WebP 。
虽然目前仅Android系统原生支持WebP格式, 但由于其对页面性能优化的巨大意义, 我们会在页面加载时进行环境探测, 如页面渲染环境支持WebP我们会替换页面中的图片链接为WebP格式的版本。 如果页面专门用于可控的客户端内(我们能在客户端中放置专门的WebP decoder),就算是iOS环境我们也会启用WebP.
优化高分屏和弱网适配
从苹果的Retina开始,手机厂商开始越来越多的使用高像素密度显示屏。在浏览器里我们的一个CSS像素往往能对应两个或更多个设备像素,在这种环境下为了追求最好的显示效果,我们会采用数倍于浏览器CSS像素标识的图片尺寸. 这里需要注意的是,如果你采用了2x (两倍CSS像素分辨率) 的图片,由于水平和垂直像素都进行了加倍,最终图片体积会增加4倍(内存占用也会增加4倍). 同理,如果你采用了3x的图片,最终增加的传输体积会增至9倍.
用户喜欢清晰绚丽的图片, 但用户更加痛恨打不开的页面. 在我们的实践中,我们最多使用2x(两倍CSS像素分辨率)的图片。 如果页面专门用于可控的客户端内,我们会根据从客户端获取的网络情况替换页面所使用的图片资源. 在最糟糕的网络环境(2G移动网络),我们甚至会采用按30%质量进行压缩的图片以替换原始图片链接。
单张图片大小控制
有时,如果不设限无论你如何优化糟糕的情况总会出现。在我们的实践中, 针对图片我们设置了单张图片大小不超过50Kb的限制。在每次发布时,我们会对页面图片进行检查, 如果图片超过这个限制仍需要发布,就得走特别的流程了.
合理使用CSS/SVG/ICON Font替代图片
传统桌面Web中,针对页面内的图标,我们往往采用Sprite(雪碧图)技术把多个图标合并到一张大图片中,针对不同的图标显示大图中不同的部分。但在移动互联网环境下, 由于设备内存有限,每使用Sprite技术展示一个图标,都需要浏览器把整个大图解码到内存中一次,考虑到前文提到的多倍CSS像素分辨率情况, 占用的内存和解码时间往往是可观的。不合理的使用Sprite技术会造成移动页面性能不升反降。
更合适的选择是CSS3,SVG和ICON Font技术。如果你的图标能使用这些技术绘制,在任何分辨率和缩放设置都可以提供清晰的效果并减小传输和内存的开销.
对图片进行按需加载
电商类型网站多用多图列表页面展现商品内容, 我们会在非WIFI网络环境时对图片资源进行按需加载,仅仅当图片资源出现在首屏或随着用户滑动屏幕进入可见区域时,我们才进行加载. 进行这项优化的关键在于对全局的图片呈现进行一层抽象,以便统一控制.
网络请求
今天我们谈论的无线页面,很多时候已不再是传统的"页面",而是一个个"单页应用"。随着应用复杂度的逐渐增加,所需加载的除图片等静态数据外,动态数据也会越来越多。如果想追求高质量的单页应用,对这些请求的优化势在必行.
域名收敛
如果你页面中引入的各种资源来自不同的域名,注意每增加一个域名,都会增加一次域名解析开销。 在复杂的国内移动互联网网络环境下,不同域名的解析速度可能会相差数十倍。 所以你需要有意识的收敛页面资源所需解析的域名数, 特别是会阻塞页面渲染的CSS,JS,Font资源。 很多性能糟糕页面究其原因或许会是引入的资源域名解析速度很慢或完全不能正确解析。在我们的实践中, 一个页面所产生的域名解析数不能超过5个。
减少请求数
在优化了需要解析的域名数后,你需要关注页面资源请求数. 如果是长期维护的产品型页面 ,页面中引入的静态资源除最通用的基础库外需要按依赖顺序进行合并压缩. 一般是JS和CSS请求各一。 针对电商厂商多见的营销活动页面,我们甚至开发了工具把全部的CSS和JS资源内联入页面,从而实现除图片外的其余资源One Request就能获得.
另外,资源请求重定向也应该尽量避免,少一次重定向,少一个请求数.
文本数据的优化与压缩
文本数据(HTML,CSS,JavaScript)的优化与压缩分为三个阶段,分别是发布准备(去除注释,合并CSS声明,去除不会被执行的JS 代码块), 编译期压缩(合并文件,去除空格,混淆) 和 传输阶段压缩( GZip ) . 这项优化的关键在于梳理流程确保压缩的自动化和服务器GZip指令被正确配置。
数据接口优化与监控
随着近两年Web前后端分离思潮的流行与前端模板技术的发展 , 我们越来越倾向在页面加载完成后再通过接口获取JSON数据并在前端进行页面渲染。这种方式带来了页面第一次加载速度的提升,但常常把原有的性能问题隐藏了起来。 需要花功夫优化的数据获取并最终呈现时间往往被隐藏在空页面快速呈现的表象之下。更严重的情况发生在需要从多个不同接口获取数据,并且这些接口调用还存在互相依赖的情况下,一旦出现这样的情况,页面性能往往是不升反降的.
在我们的实践中, 我们要求数据在后端组装完成后再交由前端渲染,一屏中完整渲染所需数据不能来自多过一个接口。 所有数据源统一收敛到单一的接口服务层,以便进行统计和监控。
来自:https://github.com/amfe/article/issues/1