Open yanyue404 opened 1 year ago
举例以一个 Vue 全家桶 项目为例~
各项指标说明:https://mp.weixin.qq.com/s?__biz=Mzg5MDY1MjIxMA==&mid=2247496148&idx=1&sn=e7afda57d67a1d87ee0a42a907c6ef52&source=41#wechat_redirect
vue.all.runtime.js
『Webpack 系列』—— SplitChunks 插件用法详解 :https://juejin.cn/post/6844904198023168013
用 SplitChunks 插件来控制 Webpack 打包生成的 js 文件的内容的精髓就在于,防止模块被重复打包,拆分过大的 js 文件,合并零散的 js 文件。最终的目的就是减少请求资源的大小和请求次数。因这两者是互相矛盾的,故要以项目实际的情况去使用 SplitChunks 插件,需切记中庸之道。
{ optimization: { splitChunks: { cacheGroups: { vendors: { name: 'chunk-vendors', test: /[\\/]node_modules[\\/]/, priority: -10, chunks: 'initial' }, common: { name: 'chunk-common', minChunks: 2, priority: -20, chunks: 'initial', reuseExistingChunk: true } } } }
prefetch:用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容 preload:用来指定页面加载后很快会被用到的资源,所以在页面加载的过程中,我们希望在浏览器开始主体渲染之前尽早 preload
// 移除 preload(预载) 插件 config.plugins.delete("preload"); // 移除 prefetch(预取) 插件 config.plugins.delete("prefetch");
打包产物新增 gzip 资源,页面加载优先使用(network 请求多出 gzip 资源)
const CompressionPlugin = require("compression-webpack-plugin"); new CompressionPlugin({ algorithm: "gzip", test: /\.js$|\.html$|\.css$/, // 匹配文件名 minRatio: 1, // 压缩率小于1才会压缩 threshold: 10240, // 对超过10k的数据压缩 deleteOriginalAssets: false, });
.vue
建议 js、css、图片 单个文件资源大小不超过 100k
说明:https://www.npmjs.com/package/speed-measure-webpack-plugin
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); module.exports = { configureWebpack: (config) => { config.plugins.push(new SpeedMeasurePlugin()); }, };
npm install --save-dev vue-cli-plugin-dll
接下来就是 dll 的相关配置,将我们项目中的依赖使用 dll 插件进行动态链接,这样依赖就不会进行编译,从而极大地提高编译速度,因为这些插件没有编译,在 vue.config.js 中进行配置,也很简单
const path = require("path"); module.exports = { pluginOptions: { dll: { //这里放的是你的依赖插件,就是你项目安装的其他的插件,将这些插件的名字依次加在后面,我建议将所有项目依赖插件全部放在后面 //注意这里不能放webpack,gulp等需要node环境的插件,我尝试将babel等放到这里报错提示没有V8环境 entry: ["vue", "vue-router", "view-design"], //dll 编译后的链接库的地址 cacheFilePath: path.resolve(__dirname, "./public"), // 是否开启 DllReferencePlugin, open: true, // 在执行 `dev` , `build` 等其他指令时,程序会自动将 `dll` 指令生成的 `*.dll.js` 等文件自动注入到 index.html 中。 inject: true, }, }, };
多入口
const path = require("path"); module.exports = { pluginOptions: { dll: { // 入口配置 entry: { vue: ["vue", "vue-router", "vuex"], ui: ["view-design"], }, // 输出目录 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, }, }, };
配置好之后然后运行,进行你上面配置插件动态链接库的编译
npx vue-cli-service dll
dll 编译完成后会在上面配置的目录下生成 dll 文件夹,就可以开始跑项目了,因为这些插件都不需要编译,跑起来很流畅,修改后的热更新速度更是显著提升。我以前修改一行代码热更新编译在 30 秒以上,使用这个以后基本十秒以内搞定。
npm run serve
Vue-Cli
Vue-Cli 已经内置,开启
module.exports = { parallel: true };
parallel
是否为 Babel 或 TypeScript 使用 thread-loader。 该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
Webpack
npm install --save-dev thread-loader
配置
const path = require("path"); module.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve("src"), use: [ "thread-loader", // 耗时的 loader (例如 babel-loader) ], }, ], }, };
运用这个插件能在代码使用了 import 语法的情况下,大大提高代码的编译速度。
安装 babel-plugin-dynamic-import-node
npm install --save-dev babel-plugin-dynamic-import-node
vue-cli3
修改 babel.config.js 文件
module.exports = { presets: ["@vue/cli-plugin-babel/preset"], env: { development: { plugins: ["dynamic-import-node"] } }, };
Webpack 中几种缓存方式:
以上这些缓存方式都有首次启动时的开销,即它们会让 “冷启动” 时间会更长,但是二次启动能够节省很多时间.
Vue-Cli 已经内置了 cache-loader 进行以下两个的缓存,未添加 hard-source-webpack-plugin
cache-loader
hard-source-webpack-plugin
[ { test: /\.vue$/, use: [ { loader: "project_path\\node_modules\\cache-loader\\dist\\cjs.js", options: { cacheDirectory: "project_path\\node_modules\\.cache\\vue-loader", cacheIdentifier: "036da057", }, }, { loader: "project_path\\node_modules\\vue-loader\\lib\\index.js", options: { compilerOptions: { whitespace: "condense", }, cacheDirectory: "project_path\\node_modules\\.cache\\vue-loader", cacheIdentifier: "036da057", }, }, ], }, { test: /\.m?jsx?$/, include: ["/packages"], exclude: [ function () { /* omitted long function */ }, ], use: [ { loader: "project_path\\node_modules\\cache-loader\\dist\\cjs.js", options: { cacheDirectory: "project_path\\node_modules\\.cache\\babel-loader", cacheIdentifier: "5217b3ec", }, }, { loader: "project_path\\node_modules\\babel-loader\\lib\\index.js", }, { loader: "babel-loader", }, ], }, ];
提示:Vue-Cli 自带的 cache-loader 会默认为 Vue/Babel/TypeScript 编译开启。文件会缓存在 node_modules/.cache 中。如果你遇到了编译方面的问题,记得先清缓存目录之后再试试看。
HardSourceWebpackPlugin
详细说明 :https://www.npmjs.com/package/hard-source-webpack-plugin
在启动项目时会针对项目生成缓存,若是项目无 package 或其他变化,下次就不用花费时间重新构建,直接复用缓存。
安装
npm install --save-dev hard-source-webpack-plugin
配置 vue.config.js
为模块提供中间缓存,缓存路径是:node_modules/.cache/hard-source
node_modules/.cache/hard-source
const HardSourceWebpackPlugin = require("hard-source-webpack-plugin"); module.exports = { configureWebpack: (config) => { config.plugin.push( new HardSourceWebpackPlugin({ root: process.cwd(), directories: [], environmentHash: { root: process.cwd(), directories: [], // 配置了files的主要原因是解决配置更新,cache不生效了的问题,配置后有包的变化,plugin会重新构建一部分cache files: ["package.json", "yarn.lock"], }, }) ); }, };
举例以一个 Vue 全家桶 项目为例~
构建体积相关 + 首屏性能优化
0. 优化前使用 LightHouse(灯塔)评测各项性能指标
各项指标说明:https://mp.weixin.qq.com/s?__biz=Mzg5MDY1MjIxMA==&mid=2247496148&idx=1&sn=e7afda57d67a1d87ee0a42a907c6ef52&source=41#wechat_redirect
1. 使用 webpack-bundle-analyzer 查看冗余代码
vue.all.runtime.js
减少请求数量)2. 使用 splitChunks 插件拆分公共代码
『Webpack 系列』—— SplitChunks 插件用法详解 :https://juejin.cn/post/6844904198023168013
用 SplitChunks 插件来控制 Webpack 打包生成的 js 文件的内容的精髓就在于,防止模块被重复打包,拆分过大的 js 文件,合并零散的 js 文件。最终的目的就是减少请求资源的大小和请求次数。因这两者是互相矛盾的,故要以项目实际的情况去使用 SplitChunks 插件,需切记中庸之道。
3. 关闭 prefetch、preload
prefetch:用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容 preload:用来指定页面加载后很快会被用到的资源,所以在页面加载的过程中,我们希望在浏览器开始主体渲染之前尽早 preload
4. 前端开启 gzip(双端开启指南:https://cloud.tencent.com/developer/article/1507153)
打包产物新增 gzip 资源,页面加载优先使用(network 请求多出 gzip 资源)
5. 图片资源优化
6. 资源加载
.vue
文件异步加载)7. 生产环境
构建速度相关
1. 查看构建时间
说明:https://www.npmjs.com/package/speed-measure-webpack-plugin
2. vue-cli-plugin-dll
接下来就是 dll 的相关配置,将我们项目中的依赖使用 dll 插件进行动态链接,这样依赖就不会进行编译,从而极大地提高编译速度,因为这些插件没有编译,在 vue.config.js 中进行配置,也很简单
多入口
配置好之后然后运行,进行你上面配置插件动态链接库的编译
dll 编译完成后会在上面配置的目录下生成 dll 文件夹,就可以开始跑项目了,因为这些插件都不需要编译,跑起来很流畅,修改后的热更新速度更是显著提升。我以前修改一行代码热更新编译在 30 秒以上,使用这个以后基本十秒以内搞定。
3. thread-loader 多进程打包
Vue-Cli
Vue-Cli 已经内置,开启
parallel
是否为 Babel 或 TypeScript 使用 thread-loader。 该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
Webpack
配置
4. import 优化
运用这个插件能在代码使用了 import 语法的情况下,大大提高代码的编译速度。
安装 babel-plugin-dynamic-import-node
vue-cli3
修改 babel.config.js 文件
5. 利用缓存提升二次构建速度
Webpack 中几种缓存方式:
以上这些缓存方式都有首次启动时的开销,即它们会让 “冷启动” 时间会更长,但是二次启动能够节省很多时间.
Vue-Cli 已经内置了
cache-loader
进行以下两个的缓存,未添加hard-source-webpack-plugin
HardSourceWebpackPlugin
详细说明 :https://www.npmjs.com/package/hard-source-webpack-plugin
在启动项目时会针对项目生成缓存,若是项目无 package 或其他变化,下次就不用花费时间重新构建,直接复用缓存。
安装
配置 vue.config.js
为模块提供中间缓存,缓存路径是:
node_modules/.cache/hard-source
参考