dll ?

动态链接库英文为DLL,是Dynamic Link Library的缩写。DLL是一个包含可由多个程序,同时使用的代码和数据的库。

起因

在查看hzero前端项目框架介绍时提到了dll,外加之前经常看见dll文件,于是有了兴趣了解一下 webpack dll。

webpack官网介绍

记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

DLLPlugin和DLLReferencePlugin用某种方法实现了拆分 bundles,同时还大大提升了构建的速度.

模块预编译原理

webpack.dllPlugin本质是将大量复用模块且不会频繁更新的库进行预编译,且只需要编译一次,编译完成后产出指定文件(可以称为动态链接库)。在之后的构建过程中不会再对这些模块进行编译,而是直接使用DllReferencePlugin来引用动态链接库的代码,因此可以提高构建速度。一般可以将第三方模块进行预编译,如vue、vue-router、vuex等,只要这些依赖模块不更新,就不需要再重新编译。

vue-cli-plugin-dll

因为项目使用的vue-cli构建的,搜到了这么个专门的插件可以使用。
为了实践效果。使用两个项目相同的项目来进行对比。

使用** vue create test **创建了个名称为test的项目,在此基础上增加了moment / lodash / bignumber / ElementUI / Viewer / mint / VueKinesis 库来体现效果。

yarn build : 9.37s
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

yarn serve : 2.08s
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

复制上面项目出来,重命名项目为test-dll开始实现dll配置。步骤如下:

  1. 执行命令 vue add dll 来安装 vue-cli-plugin-dll 插件。

记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

  1. 新建vue.config.js 文件来进行相关的配置。
const path = require('path')
module.exports = {
    pluginOptions: {
        dll: {
         // 入口配置
         entry: ['vue','vuex','vue-router','vue-kinesis','v-viewer','moment','mint-ui','lodash','element-ui','core-js','bignumber'],
         // 输出目录
         output: path.join(__dirname, './public/dll'),
         // 是否开启 DllReferencePlugin,
         open: true,
         // 在执行 `dev` , `build` 等其他指令时,程序会自动将 `dll` 指令生成的 `*.dll.js` 等文件自动注入到 index.html 中。
         inject: true,
       }
     }
}
  1. 生成dll文件

需自行使用命令生成。

npm run dll  // or
yarn dll // or
npx vue-cli-service dll

配置完成,dll文件生成,此时已经将文件都集中到输出目录中。来看看效果吧!

yarn build: 4.17s
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

yarn serve: 0.5s
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

可以清楚的看到,无论是打包还是构建,速度快了很多。且构建出来的文件同样可以执行。我们再来对比下线上怎么请求资源的吧。

test项目:
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度
test-dll项目:
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

可以看见,主要区别在于 chunk-vendors.js 和 dll.508b73da.dll.js 。
正常的项目 chunk包大小已经到了11M,打包过程和加载也是主要花时间在这。不过并没有dll包需要加载。
相反,经过dll plugin处理后的项目,chunk包只有不到1M,dll包也只有1.6M,极大的缩减了打包和加载时间。同时在首页渲染时也是分离了代码,可以同步进行加载js文件。

当然,我这项目只有文件的引入,没有业务代码,对比才会这么震撼。但是同样可以看出dll可以实现项目的优化。

多入口配置

在这个的基础上,可以在对dll文件拆分进行优化。配置如下:

const path = require('path')
module.exports = {
    pluginOptions: {
        dll: {
         // 入口配置
         entry: {
            vue: ["vue", "vue-router", "vuex", 'vue-kinesis'],
            plugin: ["v-viewer",'moment','lodash','bignumber','core-js'],
            ui: ["mint-ui",'element-ui'],
         },
         // 输出目录
         output: {
            path: path.join(__dirname, 'public/dll'),
            filename: '[name].dll.js',
            // vendor.dll.js中暴露出的全局变量名
            // 保持与 webpack.DllPlugin 中名称一致
            library: '[name]_[hash]'
         },
         // 是否开启 DllReferencePlugin,
         open: true,
         // 在执行 `dev` , `build` 等其他指令时,程序会自动将 `dll` 指令生成的 `*.dll.js` 等文件自动注入到 index.html 中。
         inject: true,
       }
     }
}

通过配置多个entry和对应对output来接收。执行 yarn dll 命令后,会生成多个dll.js文件。

yarn build:
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度
yarn serve:
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度
记 vue-cli-plugin-dll 使用,优化vue-cli项目构建打包速度

看到打包速度又优化了些,而且可以做到dll.js文件拆分同时加载。
在引入的文件多且臃肿的情况下,使用webpack dll进行性能优化是个很好的选择。

注意事项

每当生成过dll中存在依赖需进行升级或更新的时候,都要执行 生成dll文件 的命令来生成新的文件。

发表回复