性能优化调研系列文章
《前端性能优化(中)》中大概梳理了页面加载导航、渲染的大致流程。知道了整个过程,才能更好的了解哪些节点可能最容易成为性能瓶颈和对应的性能问题如何优化。
工欲善其事 必先利其器
开始我们的优化
设立优化目标
- 想要你页面的性能达到什么效果, 设定一个你的性能预算(加载资源多少 各个指标的预期值是多少等)
- 可以借助 lighthouse performance-budgets 来指定你的优化目标。
- 可以使用 https://www.performancebudget.io/ 来快速的设定的目标 然后获取lighthouse的配置文件。
- 查看你的哪一项指标没有达到预期
- 针对性的开始优化~
优化的指导原则
Google给出的知道原则: PRPL
- 推送或者是预取最重要的资源(比如你的LCP 元素 图片资源)---
Push Preload
- 尽可能快的渲染的你的初始化路由---
render
- 缓存你的资源,加速再次访问速速---
pre-cache
- 懒加载其他的路由或者非关键资源---
lazy-load
web相比native在启动的时候的缺点
其中涉及到网络请求耗时一般最长,优化效果最明显 收益也最高。
导航加载优化策略
js外部资源后置(还记得雅虎军规么),css样式资源前置
目的:避免js加载和解析执行的阻塞DOM解析从而阻塞FP, FCP
对于客户端渲染项目,一般初始化渲染的时候是空页面(所有的页面结构都是通过js动态创建),使用骨架屏 App shell 是一种不错的优化体验的方式,显示的告知用户正在加载资源(而不是白屏)同时提升了FP,FCP的时间点。 关于骨架屏生成自动化方案社区中有一些具体的实现方案,具体见最后的“参考”;
使用preload prefetch 进行资源预取,
preload
是一种使串行请求模式转换成一种并行模式的好方式,但是需要注意浏览器和http协议对资源并行加载的限制
- chrome对HTTP1.1协议的资源 同一个域名最多允许并行请求为6个, 所以请谨慎使用preload ,合理规划你的并行加载机制。
- HTTP2版本 对于同一个域名使用同一个tcp连接,理论上可以无限并行加载,实际上需要情况不是这么简单,参考 The Right Way to Bundle Your Assets for Faster Sites over HTTP/2 (
中文翻译版本);
下图是针对加载同样体积大小的资源,分别拆分成1000、50、6、1个文件请求 在HTTP2下的加载时长
结论: 综合测试结果和考虑兼容HTTP1.1版本,建议HTTP2协议中并行加载资源不超过 50个 ;但是实际上在使用过程中还是非常复杂,比如不同优先级的资源请求可能会影响并行发起请求数量。
- prefetch 适合对后面的操作(非高频)或者后面的路由中使用的资源进行预取,通常会结合按需加载一起使用
- 同时不要过分使用preload 和 prefetch,浪费用户的流量。
尤其是对于LCP来说,很多时候因为最大元素是图片元素,而在SPA项目中,创建img元素的时机又依赖关键js的加载和执行,这之后才会触发请求图片资源,加载成功之后才会上报LCP。 所以我们可以通过preload技术提前加载图片资源
正常的流程
使用 preload 进行关键资源预取
-
关于dns-prefetch 正确使用方式 参考 DNS Prefetching 的正确使用姿势
-
关于
preload prefetch dns-prefetch preconnect
详细的说明和区别 参考这篇文章 :[译] 资源提示 —— 什么是 Preload,Prefetch 和 Preconnect
静态资源的压缩
老生常谈 却经常忽略
- 包含不限于js、css、html、图片等资源。
- 选择合适的资源格式,比如webp;使用webp的注意事项
- 压缩和GZIP的不同之处 参考:The Difference Between Minification and Gzipping
尽量减少构建体积
- 使用合适的第三方依赖(考虑性能和体积)
- 利用tree shaking技术等。
按需加载
- 进入到可视区域范围(距离视区指定阈值)(懒加载或者预加载技术)
- 根据不同的屏幕尺寸(响应式)加载不同的资源
- 根据不同的网络环境(3G 4G WIFI)加载不同的资源
- 根据不同的设备性能(cpu核数、内存状态)加载不同的资源
按需加载,尤其是在交互反馈中使用的场景,会造成因为按需延迟的资源导致响应时间边长,这个时候合理的使用preload prefetch
是一个比较好的方案。
资源合并、拆分
请求合并与拆分是一个技术活儿,需要进行测试(尤其是考虑HTTP2的情况下),与此同时 利用构建工具(如webpack等)合理的进行代码分割、打包也需要专门进行研究(待补充)。
- 合理拆分包大小
- http协议不同版本的影响
- 考虑首次加载性能和缓存利用率
缓存最大化,加速再次访问速度
- CDN 节点缓存、基于HTTP协议的本地缓存和协商缓存;关于最大化网络缓存利用率和命中率,使用构建工具(如webpack)也需要进行特定的配置。
- 基于浏览器存储技术的缓存,包括使用
localStorage indexdb
等进行数据缓存 - 使用PWA技术
- 如果你是在开发hybrid应用,可以借助客户端的能力,使用离线包技术;甚至使用RN weex方案。
SPA页面SSR or CRS
运行时性能优化
待补充。
参考
- lighthouse performance-budgets
- The Difference Between Minification and Gzipping
-
The Right Way to Bundle Your Assets for Faster Sites over HTTP/2 /
中文翻译版本 - DNS Prefetching 的正确使用姿势
- [译] 资源提示 —— 什么是 Preload,Prefetch 和 Preconnect
- https://github.com/dhg/Skeleton
- https://github.com/famanoder/dps
- https://github.com/kaola-fed/awesome-skeleton
- https://github.com/Jocs/jocs.github.io
- https://korbinzhao.github.io/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/%E9%AA%A8%E6%9E%B6%E5%B1%8F/2018/06/23/skeleton-auto-generator/
- App shell and Skeleton-Screen
- css contain
网友评论