快速了解前端性能优化

2022-09-26 10:44:02 浏览数 (1)

前言

在前端开发的过程中,很多时候除了日常的需求开发以外,我们还需要对我们的页面进行性能优化,那么这次就分享一下前端开发我能想到的一些优化方案进行总结。

前端性能优化是什么?

有很多小伙伴无论是日常遇到优化需求或者面试的时候被问到性能优化,往往并没有很好的完整分析出性能瓶颈在那里。面试过程中,很多时候并没有能很系统的去回答完整前端的性能优化的方案。

什么是前端性能优化呢?我会分为以下两大部分:

  1. 渲染优化
  2. 加载优化
  3. 运行优化

性能优化如何分析

在对页面进行优化前,必须搞清楚到底需要优化的点在那里,是首屏加载很慢?资源加载慢?等等。那么我们需要如何分析一个页面需要如何优化呢?

首先我们必须要搞清楚你当前是优化首屏慢(白屏时间长),可交互时间长,在现在的前端开发中,往往我们通过performance来查看页面的onload时间或者domReady时间其实并不可靠。举个例子,我们一般现在开发已经越来越多使用React或者Vue这一类框架进行开发,那么我们的页面渲染大量依赖数据,那么获取数据的时候长短就显得很重要。所以会发现使用了React或者Vue的页面,在不做任何优化的情况下,白屏的时间往往会比以前是jq或者直接后端套模板输出html要慢得多。

回到问题上,如果去分析优化的方向呢?如果你是白屏优化,那么就要看html的加载时间以及domReady时间,找到导致domReady时间长的原因是哪里?如果你是要考虑可交互时间的优化,那么就需要定位页面渲染可交互元素的逻辑,如何将交互组件尽可能提前渲染。下面将会详细说说各种优化的点和方式。

渲染优化

渲染性能优化往往更多是解决白屏的问题,如果白屏时间减少,那么可交互时间也会减少!

这是一张浏览器解析html,css的流程图。

  • 解析html标签
  • 遇到style同步解析,但不会阻塞解析,但是会阻塞渲染
  • 遇到css同步加载,但不会阻塞解析,但是会阻塞渲染
  • 遇到img会同步加载,但是不会阻塞解析和渲染
  • 遇到js,默认同步加载,并阻塞渲染,运行完js后才继续渲染
  • 最后html标签渲染完,触发domReady

HTML优化:

  1. HTML优化主要体验在减少不必要的html标签数量,例如注释,这样能减少浏览器请求获取document文件时的体积大小。(建议所谈,减少不了多少东西,如果使用React或者Vue,基本可以无视)。
  2. 服务器使用gzip压缩html体积。

CSS优化:

css的有一个特点,就是浏览器遇到style或者css标签的时候,因为dom树和css树的构建是同步构建的,所以加载css或者解析style并不会阻塞dom的解释。但是因为最终的渲染树是需要dom树和css树结果得出的,所以css和style的加载和解析是会阻塞dom的渲染的。

  1. 减少css体积(gzip,webpack混淆)。
  2. 减少css的元素。
  3. 减少使用加长css解释时间的属性,例如:媒体查询、css表达式等。

JavaScript优化:

JavaScript的加载是会阻塞dom的解析和渲染的,因为js的解析线程是和ui渲染的线程公用,导致解释js时,所有渲染都必须停下,等待js的加载和执行完毕后才能继续对页面进行解释和渲染。

  1. 减少js体积(gzip,webpack混淆)。
  2. 如果js不必等待html完全解释和渲染完成才能执行的话,可以使用script标签的async属性。让js的加载不会阻塞dom的解释,但是下载完成后将会立马执行js,还是会阻塞解释和渲染,只是将阻塞延后到js加载完毕后才出发而已。
  3. 可以使用script标签的defer属性,让js的加载不会阻塞dom的解释,但是js的运行时机会在html解析完后再进行执行。

总结

一般比较好的处理方式是将css放在head进行加载,将js尽可能靠近html底部进行加载。当然也有例外,例如计算rem的js,可能需要尽可能的内联在css加载之前,在解析css之前将rem的单位计算好。或者一些收集统计的代码,尽可能内联在html的最开始。

因为html的渲染,是需要解析完dom树和css树,最终合成渲染树才能呈现画面在屏幕上,中间遇到的外部资源或者内联资源都会存在不同程度的影响渲染树的完成时间。所以总体来说就是如何让渲染树尽可能的快完成,这也是优化关键渲染路径的核心思想。

加载优化

渲染优化基本上就是对不同资源不同的作用调整位置,或者添加属性让一些本来影响解析的操作尽可能延后或者同步。但是加载优化会比渲染优化复杂得多,我主要会分成两种加载优化:

  1. 资源加载优化
  2. 网络优化

资源加载优化

资源加载优化一般的优化方案如下:

  1. js资源利用webpack进行拆分,尽可能的利用浏览器提供的并发加载来加速资源的加载速度。
  2. 对框架(React或者Vue等等)的runtime代码抽离,利用浏览器缓存对比较大的框架文件进行缓存,提高框架的runtime.js的加载速度。
  3. 对公用js文件,如swiper,axios等常用工具库进行拆分,理由同上。
  4. 异步加载非首屏或可视范围外的组件,利用webpack的异步加载或者利用框架自带的一些工具进行组件抽离,尽可能减少首屏加载时的业务代码体积。
  5. 对于图片资源应该使用懒加载的方式进行渲染,而且为了节省带宽,应该将图片放到首屏出来后再开始进行加载。
  6. 可以使用preload对本页资源进行预加载,例如字体文件,可以让css使用的字体可以提前进行加载。
  7. 可以使用prefetch对之后其他页面可能用到的资源进行预加载。优先级会比preload低。
  8. DNS 预解析 dns-prefetch,对一些常用的域名进行预解析,提高dns的速度。

网络优化

网络优化一般需要协同后端或者运维人员进行解决,但是作为前端,我们可以发现问题,并且提出解决的方式,优化的方案如下:

  1. 静态资源上cdn。
  2. 接口拆分,对首屏用到的接口进行拆分。
  3. 后端返回html时间优化。
  4. 对资源按需处理过期时间,对于长久的资源使用超长过期时间,并通过webpack构建出带有文件md5的文件名,对文件进行强制更新。
  5. 启用http2.0,使用多路复用,提高并发请求中的tcp重复握手问题。

运行优化

运行优化是指对于JavaScript代码的运行速度优化,这个网上也有很多资料,我就举一些常规优化。

  1. 慎用定时器,用完记得清除
  2. 虚拟滚动,长列表优化
  3. 图片按需加载
  4. 事件委托
  5. 减少阻塞线程操作,例如数据量大的循环,频繁的事件响应(节流,防抖)
  6. ...

总结

前端的性能优化并不能说有一套万能的方案,上面所说到的仅仅只是我日常开发过程中,使用过的一些性能优化的方案总结,多种方案可以搭配使用,但是还是需要根据每个公司不同团队,以及页面的性质做优化的完整方案。例如能不能用SSR进行渲染Vue或者React的页面,能不能让App中对html的加载做拦截,实现本地html的超级缓存等操作。具体问题需要具体分析。希望还有优化的骚操作进行补充。

0 人点赞