衡量标准
谈论性能优化首先需要明确衡量标准,前端工程师需要做的就是根据标准中的指标来确定一个页面是否有性能问题,然后通过经验或者相关工具来判断性能的瓶颈在哪里,从而确定具体优化的方案。
RAIL模型
RAIL 是一种以用户为中心的性能模型,它提供了一种考虑性能的结构。该模型将用户体验分解到按键操作(例如,点击、滚动、加载)中,帮助您为每个操作定义性能目标。
RAIL 代表 Web 应用生命周期的四个不同方面:响应、动画、空闲和加载。用户对这些上下文分别有不同的性能期望,因此,性能目标是根据上下文以及用户如何感知延迟的用户体验研究来定义的。
模型的细节可以使用 RAIL 模型衡量性能 , 总结一下:
- 以用户为中心。
- 在 100 毫秒内响应用户输入。
- 播放动画或执行滚动时,在 10 毫秒内生成一帧。
- 最大限度延长主线程空闲时间。
- 在 5000 毫秒内加载交互式内容。
测量工具
Chrome浏览器的Performance
使用lighthouse生成报告
指标包括:
- FCP(First Contentful Paint)
- LCP(Last Contentful Paint)
- TTI(Time To Interractive)
- FID(First Input Delay)
- TBT(Total Block Time)
- CLS(Cumulative Layout Shift)
如何衡量加载速度:FCP、LCP
如何衡量操作流畅度:TTI、FID、TBT
如何衡量页面的视觉稳定程度:CLS
参考这篇文章
优化手段
图片
- JPEG
JPEG使用的是有损压缩算法,压缩比高,所以适合做轮播图、背景图等,可以呈现丰富的色彩。但是不太适合展示logo等对细节要求高的图片。
渐进式JPEG
在网络缓慢的情况下可以优先加载出一个比较模糊的版本,再逐渐清晰。
- GIF
GIF支持的颜色数量少,不太适合展示照片。展示Logo的话不如PNG,所以一般用来展示动画,但是单纯展示动画也不如使用视频格式,成熟的视频编解码格式更能节省网络开销。
- PNG
PNG使用的是无损压缩算法,并且支持alpha透明通道,适合展示logo或者带透明度的图片,通常包括PNG-8、PNG-24、PNG-32。
- WebP
WebP是一种有较高视觉体验的格式,但在IE和Safari上兼容性较差。所以需要做兼容处理。
- SVG
SVG是一种基于XML语法的文件格式。适合展示矢量图。学习成本比较高,通过工具编辑出来的svg会携带大量冗余信息。
优化手段包含:
- CSS Spirit
- 小图片使用Base64
- 使用Web字体
视频
- 非首屏视频关闭预解析
- 添加占位图
加载
- 图片懒加载(注意intersection Observer)
- 预加载(preload/prefetch/preconnect/dns-prefetch)
构建
- 压缩混淆
- 代码拆分,按需加载
- DLLPlugin
- 多进程加快速度
- 支持TreeShaking
渲染
- 避免回流和重绘,尽量只触发合成(仅触发合成的CSS属性只有transform和opacity),可以参考浏览器渲染原理
- 避免主线程阻塞,可以使用web worker
- 截流防抖
- 减少样式计算,CSS使用BEM规范
- 避免频繁修改DOM,可以使用react等虚拟DOM技术
缓存
- 强制缓存(相关HTTP头expires和cache-control)
- 协商缓存(一般是last-modified和ETag两个头同时使用)
- Service Worker拦截请求
- 通过HTTP2实现的Push缓存
- CDN缓存
结合实际项目
小程序首页优化,测试机器iphone8:
优化前: 2s+
- 分包加载1s
- 代码执行1s
- 接口1s
优化后: 1s+
- 分包加载1s
- 代码执行 + 接口 1s
方案:
图片优化
- 使用webp
- 后台上传图片增加相关校验,从上游规范素材质量
- 设置宽高,避免页面抖动
- 开启懒加载只渲染可是区域内的图片,首屏从100+图片减少到30+
- 使用字体图标
渲染优化:
- 拆分接口,分屏渲染,使首页接口请求速度提升50%+
- 通过localstorage缓存首屏骨架,实现渐进式秒开
- 利用空闲计算时间进行预加载详情页关键
- 下架一些不再使用的实验逻辑
针对feed流优化:
- 无限滚动。通过一个二位数组存储数据,根据视口的位置判断到底展示哪个list,其他list使用div替代。
- 算法优化。之前为了保证左右两边元素个数相同,频繁获取元素的clientHeight。改为一次计算。