前端常用性能优化方案

一切性能优化是根据网站测试结果去针对性进行的,不需要无脑的进行优化。另外,没有固定的优化策略,不同的项目要分而治之。

性能优化思路

  1. 了解浏览器工作原理及web渲染原理,认识影响性能的因素
  2. 使用如Performance、Lighthouse、PageInsight等工具对性能进行评估,帮助了解短板,说服Linder
  3. 使用控制台面板功能(如请求列表,缓存,资源大小,请求耗时)和DevTools寻找突破口
  4. 使用正确的有针对性的方法解决性能问题

首屏常见性能指标

首屏性能影响因素

  • 域名及DNS解析时间慢
  • 服务器响应时间慢
  • 阻断渲染的js和css
  • 资源加载时间慢
  • 客户端渲染时间慢

减小资源体积

牺牲代码可读性,减小阻塞资源的体积。

  • 对CSS/JS进行压缩(Minifycation),可使用一些成熟的工具如UglifyJS
  • HTML压缩,剔除空格、制表符、去除注释
  • 图片使用JPG/webp/SVG等格式,减少图片大小。在保证质量的前提下可对图片进行压缩
  • 图标可通过font-icon或矢量图(如SVG)来代替
  • 使用Gzip压缩页面(前端提供压缩包,服务器开启压缩,浏览器解压后进⾏再进⾏解析)
  • 移除昂贵的代码库。如果能够手写解决尽量手写。比如使用webpack-bundle-analyzer分析插件可以分析引用库的大小。
  • Tree shaking 消除死码,一些构建工具会帮我们完成。比如Vue3在编译阶段会用到tree shaking按需加载模块和死码消除

控制资源文件加载优先级

浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。一般情况下都是 CSS 在头部,JS 在底部。

按需加载、懒加载

  • UI框架、自定义组件按需加载
  • 图片或视图区域懒加载:图片懒加载实现
  • 对于响应式页面的图片, 可以使用srcset定义图像, 使浏览器可以在图像之间进行选择,详见

合理利用缓存

资源缓存可以避免过多的TCP连接和响应。数据和状态缓存可以避免过多的计算。

  • HTML离线缓存静态页面,在html标签中添加manifest属性,关联如cache.manifest文件(HTML5支持)
  • 缓存页面资源, 减少浏览器对资源的请求次数
  • 由于HTTP/2多路复用,可以减小缓存粒度,传输轻量、细粒度的资源,以便独立缓存和并行传输。合理安排缓存更新和过期策略,提高缓存的命中率
  • 对请求的静态数据进行缓存(封装),利用浏览器的localStorage和sessionStorage,比如用户信息、菜单

优化资源阻塞,异步加载

优化资源传输效率

减少资源请求数量

虽然HTTP/2的多路复用解决了分域查询的痛点,减少了连接开销,但避免过多的资源数量同样也是有效的优化方案。因为浏览器的并发请求数量是有一定的限制的。比如同一域名谷歌浏览器一是6个。

  • 小图片转为Base64格式的内联代码,避免文件请求
  • 服务端渲染,数据预处理(在服务端已经处理首屏渲染的数据),比如Vue提出的Nuxt.js和React提出的Next.js。
  • 在生产环境关闭source map
  • CSS非必要避免使用import引用

代码层面优化方案

  • HTML减少DOM节点
  • HTML避免空src空href值,会给浏览器增加请求负担
  • CSS优化,尽量使用全局样式,减少行内样式,减少样式选择器的层级
  • CSS属性选择合并
  • 使用简写CSS属性,比如使用margin代替margin-top等
  • JS优化,封装复用方法和工具,封装公共方法
  • JS优化,分解耗时任务:比如使用 web worker 独立运行耗时任务。
  • JS优化,使用更高效的API,比如ES6中的解构赋值,比如Vue3中使用Proxy取代Object.defineProperty
  • 生产环境去除注释。
  • 避免内存泄漏。比如:不必要的全局变量、循环引用、闭包、未清除的定时器、打印到控制台的对象、获取且未使用的Dom对象

减少重排(Reflow)

重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 的过于频繁,CPU 使用率就会急剧上升。

如何避免重排?

DNS解析优化

减少TCP连接开销

由于TCP连接需要握手,是比较昂贵的操作。所以需要进行优化。

  • 页面的重定向非常昂贵,必须减少页面重定向
  • SPA一定程度上也可以减少页面的重定向
  • 延迟会增加TCP连接开销,使用CDN可以加速

实际上,HTTP/2的多路复用解决了分域查询的痛点,减少了连接开销。

首屏用户体验优化方案

  • 使用骨架屏或Loading图来替换白屏

HTTP2

实际上很多优化方案都是针对HTTP/1版本的,在2015年HTTP/2以后,解决了很多痛点,使得很多优化手段无需再做,甚至用在HTTP/2上会降低性能。了解这些特性很重要,能够避免走入一些性能优化的误区。HTTP/2优势详见

解决痛点的主要特性就是多路复用。HTTP/2对每个服务器只使用一个连接,而不是每个文件一个连接。避免了多次建立连接的开销。如下是HTTP/2无需做的一些优化。

  1. 分域存储。为了实现并行请求文件,你可能把文件分散到了不同的域里,CDN会自动这么做。但分域存储会影响HTTP/2的性能,建议使用HTTP/2友好的分域存储:①让多个域名解析到同一个IP。②确保证书包含通配符,以便所有分域名都可以使用。
  2. 雪碧图。雪碧图把很多图片拼成一个文件,然后通过代码按需取得每个图片。雪碧图在HTTP/2的环境下没太大用处。
  3. 拼接的代码文件。与使用雪碧图的原因类似,很多独立的文件也会被弄成一个,然后浏览器再从其中找到并运行需要的文件。
  4. 插入行内的文件。CSS代码、JavaScript代码,甚至图片等被直接插到HTML文件中的内容。这样可以减少文件传输,代价是初始HTML文件较大。

后端和服务器配合

性能优化并不是前端一个维度可以实现的。服务端需要一定的配合。

  • 合理分配带宽
  • 服务器硬件性能优化
  • 后端要进行并发优化和数据库查询优化

浏览器性能检查工具

Performance(性能)

Performance 是 Chrome 开发者工具中的一个功能,用于记录网页从初始化到运行时的所有性能指标。

使用 Performance 前,我们最好打开 Chrome 的无痕模式。因为 Chrome 上一般有着大量的插件,会或多或少的影响页面的性能,所以我们关掉这个来避免对页面性能的影响。

点击左上角的 Record(小圆点)按钮,Performance 进入 Record 阶段,从此刻开始,它会记录用户的交互以及这些交互对页面性能数据的影响。

生成的 Performance 性能报告,我们先看顶部的三个数据:FPSCPU 以及 NET

  • FPS:主要和动画性能有关,代表每秒帧数。图表中的绿色长条越高,说明FPS越高,用户体验越好。如果其中有红色长条,代表着这部分帧数有卡顿,需要优化
  • CPU:和底部的 Summary 对应,显示了页面加载过程中,各阶段对 CPU 的占用时间,占用时间越多,代表该阶段越需要优化。在 Performance 中,该部分是最需要关注的指标之一。
  • NET:每条彩色横杠表示一种资源。横杠越长,检索资源所需的时间越长。 每个横杠的浅色部分表示等待时间(从请求资源到第一个字节下载完成的时间) 深色部分表示传输时间(下载第一个和最后一个字节之间的时间)
  • Main:火焰图。它展现了主线程在 Record 过程中做的所有事情,包括:Loading、Scripting、Rendering、Painting 等等。火焰图的横轴代表着时间,纵轴代表着调用堆栈。每一个长条代表执行了一个事件或函数,长条的长度代表着耗时的长短,如果某个长条右上角是红色的则表示该函数存在性能问题,需要重点关注。
  • DOMContentLoaded :就是 dom 内容加载完毕。 那什么是 dom 内容加载完毕呢?打开一个网页当输入一个 URL,页面的展示首先是空白的,然后过一会,页面会展示出内容,但是页面的有些资源比如说图片资源还无法看到,此时页面是可以正常的交互,过一段时间后,图片才完成显示在页面。从页面空白到展示出页面内容,会触发 DOMContentLoaded 事件。而这段时间就是 HTML 文档被加载和解析完成。
  • load: 页面上所有的资源(图片,音频,视频等)被加载以后才会触发 load 事件,简单来说,页面的 load 事件会在 DOMContentLoaded 被触发之后才触发。

Performance 提供的性能监测功能已经较为完备,但是,它有两个问题:

  • 数据缺少实时性
  • 数据面板过于复杂,不够直观

为此,Performance monitor 功能可以实时直观的数据展示页面性能。

Lighthouse面板

Lighthouse 是一个开源的自动化工具,是 Chrome 的一个扩展程序。为 Lighthouse 提供一个您要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告,会对页面的加载进行分析,然后给出提高页面性能的建议。可以对以下分类做报告:

  • 性能
  • 无障碍使用
  • 用户体验
  • SEO 优化
  • 移动设备和桌面设备兼容性

Page Insight 和 Page Speed Insight

这是来自Chrome商店的浏览器插件。可以出具网页性能测试报告。提供性能优化建议等。

加载中...
加载中...