对于前端开发者来说,前端性能优化就跟浏览器兼容性一样是不得不面对的一个问题,我们经常会在项目的 1.0 之后才考虑性能优化的问题,但我认为其实最佳实践是在项目开始之前或项目开发过程中便考虑性能优化的问题,这时便需要我们对前端性能优化已经形成一个较完整的知识体系,以便能够更早地去做好前端性能优化的规划。
本文主要尽可能地总结关于前端性能优化的能够立马在项目中实践的知识点,开发者可以根据实际的需要去选择项目性能优化的点。
我习惯于将前端性能优化分为HTTP 请求优化、静态资源优化和代码优化三个层面。
HTTP 请求优化
HTTP 请求优化主要是减少 HTTP 请求,减少 HTTP 请求能够明显提升浏览器的加载速度,在一个页面加载过程中,浏览器会向服务器端请求静态资源、接口数据等,所以我们一般可以通过以下几种方式来减少 HTTP 请求。
合理规划页面接口。在开发过程中跟后端人员合理规划当前页面的接口数量,尽量减少接口请求。
合并 CSS 样式文件和 JS 脚本。根据实际场景,将多个 CSS 样式文件和 JS 脚本合并。
使用 CSS Sprites。CSS Sprites 即我们通常说的雪碧图,它是一种网页图片应用处理方式,即将页面中的多张零星图片合并为一张,然后通过 background-position 来决定使用哪一张图片。
实现懒加载。可以通过 IntersectionObserver 实现图片、音频、视频等的懒加载。
静态资源优化
内联关键 CSS。使用 link 标签的方式引用外部 CSS 样式文件需要等到 HTML 文档加载完成后才能知道所引用的 CSS 样式文件并请求加载,而内联样式则会随着 HTML 文档一起加载,所以内联样式能够使浏览器更快地开始页面渲染。内联关键 CSS 指的是将原本需要渲染页面的 CSS 样式中的关键 CSS 提取出来内联到 HTML 文档中。可以通过 Github 上的 Critical 项目确定关键 CSS。
异步加载 CSS 样式文件。通过设置 link 标签的 rel="preload" 实现异步加载 CSS。
<link rel="preload" href="myStyle.css" as="style" ="this.rel='stylesheet'">
无阻塞加载 JS 脚本。JS 脚本的加载与执行会阻塞页面渲染,我们可以通过将 JS 脚本的引入放到页面的最底部,也可以通过在 script 标签中加上 defer、async 属性来实现 JS 脚本的异步无阻塞加载。当使用 defer 时,加载文档的过程将和 JS 脚本的加载并行进行,但是要等到文档解析完成后才执行 JS 脚本;当使用 async 时,加载文档的过程将和 JS 脚本的加载与执行并行进行,但 JS 脚本加载完会立马执行。
静态资源压缩。静态资源通常包含了 CSS 样式文件、JS 脚本、图片等等,静态资源文件的大小会影响浏览器的加载速度,我们可以通过网上现有的工具手动去压缩,也可以通过 Webpack、Gulp 等构建工具,还可以通过服务器端开启 gzip 压缩去压缩静态资源。
使用 CDN。CDN 能够加速静态资源加载。
使用 iconfont。iconfont 是阿里巴巴矢量图标库,可以将图标上传到该网站后将图标转换成矢量在代码中实现。
代码优化
减少访问 DOM 的次数并将经常需要访问的 DOM 元素和属性保存到变量中。访问 DOM 会比较消耗性能,而直接访问变量比访问 DOM 元素和属性要快很多。
减少重排和重绘,必要时让元素脱离文档流。在操作 DOM 的时候可能会造成重排与重绘,重排和重绘对性能影响很大,如果在操作 DOM 的时候会造成多次重排与重绘,可以先让元素脱离文档流,处理完毕后再让元素回归文档流,这样浏览器只会进行两次重排与重绘(脱离时和回归时)。
善用事件委托。对多个同级相同的元素绑定事件后执行时会比较消耗内存影响性能,使用事件委托的方式能够提升页面性能。
提升数据访问速度。不同的数据访问的速度是不一样的,我们应该避免去访问那些速度慢的数据。比如在搜索变量的过程中,如果该变量存在其上下文的作用域链越末端,则搜索速度越慢;访问对象属性时,该属性嵌套得越深,则访问速度越慢;在查找实例中的属性或方法时,若其存在原型链中的位置越深,则查找的速度越慢。对于频繁需要访问的速度慢的数据,可以将其直接存储起来以便后续的访问。
作者:淘淘笙悦
链接:https://www.jianshu.com/p/31226d0d8478