所谓的性能优化在我看来就是访问速度的一个提升,那如何提升呢?下面是我的一些粗鄙的见解,请参考:
用过vue 的开发者应该都晓得开发vue 项目随着项目开发愈久用到的插件越来越多的情况下打包后的chunk-vendors.js文件会越来越大,这个是最常见的导致页面加载缓慢文件之一:
推荐两款常见的比较好用的分析工具:
1、vue ui(可参考此博客vue ui 如何操作的)
2、webpack-bundle-analyzer打包文件分析工具webpack-bundle-analyzer
chunk-vendor.js文件说明: 来自第三方插件,也就是node_modules/ 下所有用到的依赖包集合的打包文件的输出。
下面是个人项目vue,config.js部分配置文件供参考:有更好建议请留言赐教
分包方式优化chunk-vendors.js 过大问题
- const { defineConfig } = require('@vue/cli-service');
- const path = require('path');
- // const useCDNs = require('./useCDNs');
- const webpack = require('webpack');
- const CompressionPlugin = require('compression-webpack-plugin');
- // const zlib = require('zlib');
-
- function resolve(dir) {
- return path.join(__dirname, dir);
- }
-
- module.exports = defineConfig({
- transpileDependencies: true,
- productionSourceMap: false,
- });
- module.exports = {
- // productionSourceMap: false,
- publicPath: '/',
- parallel: false,
- pwa: { // pwa 缓存处理
- iconPaths: {
- favicon32: 'favicon.ico',
- favicon16: 'favicon.ico',
- appleTouchIcon: 'favicon.ico',
- maskIcon: 'favicon.ico',
- msTileImage: 'favicon.ico',
- },
- },
- // 不输出 map 文件,以加速生产环境构建
- chainWebpack: (config) => {
- config.module
- .rule('md')
- .test(/\.md/)
- .use('vue-loader')
- .loader('vue-loader')
- .end()
- .use('vue-markdown-loader')
- .loader('vue-markdown-loader/lib/markdown-compiler')
- .options({
- raw: true,
- });
- config.module.rule('svg').exclude.add(resolve('src/icons')).end();
- config.module
- .rule('icons')
- .test(/\.svg$/)
- .include.add(resolve('src/icons'))
- .end()
- .use('svg-sprite-loader')
- .loader('svg-sprite-loader')
- .options({
- symbolId: 'icon-[name]',
- })
- .end();
- },
- configureWebpack: {
- resolve: {
- alias: {
- '@': path.resolve(__dirname, './src'),
- '@i': path.resolve(__dirname, './src/assets'),
- },
- },
- plugins: [
- new webpack.IgnorePlugin({
- resourceRegExp: /^\.\/locale$/,
- contextRegExp: /ElementPlus$/,
- }),
- new CompressionPlugin({ // 开启gzip压缩
- filename: '[path][base].gz',
- algorithm: 'gzip',
- test: /\.ts$|\.js$|\.css$|\.html$/,
- threshold: 10240,
- minRatio: 0.8,
- }),
- ],
- // 开启分离 js
- optimization: {
- runtimeChunk: 'single',
- splitChunks: {
- chunks: 'all',
- // maxInitialRequests: Infinity,
- // minSize: 20000,
- cacheGroups: {
- commons: {
- // split async commons chunk
- name: 'chunk-async-commons',
- minChunks: 2,
- priority: 40,
- chunks: 'async',
- },
- elementPlus: {
- name: 'chunk-elementPlus', // split elementUI into a single package
- priority: 30, // the weight needs to be larger than libs and app or it will be packaged into libs or app
- test: /[\\/]node_modules[\\/]_?element-plus(.*)/, // in order to adapt to cnpm
- },
- },
- },
- },
- },
- devServer: {
- //开发服务的一些处理
- },
- };
依赖包通过cdn方式引入来优化项目打包过大问题:
弊端: cdn外链资源请求慢的情况下,或者cdn当掉的话,那么项目启动肯定是会直接当掉或者一直加载中
- /** @file useCDNs.js */
-
- /** @typedef {string} ModuleName 模块名 */
- /** @typedef {string} ModuleRefer 模块在全局的引用 */
- /** @typedef {string} ElementTem 元素模板 */
- /** @typedef {{mod:ModuleName;refer:ModuleRefer;el:ElementTem}} CDNItem cdn 项目 */
-
- /**
- * cdn 使用函数。
- *
- * 此函数可以在指定开发环境中,指定某些模块作为外部依赖出现,并把准备好的第三方 cdn 模板以 `cdns` 参数通过 HtmlWebpackPlugin 插件插入到 `public/index.html` 文件中。
- * 你可以在 `public/index.html` 中使用 ejs 语法 <%= htmlWebpackPlugin.options.cdns %> 来插入准备好的 cdn。
- *
- * @param {import('webpack-chain')} config webpack-chain 实例
- * @param {CDNItem[]} cdns 传入需要使用的 cdn 数组
- * @param {string} env 什么环境下使用 cdn ,默认生产环境
- */
- module.exports = function useCDNs(config, cdns = [], env = 'production') {
- if (process.env.NODE_ENV !== env) return;
-
- config.externals(
- cdns.reduce((prev, v) => {
- prev[v.mod] = v.refer;
- return prev;
- }, {})
- );
-
- config.plugin('html').tap((args) => {
- args[0].cdns = cdns.map((v) => v.el).join('');
- return args;
- });
- };
在vue.config.js 中使用useCDNs.js将需要用的cdn资源注入
下面使用elemet-ui为例子:线上环境使用cdn方式,开发环境使用依赖方式、样式文件可以通过
在main.js/main.ts 中引入
- const { defineConfig } = require('@vue/cli-service');
- const path = require('path');
- // const useCDNs = require('./useCDNs');
- const webpack = require('webpack');
- const CompressionPlugin = require('compression-webpack-plugin');
- // const zlib = require('zlib');
-
- function resolve(dir) {
- return path.join(__dirname, dir);
- }
-
- module.exports = defineConfig({
- transpileDependencies: true,
- productionSourceMap: false,
- });
- module.exports = {
- // productionSourceMap: false,
- publicPath: '/',
- parallel: false,
- pwa: {
- iconPaths: {
- favicon32: 'favicon.ico',
- favicon16: 'favicon.ico',
- appleTouchIcon: 'favicon.ico',
- maskIcon: 'favicon.ico',
- msTileImage: 'favicon.ico',
- },
- },
- // 不输出 map 文件,以加速生产环境构建
- chainWebpack: (config) => {
- // 只在生产环境使用 cdn
- useCDNs(config, {
- mod: 'moment',
- refer: 'moment',
- el: 'https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js',
- });
- configureWebpack: {
- resolve: {
- alias: {
- '@': path.resolve(__dirname, './src'),
- '@i': path.resolve(__dirname, './src/assets'),
- },
- },
- plugins: [
- new webpack.IgnorePlugin({
- resourceRegExp: /^\.\/locale$/,
- contextRegExp: /ElementPlus$/,
- }),
- new CompressionPlugin({
- filename: '[path][base].gz',
- algorithm: 'gzip',
- test: /\.ts$|\.js$|\.css$|\.html$/,
- threshold: 10240,
- minRatio: 0.8,
- }),
- ],
- // 开启分离 js
- optimization: { // 如果打包出的chunk-vender文件过大的话使用它
- runtimeChunk: 'single',
- splitChunks: {
- chunks: 'all',
- // maxInitialRequests: Infinity,
- // minSize: 20000,
- cacheGroups: {
- commons: {
- // split async commons chunk
- name: 'chunk-async-commons',
- minChunks: 2,
- priority: 40,
- chunks: 'async',
- },
- elementPlus: {
- name: 'chunk-elementPlus', // split elementUI into a single package
- priority: 30, // the weight needs to be larger than libs and app or it will be packaged into libs or app
- test: /[\\/]node_modules[\\/]_?element-plus(.*)/, // in order to adapt to cnpm
- },
- },
- },
- },
- },
- devServer: {
- },
- };

简单记录有问题可私信解决