项目技术栈

1.vue 2.6.10
2.vue/cli 4.5.15

初始构建大小

dist文件夹内容
初始build的结果如上图所示,整个dist文件夹大小是49.7MB,从文件上可以看到,app.js、0.js、2.js、3.js文件夹非常大,这种时候就要找找原因了

引入辅助工具

既然要分析这些比较大的文件里面都有些什么, 我们就引入一下分析包的工具,webpack-bundle-analyzer:

npm install --save-dev webpack-bundle-analyzer

接着在vue.config.js中要做一些配置

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
	configureWebpack: (config) => {
		return {
			//...
			plugin: [
				new BundleAnalyzerPlugin({
		            analyzerPort: 8889, // 分析页面
		            openAnalyzer: false // 默认不打开分析模块页面
		        })
			]
			//...
		}
	}
}

配置好了,看看效果,执行一下编译打包的命令

npm run build

编译完成之后,打开浏览器,地址栏输入localhost:8889
打包文件分析

从上图就很明显看到哪些文件占的大。好了,接下来做一些针对性的解决方法吧。


优化一:cdn引入

首先让我很耿耿于怀的就是这个ercharts,确实用的多,打包之后也很占空间,所以我决定用cdn来引入:

public/index.html

<script crossorigin="anonymous" src="https://lib.baomitu.com/echarts/5.2.1/echarts.min.js"></script>

其它版本你们自己移步到链接: echarts

配置vue.config.js

module.exports = {
	chainWebpack: config => {
	    // ...
	    var externals = {
	      'echarts': 'echarts',
	    }
	    config.externals(externals)
	    config.plugins.delete("prefetch") //配置可以取消首屏渲染时对组件js文件的预加载, 实现真正的按需加载
	},
	//...
}

使用方法

import * as echarts from 'echarts'

哪个页面需要用到,就按照上面的引入就行,也可以在main.js全局引入,这样就可以直接使用echarts.init()等方法了

重新打包看效果

我忘记截图了,你们可以自己看看效果哈,就echarts.js部分就没了,我这边是缩小了6MB


优化二:按需引入

按需引入的话,其实是编码习惯来的,有些项目为了方便,就在main.js中全局引用样式框架等,最后有没有用到其实也不知道,打包的时候还一起打包了,所以导致打包之后体积很大,在main.js中全局引用element-ui的童鞋看过来:

安装插件

npm install babel-plugin-component -D

配置babel.config.js

module.exports = {
  presets: [
    '@vue/app'
  ],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

重新打包看效果

你们可以自己看看效果哈。


优化三:懒加载

经过前面两个步骤的优化之后我们会发现,虽然app.js是有变小,但是首屏加载整个app.js的时候,还是很慢,它还是很大,这种时候,我们应该去拆分它,使得每个页面只加载自己所需要的文件,就要用到懒加载啦!

先来看一段vue-router官网文字

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

那就来试试:

router.js

const router = createRouter({
  // ...
  routes: [{ path: '/users/:id', component: () => import('./views/UserDetails')}],
})

接着我在vue.config.js中加一些配置,你们可配可不配,我就是为了打包之后js文件放在文件夹内

module.exports = {
	configureWebpack: (config) => {
		return {
			//...
			output: {
	          // 防止打包js不在js文件夹下,生成新的js名称防止缓存
	          filename: `js/[name].[hash].js`
	        },
			plugin: [
				new BundleAnalyzerPlugin({
		            analyzerPort: 8889, // 分析页面
		            openAnalyzer: false // 默认不打开分析模块页面
		        })
			]
			//...
		}
	}
}

打包看效果
打包之后发现js文件变多了,但是基本上体积都很小,部署之后也会发现速度快了很多,因为首屏需要加载的内容也不多,然后你会发现打包出来的很多js文件命名是0,1,2,3,4这种,你不知道对应那个页面的,这种时候,我们可以引入chunkFilename

修改一下router.js

const router = createRouter({
  // ...
  routes: [{ path: '/users/:id', component: () => import(/* webpackChunkName: "UserDetails" */'./views/UserDetails')}],
})

修改一下vue.config.js

output: {
	filename: `js/[name].[hash].js`,
	chunkFilename: `js/[name].[hash].js`
},          

重新打包看效果

打包之后js文件命名就不是0,1,2…这种了,并且你会发现,同一个命名文件的页面,会打包到同一个js文件里面,看自己需求做哈,还有chunkname是可以动态设置的,有些项目的路由是遍历出来的,需要动态命名chunkname,有兴趣自己查一下哈


优化四:压缩文件

优化进行到这里,其实页面加载速度已经快了很多了,总体的文件还是比较大的,所以我们再搞一个压缩插件,引入compression-webpack-plugin

npm install compression-webpack-plugin -D

修改vue.config.js

const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
	configureWebpack: (config) => {
		return {
			//...
			new CompressionWebpackPlugin({
	            filename: '[path].gz[query]',
	            algorithm: 'gzip',
	            // test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
	            test: /\.js$|\.css$/,
	            threshold: 10240, // 只有大小大于该值的资源会被处理,当前配置为对于超过1k的数据进行处理,不足1k的可能会越压缩越大
	            minRatio: 0.99, // 只有压缩率小于这个值的资源才会被处理
	            deleteOriginalAssets: true // 删除原文件
	         }),
			output: {
	            // 防止打包js不在js文件夹下,生成新的js名称防止缓存
	            filename: `js/[name].[hash].js`,
	            chunkFilename: `js/[name].[hash].js`
	        },
			plugin: [
				new BundleAnalyzerPlugin({
		            analyzerPort: 8889, // 分析页面
		            openAnalyzer: false // 默认不打开分析模块页面
		        })
			]
			//...
		}
	}
}

重新打包看效果
js和css压缩之后体积更小了
压缩文件后
压缩文件后2.0


总结

—加载速度慢原因分析—

1.懒加载只使用在部分路由上,导致没有用懒加载的部分全部打包之后塞在app.js文件中,首屏加载时app.js加载完使用的时长较长;

2.页面引用了很多其实没有实际用到的插件,导致打包之后插件的体积较大;

3.echarts和vue-echarts的重复引用;

4.没有按需引用插件,像elementui直接在main.js中use,但是没有做打包过滤没有用到的样式处理;

【优化前】1分15秒 49.7MB

【优化后】3.5秒 10.7MB

注意:优化体积大小变化不大,但是因为使用懒加载,不会存在像之前那种单个包十几个M的问题.

有问题的地方,请大家不吝指教!

Logo

前往低代码交流专区

更多推荐