likes
comments
collection
share

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

作者站长头像
站长
· 阅读数 22

前言

首先我们需要确认一点,不管是webpack也好,vite也好,rollup也好,他们都只是构建工具,所以这一章我们就来探索一下项目在构建时的策略所能带来的性能优化。想学习webpack的同学,请戳 >>> 重学webpack系列(九) -- webpack的高级特性与前端性能优化

分包策略

  • 背景:在项目开发中,我们肯定是会去引用第三方包里面的某个或多个方法,但是打包之后,我们会发现,三方包的代码与业务代码会糅杂在一起,因为三方库代码一般是永久不变的,而业务代码可能会经常变化,那么每一次打包就会重新打包所有文件,这将会造成浏览器缓存失效。为什么浏览器缓存会失效?因为每一次重新打包之后文件名会变化,文件名变化之后,浏览器会重新请求资源包,所以需要分包策略来实现资源包的拆分,以达到浏览器只对有过更改的资源包进行请求。
  • 示例:我们以lodash库作为示例。
import {debounce} from 'lodash'; // 导入debounce

const list = [1,2,3];

function abc(list){
  list.forEach(ele=>{
    console.log(ele)
  })
}

debounce(abc(list), 2000) // 测试代码而已

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化 根据上面的图,我们看到我只用了debounce一个方法,他却把整个lodash一起打包了,所以我们需要把lodash包拆出来单独打包。

  • 实践:vite给我们提供了一个build配置,来实现分包。
export default defineConfig({
  ...
  build:{ // 生产环境的配置
    rollupOptions:{ // 给rollup的配置
      output:{ // 输出
        assetFileNames:"[name]-[hash].[ext]", // 文件名处理
        manualChunks:(id)=>{ // 分包
          if(id.indexOf('node_modules') !== -1){
            return 'vendor' // 如果参与打包的模块含有node_modules里面的模块,那么就打包到vendor里面
          }
        }
      }
    },
    assetsInlineLimit:"1024", // 大于1024kb资源,打包成base64,
    outDir:"build",
    assetsDir:"static",
    minify:false
  },
})

结果是产生了一个vendor来专门存放lodash库的代码。

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

我们的业务代码只会放进index-*.js中。

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化 比如我们再去添加其他的库看看打包效果,添加如下代码:

import $ from 'jquery';

const arr = $.merge([1,2], [3,4])

console.log('arr////',arr);

明显可见jQuery被打包进了vendor中,业务代码进了index-*.js

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化 所以我们可以在浏览器端通过更改文件来测试一下。

  • 首次刷新:

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

  • 更改testJQuery.js之前:

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

  • 更改testJQuery.js之后:

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

所以这就实现了我们分包策略,能够很大程度的去减少网络请求资源所需要的时间,提高收益。

多入口打包策略

webpack一样,vite也具有多入口打包的策略,vite提供了一个input配置项,能够指定多个入口进行打包,比如:

```js
export default defineConfig({
  ...
  build:{ // 生产环境的配置
    rollupOptions:{ // 给rollup的配置
      input:{ // 配置入口,默认index.html为入口
        dev:path.resolve(__dirname, 'dev.js'),
        prod:path.resolve(__dirname, 'prod.html'),
        index:path.resolve(__diename, 'index.html')
      },
      output:{ // 输出
        assetFileNames:"[name]-[hash].[ext]", // 文件名处理
        manualChunks:(id)=>{ // 分包
          if(id.indexOf('node_modules') !== -1){
            return 'vendor' // 如果参与打包的模块含有node_modules里面的模块,那么就打包到vendor里面
          }
        }
      }
    },
    assetsInlineLimit:"1024", // 大于1024kb资源,打包成base64,
    outDir:"build",
    assetsDir:"static",
    minify:false
  },
})

前端构建工具vite进阶系列(六) -- vite在实际项目中所能带来的性能优化

vite对于多入口打包,会自动进行依赖检测,如果有第三方包的时候,会自动打包进一个文件,与业务代码分离开,这是vite自己做的优化,比较不错。

dev-25b8fa7e.js中,我们会看到import { $, l as lodashExports } from "./lodash-0339e1c5.js";这一行代码,同时在index-16444b52.js中,我出现了相同的代码。

gzip压缩策略

  • 描述:通常是服务端对资源进行压缩,浏览器端对资源进行解压。
  • 背景:通常情况下,一个文件顶多十几kb、几十kb,如果资源真的过大,那就是相当严重的情况了,上面我们讲解了分包策略,这里我们使用gzip压缩。
  • 实践:vite提供了vite-plugin-compression来进行gzip压缩。
import viteCompression from 'vite-plugin-compression';

export default defineConfig ({
    ...
    plugins: [viteCompression()],
})

这个插件就是开箱即用的,但是我们需要去告知后端设置解压缩方式为:"Content-Encoding":"gzip"。但是物极必反,不是很大的文件,就不需要去开启gizp压缩,因为浏览器解压缩,也需要时间。

动态导入策略(Dynamic import)

vite的动态导入不像webpack一样,因为webpack在初期会遍历所有依赖形成依赖图,再去启动一个devServer,所以他的动态导入只是针对于编译阶段(或许这样说的不妥),但是vite相比于webpack来讲,确实没有前期这样的一个构建过程,而是先启动一个开发服务器,在请求到入口文件的时候,根据入口文件里面的内容,可能再会去请求其余的依赖,这种按需加载称之为动态导入。动态导入的示例可以参照 >>>重学webpack系列(九) -- webpack的高级特性与前端性能优化

cdn加速策略

  • 背景:因为客户在使用我们的应用的场景可能在全球各地,你的服务器只是在某一地,这样客户客户端请求资源的时候,就必须先到达你的服务器,如果距离过长,那么http请求链路耗时就会过长,cdn策略表示,多台服务器具有资源,你请求距离你距离最近的一台资源就可以了。
  • 实践:vite给我们提供了一个插件vite-plugin-cdn-import
// vite.config.js
import reactRefresh from '@vitejs/plugin-react-refresh'
import importToCDN from 'vite-plugin-cdn-import'

export default {
    plugins: [
        importToCDN({
            modules: [
                {
                    name: 'react', // cnd导出名字,
                    var: 'React', // cdn导出全局变量,比如jQuery:$,lodash:_
                    path: `umd/react.production.min.js`, // cdn地址,用script引入页面
                },
                {
                    name: 'react-dom',
                    var: 'ReactDOM',
                    path: `umd/react-dom.production.min.js`,
                },
            ],
        }),
    ],
}

是不是经过上述这么一整,加载资源的速度又快了很多?

总结

关于vite里面的代码压缩等一些功能,vite已经帮我做了,这里我们就不去深究了,下一章 >>> 前端构建工具vite进阶系列(七) -- vite与框架的结合实践

转载自:https://juejin.cn/post/7208844516949164090
评论
请登录