本质上,要从用户体验指标考虑页面性能
- 页面加载时长
- 用户交互反馈时长
- Web动画中的帧数
分析要点
- 在无痕窗口分析,以避免历史数据和拓展程序对分析结果造成影响
- 利用Network分析网络问题
- 利用Performance查看运行过程中的性能数据,深入分析 Web 应用的性能问题,可以查看 Performace 了解使用
- Lighthouse 这个工具会给出性能得分和优化建议,帮助分析加载时的性能问题
首屏的显示涉及了哪些技术因素
- DNS、HTTP、DOM 解析、CSS 阻塞、JavaScript 阻塞等等
- 关键资源个数: 可能阻止网页首次渲染的资源(CSS、JavaScript)
- 关键资源大小: 现网页首次渲染所需的总字节数,它是所有关键资源传送文件大小的总和
- 关键路径长度: 获取所有关键资源所需的往返次数或总时间
首屏分析
- 抓图信息区域 (Network --> 勾选Capture screenshots),可以用来分析用户等待页面加载时间内所看到的内容,分析用户实际的体验情况。比如,如果页面加载 1 秒多之后屏幕截图还是白屏状态,这时候就需要分析是网络还是代码的问题了
- 分析单个资源的时间线
3. 分析渲染流水线——这个阶段包括了解析 HTML、下载 CSS、下载 JavaScript、生成 CSSOM、执行 JavaScript、生成布局树、绘制页面一系列操作。 此阶段涉及的知识点: * CSS加载不会阻塞DOM树的构建,但会影响布局树(也叫Render树)的构建 * JavaScript的执行依赖于前面的CSS
通常情况下的瓶颈主要体现在下载 CSS 文件、下载 JavaScript 文件和执行 JavaScript。
优化方案
1.网络传输
- 减少Timing——Queuing等待时间
- Queuing等待时间可能是每个域名最多维护 6 个连接导致,将域名分片,增加单位时间内的可连接数,比如将静态资源放在静态域static
- 升级至HTTP2.0
- 降低TTFB (第一字节时间)
- 服务器生成页面数据的时间过久——通过增加各种缓存的技术
- 网络的原因,带宽过低——使用CDN来缓存一些静态文件
- 发送请求头时带上了多余的用户信息,服务器根据请求信息做了多余的无用功——减少多余信息的传输
- Content Download 时间过久
- 减少文件大小——压缩、去掉无用注释等
- 减少请求数
- CSS/JS合并打包(注意:可能引起单次请求下载时间过长,基于现今HTTP2.0无连接限制,分开下载可能效率更高,需要综合考虑,而且内联无法缓存)
- CSS雪碧图、base64
2. 加载时优化
- 首屏内联 JavaScript、内联 CSS 来移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了
- CSS放头部,JS放尾部,可以使DOM尽快构建,使DOMContentLoaded尽快触发
- 静态资源大小(按需加载、压缩)—— HTML、CSS、JavaScript、image、font等
- 一些不需要在解析 HTML 阶段使用的 JavaScript 标记上 sync 或者 defer
- 对于大的 CSS 文件,可以通过媒体查询属性
3.运行时性能
- 避免批量DOM操作
- 使用createDocumentFragment,或者使用框架Vue、React
- 减少重排重绘
- 使用 class 操作样式,而不是频繁操作 style
- position属性为absolute或fixed的元素,重排开销比较小,不用考虑它对其他元素的影响
- 合理使用will-change(会比较耗内存),可以使用合成线程来处理 CSS 特效或者动画,而不涉及到主线程
- DOM属性的读写分离,下面的代码只触发一次重排
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
console.log(div.offsetLeft);
console.log(div.offsetTop);
console.log(div.offsetWidth);
console.log(div.offsetHeight);
得益于浏览器的渲染队列机制,当我们修改了元素的几何属性,导致浏览器触发重排或重绘时。它会把该操作放进渲染队列,等到队列中的操作到了一定的数量或者到了一定的时间间隔时,浏览器就会批量执行这些操作。但对于低端浏览器,依然会触发多次重排
- GPU加速
- Canvas2D,布局合成,CSS3转换(transitions),CSS3 3D变换(transforms),WebGL和视频(video)
- 这段代码可以强制开启 GPU 加速 transform: translate3d(10px, 10px, 0);
- 减少 JavaScript 脚本霸占主线程时间
- 使用web worker处理计算量大的操作
- 避免强制同步布局和布局抖动,避免多次重复渲染
- 通过Performance分析长任务,尽可能优化长任务
- 注意内存泄漏——可使用Memory分析
- 避免闭包的过量使用
- 异步加载
- 懒加载
- 防抖节流
- window.resize
- 服务器渲染
4.缓存
- 浏览器DNS缓存
- Server Worker——在用户设备缓存Common资源,减少网络请求
- 强制缓存——Expires、Cache-Control
- 协商缓存——Last-Modified / If-Modified-Since 、Etag / If-None-Match
用户性能监控
- 基于 Performance API 采集真实用户数据
参考
浏览器工作原理与实践——time.geekbang.org/column/intr… 关键渲染路径——developers.google.com/web/fundame… RAIL性能模型——web.dev/rail/
最后
- 谢谢观看~
- 欢迎关注我的github----github.com/zoro-web/bl…,你的关注是我整理知识的更大动力,我的博客会定期整理发布一些文章。