两年前,我曾经写了一篇关于性能优化的文章, 在里面提出性能优化要先对页面性能进行记录,而且要按照页面访问的整个流程分步骤进行优化。
两年过去了,我又有了一点新的思考,在阿里也学习到了一些新的优化方法,在这里分享给大家。
关于性能优化的时机,其实可以更早,比用户输入url更早,即用户将要访问你的页面这一步开始优化。
因此,我们可以将性能优化按时间顺序分为三块:
页面访问前,页面加载中,页面运行时
用户访问网站前的性能优化
- 推送资源:
- 预先将页面资源如JS,图片,多媒体文件推送到客户端/浏览器
- 预加载:
- prefetch(可能使用的资源)
- preload(必要资源)
- prerender
- 提前打开webview容器:
- 打开webview容器需要一些时间,我们可以提前打开webview来省去这些时间
- 预先请求AJAX:
- 提前获取下个跳转页面需要的ajax数据,缓存到localstorage
页面加载过程中的性能优化
- 查询强缓存:
- service worker
- 强缓存
解析dns:
- 域名收敛
- http dns
- dns-prefetch:
<link rel="dns-prefetch" href="/domain.com'>
- 使用CDN,将图片等资源的dns配置指向cdn,加速下载,抹平运营商差异
建立tcp链接:
- http2: 多路复用
- keep alive: 长连接
- 域名发散: 突破并发请求限制
- 雪碧图
- 打包代码
发送请求;
- disk cache协商缓存
- 小图片使用base64免去请求。
服务器处理请求:
- 少一些重定向, 301永久,302临时
- 使用hsts强制https,307
发送响应:
- gzip压缩资源
- 用更好的格式如webp
- 使用
<script type=module>
传输es6版本的代码,<script nomodule>
传输es5代码
解析html:
- js在下避免阻塞,
- defer有序,文档解析完成后才执行。 async加载后立刻执行,乱序
构建渲染树:
- 减少DOM的数量和嵌套层级
- 减少重绘重排: 减少dom操作,减少读取几何布局属性,class代替sttyle,resize,scroll时节流防抖。
- 懒加载
- css优化:减少选择器
白屏:
- 骨架屏
- 服务器渲染
运行JS:
- 依赖版本统一
- 精简代码
- tree shaking
- 代码分割
- 获取渲染需要的接口:
- localstorage缓存时效性不强的数据
- 在用户打开页面的过程中就获取接口(需要客户端配合改造,可以使用url带参数或是配置文件)
- 首屏内容:
- placeholder
- 关键css和dom
- 页面可交互 DOMContentloaded
- 加载完成 load
页面运行时的性能优化
使用raf记录fps可以记录帧率
- 构建合成层启用GPU加速:
- will change: opacity、transform、top left bottom right
- transfrom:translateZ
- position:fixed
- zIndex
- 减少重绘重排
- 避免频繁操作样式和DOM
- 避免读取offsettop,scrolltop,clienttop等属性
- class代替style
- 批量修改的元素、复杂动画脱离文档流
- 虚拟滚动条应对无限加载
- 节流防抖
- 虚拟DOM
- 用raf来做动画
- 滚动优化
- 节点回收
- 占位
- 事件节流,事件代理
- 对性能较差的机型降级:(怎么判断?)
- 使用canvas嗅探GPU型号:关键词包括experimental-webgl、WEBGL_debug_renderer_info、info.UNMASKED_RENDERER_WEBGL
- Native API手机机型识别
- UA 获取系统版本
- 分辨率