前端性能优化(Vue项目)

1,295 阅读5分钟

近期在项目中遇到一个性能优化的问题,Vue所构建的项目首页渲染的时间长达6到7s,这是不能接收的,对此进行了一系列的性能优化将首屏的渲染时间缩短到2到3s。其性能优化方式都是可复现的,供大家参考~~~

在谈性能优化的时候,首先要知道项目出现了什么问题,有什么样的解决方法。性能优化可以分为以下几个方面。

一 减少打包文件的体积

  1. Tree Shaking:使用Tree Shaking的方式引入外部第三方的模块,使用哪一部分的代码就引入哪一部分的方法。
  2. CDN引入:也可以使用CDN的方式引入第三方模块,CDN其实就是一个内容分发网络,可以快速的获取所要加载的资源。
  3. 进行图片压缩:小的图片可以使用base64的格式减少请求的数量,也可以使用精灵图或者WebP格式的图片减少图片的体积。
  4. 按需加载组件:对于某些组件,采用动态引入的方式,按需加载,当需要加载的时候再加载,提高首屏的渲染效率。
  5. build时删除source-map文件,这个文件建立了原代码和打包代码之间的一种映射,方便调试代码,但是生产环境下并不需要。
  6. 删除log和注释。
  7. 在打包时进行代码拆包,而不是将所有的文件都打包进一个js文件中,这样会导致js文件过大,增加首屏渲染时的白屏时间。
  8. 采用gzip压缩:gzip是一种高效的压缩算法,可以减少打包代码的体积。
  9. 抽离css,并使css按需加载。对css,html,js代码进行压缩。

二 从网络层面

  1. 减少请求的次数:对于某些图片可以做成精灵图,对与某些频繁的并且数据不咋发送变化的请求采用本地缓存。采用节流/防抖减少向服务器发送请求的次数。
  2. 采用HTTP2:HTTP2的新特性,包括头部压缩,多路复用,服务器端推送等新特性可以提高网络传输效率,提高页面的加载速率。
  3. 采用浏览器缓存。
  4. 对于某些即将使用的文件可以使用预加载,在浏览器空闲时加载该资源。
  5. 图片懒加载:如果页面中图片过多时,可以采用图片懒加载的方式进行性能优化,当图片进入到可视区域中时,为其动态设置src属性向服务器发送获取图片的请求。
  6. 采用服务器端渲染:对于某些频繁更新的页面,可以采用服务器端渲染的方式提高页面渲染性能。

三 Dom层面

核心就是减少Dom的操作次数,最小化页面的回流和重绘。在这个方面,vue3已经优化的比较彻底了,包括diff算法,异步更新队列等。浏览器也对回流和重绘进行了一定的优化,浏览器有一个渲染队列,每隔一段时间或者队列的长度到达了一定的数量就取出队列中的部分操作进行页面的渲染,将多次的回流,重绘操作变成一次回流,重绘操作。但是还是有一些优化方法:

  1. 采用DocumentFragement:当涉及多次Dom操作时,可以采用DocumentFragement减少页面的回流次数。DocumentFragement也相当于一个标签,但它是在内存中的对页面的结构不会产生影响。当页面插入DocumentFragement元素时会把所有的子标签插入到页面中,将多次的Dom操作转化为一次的Dom操作。
  2. 对于某些动画,会改变元素的大小位置,可以使其脱离文档流。
  3. 使用事件委托:利用事件冒泡的原理将事件定义在父元素中,减少定义事件的数量,减轻内存压力。

四 项目中

在项目中就是一些比较小的优化项了(Vue):

  1. v-for中的key的使用:注意不要将数组的下标作为key。
  2. v-if和v-for的合理使用:在vue2中v-for的优先级高于v-if,可以在同一个标签上定义,但是不建议这么做,会造成大量的性能消耗。在vue3中,v-if的优先级高于v-for,不能在同一个标签上使用,如果有这种v-if和v-for的需求,可以再定义个父标签写v-for或者将判断的逻辑写道函数或计算属性中(推荐)。
  3. keep-alive缓存组件。
  4. 骨架屏:主要用于首页渲染优化,通过提供一个占位动画缓解用户等待页面加载的心理,目前再app上应用的比较多。
  5. 虚拟列表:当页面一次要加载100000条数据时,可以采用虚拟列表的方式,将所有要加载的数据保存在一个数组中,通过可视区域的变化再决定去渲染哪部分数据。还有一种方法是使用requestAnimationFragement(浏览器每刷新一次就会执行一次)+ DocumentFragement进行定时,在每个tick中只进行一部分的数据操作。
  6. 合理使用计算属性,计算属性与普通函数的区别是计算属性具有缓存。
  7. 如果一个页面有上百个请求,如何优化?在浏览器中,同一个域名最多一次性可以发送6到8个请求,可以使用一个缓冲队列(长度为6~8),当队列满时堵塞请求的发送,否则则发送请求。