性能优化与调试技术 | 青训营

115 阅读7分钟

什么是web前端性能

网页在浏览器中下载,呈现以及交互的流畅程度。

从输入URL到页面加载发生了什么

要弄清楚什么是加载性能及优化手段,就得知道从输入URL到看到内容整个过程发生了什么。

  • DNS解析
  • TCP连接
  • 发送HTTP请求
  • 服务器处理请求并返回HTTP报文
  • 浏览器解析渲染页面
  • 连接结束

哪些因素影响资源加载速度

1、带宽
2、资源大小
3、http响应速度
4、缓存

浏览器渲染原理

资源加载完成后浏览器得完成资源解析和渲染,渲染的速度直接影响用户体验。不同的浏览器内核渲染流程会不一样,大致如下:解析DOM-解析CSS-生成渲染树-绘制和呈现。

前端性能指标

搞清楚了浏览器从加载到渲染两个核心流程,我们看看到底有哪些量化指标来评价一个web应用的性能。

  • FCP(First Contentful Paint)白屏时间,值越低越好;
  • SI(Speed Index)页面渲染时间,值越低越好;
  • LCP(Largest Contentful Paint)可视窗口最大内容渲染时间,值越低越好
  • TTI(Time to Interactive)用户可交互时间,值越低越好;
  • TBT(Total Blocking Time)用户行为阻塞时间,值越低越好;
  • CLS(Cumulative Layout Shift)可视窗口中累计可见元素布局偏移;
  • FID(First Input Delay)用户首次交互时间,值越低越好

FCP白屏时间

白屏时间指的是用户在浏览器中打开页面到渲染第一个DOM元素所花费的时间,DOM元素包括图片,非空白canvas,SVG等元素,不包括iframe中的元素;

FCP优化

1、DNS解析优化
DNS缓存优化
DNS预加载策略
稳定可靠的DNS服务器

2、服务端处理优化
Redis缓存、数据库存储优化或是系统内的各种中间件以及Gzip压缩等...

3、CDN加速
4、精简DOM结构,合理压缩和放置CSS,JS

5、字体加载优化

css
复制代码
@font-face {
  font-family: 'Pacifico';
  font-style: normal;
  font-weight: 400;
  src: local('Pacifico Regular'), local('Pacifico-Regular'), url(https://fonts.gstatic.com/s/pacifico/v12/FwZY7-Qmy14u9lezJ-6H6MmBp0u-.woff2) format('woff2');
  font-display: swap;//注意这里
}

浏览器经常会出现一些出乎我们意料的问题,而字体的加载就是其中之一。大多数浏览器在自定义字体还未下载之前会先隐藏文本。一般情况下,我们可能没有感知,但是网速较慢的情况下可以看到,大部分浏览器会隐藏文本一定时间直到字体加载完成,如果字体没有加载完成,甚至不会显示文本。

这个时候font-display属性就起到作用了,具体如上代码。它不仅提供了自定义字体和内容的可访问性之间的最佳平衡,还提供了和使用JavaScript脚本相同的字体加载行为。当然,这个属性存在一定的兼容性,但是问题不大。

如果字体肯定会用到,我们甚至可以预加载字体。

<link rel="preload" as="font">

TBT(响应延时)

页面响应到用户可交互之间阻塞的总时长,比如鼠标点击,屏幕触摸,键盘输入等,即从FCP到TTI的总时长,超过50ms就被认定为一个长时任务。

CLS(累计布局偏移)

页面整个生命周期所有元素发生的非预期的布局累计偏移值。

出于交互原因,页面上通常有很多未加载或者隐藏的元素在某些事件触发后展示,这就算导致周围布局发生变化,比如常见点击展开,图片加载等等,甚至修改一些元素的属性时候,比如宽高,会导致页面重排,也会消耗渲染性能。

如何减少CLS

  1. 给image,video或者其他具有长宽比的元素设置长宽值;
  2. 尽量不要在已经渲染的内容前面插入内容;
  3. 尽量选择transform animations属性去触发布局变动;
<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons" />
img {
  aspect-ratio: attr(width) / attr(height);//宽高比
}

上面提到很多性能可量化标准,以下是一些工具的使用:

network

基本上现代浏览器都提供了强大的network工具,方便查看所有资源的加载信息。也是前端开发最常用的工具之一。

Perormance

当发现web应用有卡顿现象时就得查看Perormance,它能快速定位页面渲染过程中各个环节的耗时,如果发现某个Activity耗时明显异常,就得逐步去排查对应位置的代码了。

Lighthouse

Lighthouse从专业角度给出具体web应用的评分及其优化手段,可以根据其提供的优化策略按需修改。

PageSpeed Insights

这个工具是一个网站,跟Lighthouse比较类似。

chrome://inspect/#devices

相信很多前端开发在开发移动端web应用时或多或少会遇到一些PC浏览器模拟器正常但是手机上就是有问题的情况,毕竟手机性能,webview等太多环节会影响用户体验,这个时候最有效的办法就是利用浏览器自带的远程调试工具,比如chrome的inspect,能够真实的还原问题场景,并分析存在的问题,逐个解决。

Yahoo35条军规

最后还是介绍下Yahoo35条军规,早期是前端开发人员奉行的经典,现在依然有效。

  1. 尽量减少HTTP请求数 合并文件、CSS Sprites、行内图片
  2. 减少DNS查找
  3. 避免重定向
  4. 让Ajax可缓存
  5. 延迟加载组件
  6. 预加载组件(无条件预加载、条件性预加载、提前预加载)
  7. 减少DOM元素的数量(700以内HTML标签)
  8. 跨域分离组件(静态分离,同域名并行下载一般不能超过6条)
  9. 尽量少用iframe
  10. 杜绝404
  11. 把样式表放在顶部;
  12. 避免使用CSS表达式;
  13. 选择舍弃@import;
  14. 避免使用滤镜;
  15. 去除重复脚本;
  16. 尽量减少DOM访问(缓存已访问过的元素的索引先“离线”更新节点,再把它们添到DOM树上,避免用JavaScript修复布局问题);
  17. 用智能的事件处理器(比如DOMContentLoaded 代替load,合理使用事件委托);
  18. 把脚本放在底部,合理使用defer,async异步加载;
  19. 把JavaScript和CSS放到外面;
  20. 压缩JavaScript和CSS
  21. 优化图片;
  22. 优化CSS Sprite;
  23. 不要用HTML缩放图片;
  24. 用小的可缓存的favicon.ico(越小越好,一定要有,否则会造成404);
  25. 给Cookie减肥(清除不必要的cookie、保持合理大小,合理域名、有效期);
  26. 把组件放在不含cookie的域下;
  27. 保证所有组件都小于25K;
  28. 把组件打包到一个复合文档里;
  29. Gzip组件;
  30. 避免图片src属性为空;
  31. 配置ETags(服务器)
  32. 对Ajax用GET请求(服务器);
  33. 尽早清空缓冲区(服务器);
  34. 使用CDN(Content Delivery Network);
  35. 添上Expires或者Cache-Control HTTP头

小结

前端的性能优化是综合性的问题,涉及到前端开发的方方面面,以上是对web性能分析和优化的基本整理,至于具体的框架,应用类型不同,优化的手段也会不同,没有一种优化手段是万能的,比如vue,react,angular,小程序等等,都有各自的原理和性能优化手段,具体问题还需具体分析。希望大家能够在不断的学习过程中细细感受这一发展