vue项目性能优化方法

前言:

        整理相关资料,共同进步

目录:

前言

一、gzip压缩

1. 安装npm i compression-webpack-plugin -D

2. vue.config.js文件里配置

3.运行npm run build

4.添加打包分析可以更具体的查看

执行npm run build --report​

5.参考资料:

二、路由懒加载(按需加载)

1.在路由配置中import方法实现路由懒加载

2.参考资料

二、第三方插件的按需引入(按需加载)

1.安装插件

2.在.babelrc 中添加配置

3.按需加载组件

4.参考资料:

三、减少接口请求

1.每次路由跳转或者反复多次刷新时重新向服务器发送请求时取消上一次发送的接口请求

2.keep-alive页面缓存

3.防抖节流

1.防抖工具型方法封装

2.节流工具型方法封装

四、利用Object.freeze()实现vue长列表性能优化

总结

参考资料:https://blog.csdn.net/weixin_50856920/article/details/112254038


 

一、gzip压缩

gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。(需要后端支持)
请求头

1. 安装npm i compression-webpack-plugin -D

2. vue.config.js文件里配置

<span style="color:#000000"><code class="language-javascript"><span style="color:#5c6370">// 导包</span>
<span style="color:#c678dd">const</span> CompressionWebpackPlugin <span style="color:#669900">=</span> <span style="color:#61aeee">require</span><span style="color:#999999">(</span><span style="color:#669900">'compression-webpack-plugin'</span><span style="color:#999999">)</span>
<span style="color:#5c6370">// 匹配文件名</span>
<span style="color:#c678dd">const</span> productionGzipExtensions <span style="color:#669900">=</span> <span style="color:#98c379">/\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i</span>
<span style="color:#5c6370">// 配置</span>
module<span style="color:#999999">.</span>exports <span style="color:#669900">=</span> <span style="color:#999999">{</span>
 configureWebpack<span style="color:#999999">:</span> config <span style="color:#669900">=></span> <span style="color:#999999">{</span>
   <span style="color:#c678dd">if</span> <span style="color:#999999">(</span>process<span style="color:#999999">.</span>env<span style="color:#999999">.</span><span style="color:#98c379">NODE_ENV</span> <span style="color:#669900">===</span> <span style="color:#669900">'production'</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
     <span style="color:#c678dd">return</span> <span style="color:#999999">{</span>
       plugins<span style="color:#999999">:</span> <span style="color:#999999">[</span>
         <span style="color:#c678dd">new</span> CompressionWebpackPlugin<span style="color:#999999">(</span><span style="color:#999999">{</span>
           filename<span style="color:#999999">:</span> <span style="color:#669900">'[path].gz[query]'</span><span style="color:#999999">,</span>
           algorithm<span style="color:#999999">:</span> <span style="color:#669900">'gzip'</span><span style="color:#999999">,</span>  <span style="color:#5c6370">// 默认为gzip</span>
           test<span style="color:#999999">:</span> productionGzipExtensions<span style="color:#999999">,</span>
           threshold<span style="color:#999999">:</span> <span style="color:#98c379">2048</span><span style="color:#999999">,</span> <span style="color:#5c6370">// 对超过2k的数据进行压缩 </span>
           minRatio<span style="color:#999999">:</span> <span style="color:#98c379">0.8</span><span style="color:#999999">,</span>  <span style="color:#5c6370">// 仅压缩比该比率更好的(minRatio = Compressed Size / Original Size)</span>
           deleteOriginalAssets<span style="color:#999999">:</span> <span style="color:#56b6c2">false</span>  <span style="color:#5c6370">// 是否删除原文件</span>
         <span style="color:#999999">}</span><span style="color:#999999">)</span>
       <span style="color:#999999">]</span>
     <span style="color:#999999">}</span>
   <span style="color:#999999">}</span>
 <span style="color:#999999">}</span>
<span style="color:#999999">}</span>
</code></span>

3.运行npm run build

gzip压缩后,通过gzip压缩可以使Vue首页加载速度大大提升,以下是压缩前与压缩后
gzip压缩后

4.添加打包分析可以更具体的查看

<span style="color:#000000"><code class="language-javascript"><span style="color:#c678dd">const</span> BundleAnalyzerPlugin <span style="color:#669900">=</span> <span style="color:#61aeee">require</span><span style="color:#999999">(</span><span style="color:#669900">'webpack-bundle-analyzer'</span><span style="color:#999999">)</span><span style="color:#999999">.</span>BundleAnalyzerPlugin
module<span style="color:#999999">.</span>exports <span style="color:#669900">=</span> <span style="color:#999999">{</span>
   <span style="color:#5c6370">// 构建体积分析</span>
   chainWebpack<span style="color:#999999">:</span> config <span style="color:#669900">=></span> <span style="color:#999999">{</span>
     config
       <span style="color:#999999">.</span><span style="color:#61aeee">plugin</span><span style="color:#999999">(</span><span style="color:#669900">'webpack-bundle-analyzer'</span><span style="color:#999999">)</span>
       <span style="color:#999999">.</span><span style="color:#61aeee">use</span><span style="color:#999999">(</span>BundleAnalyzerPlugin<span style="color:#999999">)</span>
       <span style="color:#999999">.</span><span style="color:#61aeee">init</span><span style="color:#999999">(</span>Plugin <span style="color:#669900">=></span> <span style="color:#c678dd">new</span> Plugin<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span>
   <span style="color:#999999">}</span>
<span style="color:#999999">}</span>
</code></span>

执行npm run build --report
gzip压缩结构体积分析

5.参考资料:

CompressionWebpack插件

二、路由懒加载(按需加载)

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

1.在路由配置中import方法实现路由懒加载

代码如下(示例):

<span style="color:#000000"><code class="language-c"><span style="color:#c678dd">const</span> router <span style="color:#669900">=</span> new <span style="color:#61aeee">VueRouter</span><span style="color:#999999">(</span><span style="color:#999999">{</span>
  routes<span style="color:#999999">:</span> <span style="color:#999999">[</span>
    <span style="color:#999999">{</span> path<span style="color:#999999">:</span> <span style="color:#669900">'/foo'</span><span style="color:#999999">,</span> component<span style="color:#999999">:</span> <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#61aeee">import</span><span style="color:#999999">(</span><span style="color:#669900">'./Foo.vue'</span><span style="color:#999999">)</span> <span style="color:#999999">}</span>
  <span style="color:#999999">]</span>
<span style="color:#999999">}</span><span style="color:#999999">)</span>
</code></span>

2.参考资料

vue官方文档路由懒加载

二、第三方插件的按需引入(按需加载)

以Vant为例,借助 babel-plugin-import ,可以只引入需要的组件,以达到减少体积的目的

1.安装插件

npm i babel-plugin-import -D

2.在.babelrc 中添加配置

<span style="color:#000000"><code class="language-c"><span style="color:#5c6370">// 在.babelrc 中添加配置</span>
<span style="color:#5c6370">// 注意:webpack 1 无需设置 libraryDirectory</span>
<span style="color:#999999">{</span>
  <span style="color:#669900">"plugins"</span><span style="color:#999999">:</span> <span style="color:#999999">[</span>
    <span style="color:#999999">[</span><span style="color:#669900">"import"</span><span style="color:#999999">,</span> <span style="color:#999999">{</span>
      <span style="color:#669900">"libraryName"</span><span style="color:#999999">:</span> <span style="color:#669900">"vant"</span><span style="color:#999999">,</span>
      <span style="color:#669900">"libraryDirectory"</span><span style="color:#999999">:</span> <span style="color:#669900">"es"</span><span style="color:#999999">,</span>
      <span style="color:#669900">"style"</span><span style="color:#999999">:</span> true
    <span style="color:#999999">}</span><span style="color:#999999">]</span>
  <span style="color:#999999">]</span>
<span style="color:#999999">}</span>

</code></span>

3.按需加载组件

<span style="color:#000000"><code class="language-c"><span style="color:#5c6370">// 接着你可以在代码中直接引入 Vant 组件</span>
<span style="color:#5c6370">// 插件会自动将代码转化为方式二中的按需引入形式</span>
import <span style="color:#999999">{</span> Button <span style="color:#999999">}</span> from <span style="color:#669900">'vant'</span><span style="color:#999999">;</span>
</code></span>

4.参考资料:

Vant自动按需引入组件

三、减少接口请求

1.每次路由跳转或者反复多次刷新时重新向服务器发送请求时取消上一次发送的接口请求

  • 请求拦截器js文件中设置
<span style="color:#000000"><code class="language-c"><span style="color:#5c6370">// 取消请求</span>
let cancelArr <span style="color:#669900">=</span> <span style="color:#999999">[</span><span style="color:#999999">]</span>
window<span style="color:#999999">.</span>cancelAxios <span style="color:#669900">=</span> function <span style="color:#999999">(</span>url<span style="color:#999999">,</span> allAxios <span style="color:#669900">=</span> false<span style="color:#999999">)</span> <span style="color:#999999">{</span>
  cancelArr <span style="color:#669900">=</span> cancelArr<span style="color:#999999">.</span><span style="color:#61aeee">filter</span><span style="color:#999999">(</span>item <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#999999">{</span>
    <span style="color:#c678dd">if</span> <span style="color:#999999">(</span>allAxios<span style="color:#999999">)</span> <span style="color:#999999">{</span>
      item<span style="color:#999999">.</span><span style="color:#61aeee">c</span><span style="color:#999999">(</span><span style="color:#999999">)</span>
      <span style="color:#c678dd">return</span> false
    <span style="color:#999999">}</span> <span style="color:#c678dd">else</span> <span style="color:#999999">{</span>
      <span style="color:#c678dd">if</span> <span style="color:#999999">(</span>item<span style="color:#999999">.</span>url <span style="color:#669900">==</span><span style="color:#669900">=</span> url<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        item<span style="color:#999999">.</span><span style="color:#61aeee">c</span><span style="color:#999999">(</span><span style="color:#999999">)</span>
        <span style="color:#c678dd">return</span> false
      <span style="color:#999999">}</span> <span style="color:#c678dd">else</span> <span style="color:#999999">{</span>
        <span style="color:#c678dd">return</span> true
      <span style="color:#999999">}</span>
    <span style="color:#999999">}</span>
  <span style="color:#999999">}</span><span style="color:#999999">)</span>
<span style="color:#999999">}</span>
<span style="color:#5c6370">// 请求拦截器</span>
_fetch<span style="color:#999999">.</span>interceptors<span style="color:#999999">.</span>request<span style="color:#999999">.</span><span style="color:#61aeee">use</span><span style="color:#999999">(</span>
  function <span style="color:#999999">(</span>config<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    window<span style="color:#999999">.</span><span style="color:#61aeee">cancelAxios</span><span style="color:#999999">(</span>config<span style="color:#999999">.</span>url<span style="color:#999999">)</span>
    config<span style="color:#999999">.</span>cancelToken <span style="color:#669900">=</span> new axios<span style="color:#999999">.</span><span style="color:#61aeee">CancelToken</span><span style="color:#999999">(</span>cancel <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#999999">{</span>
      cancelArr<span style="color:#999999">.</span><span style="color:#61aeee">push</span><span style="color:#999999">(</span><span style="color:#999999">{</span>
        url<span style="color:#999999">:</span> config<span style="color:#999999">.</span>url<span style="color:#999999">,</span>
        c<span style="color:#999999">:</span> cancel
      <span style="color:#999999">}</span><span style="color:#999999">)</span>
    <span style="color:#999999">}</span><span style="color:#999999">)</span>
    <span style="color:#c678dd">return</span> config
  <span style="color:#999999">}</span><span style="color:#999999">,</span>
  function <span style="color:#999999">(</span>error<span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#c678dd">return</span> Promise<span style="color:#999999">.</span><span style="color:#61aeee">reject</span><span style="color:#999999">(</span>error<span style="color:#999999">)</span>
  <span style="color:#999999">}</span>
<span style="color:#999999">)</span>
</code></span>

路由配置里的前置守卫

<span style="color:#000000"><code class="language-c"><span style="color:#5c6370">// 前置守卫</span>
router<span style="color:#999999">.</span><span style="color:#61aeee">beforeEach</span><span style="color:#999999">(</span><span style="color:#999999">(</span>to<span style="color:#999999">,</span> from<span style="color:#999999">,</span> next<span style="color:#999999">)</span> <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#999999">{</span>
  <span style="color:#5c6370">// 每次跳转路由取消所有请求</span>
  window<span style="color:#999999">.</span><span style="color:#61aeee">cancelAxios</span><span style="color:#999999">(</span><span style="color:#669900">''</span><span style="color:#999999">,</span> true<span style="color:#999999">)</span>
<span style="color:#999999">}</span>
</code></span>

取消请求接口

2.keep-alive页面缓存

当你希望某个页面不被重新渲染,就可以使用Vue的keep-alive组件,不仅可以缓存当前页面数据,还可以避免多次重复渲染降低性能。

  • 在组件中给name
<span style="color:#000000"><code class="language-c">export <span style="color:#c678dd">default</span> <span style="color:#999999">{</span>
  name<span style="color:#999999">:</span> <span style="color:#669900">'article'</span><span style="color:#999999">,</span>
  <span style="color:#5c6370">// keep-alive的生命周期</span>
  <span style="color:#5c6370">// 初次进入时:created > mounted > activated</span>
  <span style="color:#5c6370">// 再次进入:只会触发 activated</span>
  activated <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#5c6370">// to do..</span>
  <span style="color:#999999">}</span><span style="color:#999999">,</span>
  <span style="color:#5c6370">// 退出后触发 deactivated</span>
  deactivated <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
    <span style="color:#5c6370">// to do..</span>
  <span style="color:#999999">}</span>
<span style="color:#999999">}</span>
</code></span>

在路由出口处用keep-alive组件包裹住

<span style="color:#000000"><code class="language-c">  <span style="color:#669900"><</span><span style="color:#669900">!</span><span style="color:#669900">--</span> 路由出口 <span style="color:#669900">--</span><span style="color:#669900">></span>
   <span style="color:#669900"><</span><span style="color:#669900">!</span><span style="color:#669900">--</span> include <span style="color:#669900">-</span> 字符串或正则表达式。只有名称匹配的组件会被缓存。
        exclude <span style="color:#669900">-</span> 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
        max <span style="color:#669900">-</span> 数字。最多可以缓存多少组件实例。 <span style="color:#669900">--</span><span style="color:#669900">></span>
    <span style="color:#669900"><</span>keep<span style="color:#669900">-</span>alive include<span style="color:#669900">=</span><span style="color:#669900">"article"</span><span style="color:#669900">></span>
      <span style="color:#669900"><</span>router<span style="color:#669900">-</span>view<span style="color:#669900">></span><span style="color:#669900"><</span><span style="color:#669900">/</span>router<span style="color:#669900">-</span>view<span style="color:#669900">></span>
    <span style="color:#669900"><</span><span style="color:#669900">/</span>keep<span style="color:#669900">-</span>alive<span style="color:#669900">></span>
</code></span>

3.防抖节流

1.防抖工具型方法封装

<span style="color:#000000"><code class="language-c">  function debounce <span style="color:#999999">(</span>fnEvent<span style="color:#999999">,</span> time<span style="color:#999999">)</span> <span style="color:#999999">{</span>
          var _time <span style="color:#669900">=</span> null
          <span style="color:#c678dd">return</span> function <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
            let _arg <span style="color:#669900">=</span> arguments
            let _this <span style="color:#669900">=</span> this
            <span style="color:#c678dd">if</span> <span style="color:#999999">(</span>_time<span style="color:#999999">)</span> <span style="color:#999999">{</span>
              <span style="color:#61aeee">clearTimeout</span><span style="color:#999999">(</span>_time<span style="color:#999999">)</span>
            <span style="color:#999999">}</span>
            _time <span style="color:#669900">=</span> <span style="color:#61aeee">setTimeout</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#999999">{</span>
              fnEvent<span style="color:#999999">.</span><span style="color:#61aeee">apply</span><span style="color:#999999">(</span>_this<span style="color:#999999">,</span> _arg<span style="color:#999999">)</span>
            <span style="color:#999999">}</span><span style="color:#999999">,</span> time<span style="color:#999999">)</span>
          <span style="color:#999999">}</span>
        <span style="color:#999999">}</span>
</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.节流工具型方法封装

<span style="color:#000000"><code class="language-c">  function throttle <span style="color:#999999">(</span>fnEvent<span style="color:#999999">,</span> time<span style="color:#999999">)</span> <span style="color:#999999">{</span>
        var isLoading <span style="color:#669900">=</span> false
        <span style="color:#c678dd">return</span> function <span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#999999">{</span>
          let _arg <span style="color:#669900">=</span> arguments
          <span style="color:#c678dd">if</span> <span style="color:#999999">(</span><span style="color:#669900">!</span>isLoading<span style="color:#999999">)</span> <span style="color:#999999">{</span>
            isLoading <span style="color:#669900">=</span> true
            let _this <span style="color:#669900">=</span> this
            <span style="color:#61aeee">setTimeout</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#669900">=</span><span style="color:#669900">></span> <span style="color:#999999">{</span>
              fnEvent<span style="color:#999999">.</span><span style="color:#61aeee">apply</span><span style="color:#999999">(</span>_this<span style="color:#999999">,</span> _arg<span style="color:#999999">)</span>
              isLoading <span style="color:#669900">=</span> false
            <span style="color:#999999">}</span><span style="color:#999999">,</span> time<span style="color:#999999">)</span>
          <span style="color:#999999">}</span>
        <span style="color:#999999">}</span>
      <span style="color:#999999">}</span>
</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

四、利用Object.freeze()实现vue长列表性能优化

vue利用Object.defineProperty中的setter和geeter来对数据对象进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止 vue劫持我们的数据呢?可以通过 object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。

  • Object.freeze()介绍
    Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
    Object.freeze()

总结

以上仅仅是Vue项目性能优化的一部分,以后有时间还会给大家继续更新,感谢!!!

参考资料:https://blog.csdn.net/weixin_50856920/article/details/112254038

 

猜你喜欢

转载自blog.csdn.net/weixin_44727080/article/details/112977802