公司动态

WEB前端性能分析与优化,看这篇就够了

Web performance refers to the speed in which web pages are downloaded and displayed on the user's web browser(维基百科)。
简单点说,就是网页在浏览器中下载,呈现以及交互的流畅程度。

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

image.png

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

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

image.png

搞清楚了浏览器从加载到渲染两个核心流程,我们看看到底有哪些量化指标来评价一个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)用户首次交互时间,值越低越好

image.png

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

image.png

FCP优化策略

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

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

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

5、字体加载优化


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

image.png

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

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


image.png

SI优化策略

1、优化主进程(renderer process),包括解析HTML,创建DOM树,解析CSS,执行JavaScript

  • 优化第三方JavaScript(First Load Time)
  • 利用防抖优化用户输入事件
  • 利用web worker
  • 减少复杂的样式计算和嵌套
  • 避免大的、复杂的布局和布局回流;
  • 简化页面绘制和减少绘制区域
  • 减少冗余代码
  • 8、异步加载非必须的css

LCP measures when the largest content element in the viewport is rendered to the screen

image.png

哪些元素可能是最大的?

  • 图片
  • 里面的图片
  • 带有通过url加载背景图片的元素,不包括css gradient
  • 包含文本节点的块级元素或者包含文本节点的子元素;

注意:只有当元素在可视窗口才可能被认为的最大渲染内容,最大元素是可变的。


如下图,页面渲染及浏览的不同阶段,可视窗口最大元素是发生变化的。 image.png

  1. 页面呈现的可用内容速度,比如最大内容渲染速度;
  2. 大多数页面元素注册的事件,并且用户交互响应速度在50毫秒以内;

image.png

TTI优化策略

1、加载采用PRPL模式
  • Push (or preload) the most important resources.
  • Render the initial route as soon as possible.
  • Pre-cache remaining assets.
  • Lazy load other routes and non-critical assets.
2、减少因代码切割导致的依赖


上述两段代码功能目的是一样的,都是监听事件执行相关代码,第一段代码是先引入依赖模块,而第二段代码是在事件触发时候按需引入模块。这里可能有人会问,岂不是每次监听到事件都会引入一次?实则不然,ES6中,如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。

3、去除无用代码

可以通过eslint,webpack等工具发现和去除无用的冗余代码。

4、压缩代码和数据

无论是早期的grunt,gulp,还是现在流行的webpack,都提供了快捷方便的代码压缩工具。

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

image.png

其优化策略总体上跟TTI类似。

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

image.png

image.png

image.png

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

如何减少CLS

  1. 给image,video或者其他具有长宽比的元素设置长宽值;
  2. 尽量不要在已经渲染的内容前面插入内容;
  3. 尽量选择transform animations属性去触发布局变动;


image.png


上面提到很多性能可量化标准,那具体该如何测试获取标准数据呢?

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

image.png

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

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

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

image.png

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

最后还是介绍下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,小程序等等,都有各自的原理和性能优化手段,具体问题还需具体分析。

平台注册入口