vue 项目优化的背景
项目是通过 vue-cli3 来构建的, 项目随着需求的不断增加. 代码量也在随着增大. 项目的文件大小也随着增加. 但是这一情况就变得, 异常棘手. 我们也需要找到解决办法, 来处理这件事情, 来提高项目的运行效率. 在考虑优化之前, 我们来看下在之前项目的结构中, 我们需要做什么样的优化方式.
以往项目的优化
在以往的项目中, 我们的代码基本都是通过服务端渲染方式来响应给用户. 在这种项目结构中. 代码的情况, 都是由开发人员控制, 按照自己的需要引入相关的代码库. 代码的控制基本都是按照团队规范来处理. 所以在页面引入的代码都是当前页面需要的执行代码. 代码的优化, 主要表现在:
JS,CSS 代码公用代码提取, 按照需要引入
JS,CSS 代码的最小化压缩
图片文件的压缩
gzip 的压缩
等等. 相关的优化. 这里我们就不考虑其他性能的处理. 性能的处理最主要还是就项目的情况来处理. 离开项目的性能优化, 其实都是没有说服力. 因为不同项目, 在性能优化上是不一样的, 比如某个性能优化方案在这个项目适合, 但是在另外一个项目可能就不适合了.
Vue-cli3 的优化
vue-cli3 主要还是建立在 webpack 和 webpack-dev 之上的. 所以重点优化, 也应该是通过学习 webpack 相关的配置功能来优化我们的代码. 在 vue-cli3 中有两种方式来配置 webpack. 两种方式: chainWebpack 和 configureWebpack. chainWebpack 的方式可以查看官方教程 https://github.com/neutrinojs/webpack-chain . configureWebpack 的话直接看 webpack 的官方教程 https://webpack.js.org/configuration . 再配合看 vue-cli3 的官方文档, 我们开始进一步的思考实际的优化方式. 我们新建一个 vue.config.JS 文件
- module.exports = {
- }
在优化之前, 我们先看看项目的代码情况. 这里的项目是我写的一个测试代码, 用了 element-ui 来做界面.
单个文件已经到了 8.5m, 这个是非常可怕的. 所以我们必须要做相关的优化, 减少文件的大小.
最小化处理: 代码的最优化, 我们会通过 chainWebpak 来处理. 这里使用的是 webpack 配置中的 optimization 来处理的. 我们在优化前, 看下相关文件的响应代码: 看下 App.JS 文件的返回代码:
App.JS 代码是没有做任何的优化. 所以这也是我们需要做的优化. 所以我们需要最小化这个代码
- module.exports = {
- chainWebpack: config => {
- config.optimization.minimize(true);
- }
- }
然后我们运行我们的项目, 可以看到代码的方式.
代码已经减少到 8.4M, 然后看到的源码也是压缩的了. 其他的文件大小也是相应的减少了. 这个大家可以看看自己的项目文件情况.
分割代码 分割代码是, 将某一些相关的文件放入到相应的文件中. 我们先设置一下.
- module.exports = {
- chainWebpack: config => {
- config.optimization.minimize(true);
- config.optimization.splitChunks({
- chunks: 'all'
- })
- }
- }
这时候我们的代码文件分割了出来, 单个文件最大变成了 7.4M, 单个文件的加载速度肯定是有所提升的. 当然我们还可以继续设置 splitChunks 的参数配置, 但是我这里就不带大家去设置了. 大家可以参考 splitChunks 插件的配置. 可以设置最小文件大小, 最大文件大小, 设置异步方式, 还有模块的缓存设置, 名称的设置等等. 但是一定要平衡文件大小的和分割出来的文件数量的平衡, 数量多了, 请求也会变慢的, 影响性能. 不过大家可以详细去设置一下, 看下效果, 来设置符合自己的项目参数. 我这里的话, 就只设置成这样. 避免文件数量的增加了. 当然是可以继续优化的. 我们通过其他方式来减少文件的大小.
提取公用代码, 使用免费的 cdn 资源. 首先我们要搞明白, 为什么会有个文件会如此之大? 才能去做进一步的优化. 这个文件会这么大, 最主要是我们引入了不同的模块库, 比如 vue, vuex, vue-router, element-ui 等公共资源库. 那我们是否将他们提取出来? 答案是肯定. 我们需要使用 externals 参数来配置:
- module.exports = {
- chainWebpack: config => {
- config.optimization.minimize(true);
- config.optimization.splitChunks({
- chunks: 'all'
- })
- config.externals({
- vue: 'vue',
- vuex: 'vuex',
- 'vue-router': "'vue-router'",
- 'element-ui': "'element-ui'"
- })
- }
- }
通过 externals 参数来忽略我们这些模块的打包. 然后我们重新运行项目, 看看效果.
我们的代码已经减少到 2.8M. 但是这里有个问题, 就是我们的代码没有执行起来, 报错了. 因为我们需要将 vue, vuex, vue-router 等引入到项目界面中. 我们需要对 html 做一下处理. 这里我们就引入网络上的免费资源了, 就不下载代码放到项目中了.
在 index.HTML 页面加入这些链接. 然后我们运行效果看下.
提取 CSS 代码, 到单个文件中.
有没有发现, 我们的请求中没有看到 CSS 的请求. 那是因为 CSS 代码都是放在了 JS 文件中, 他会在执行 JS 的时候, 会动态的将 CSS 代码生成 style 标签. 所以会将 CSS 代码放在 JS 中. 这也是一个造成文件过大的原因之一. 这时候我们需要提取 CSS 代码到文件. 这里我们只需要将 CSS 配置一下:
- module.exports = {
- CSS: {
- extract: true
- },
- chainWebpack: config => {
- config.optimization.minimize(true);
- config.optimization.splitChunks({chunks: 'all'})
- config.externals({
- vue: 'Vue',
- vuex: 'Vuex',
- 'vue-router': "VueRouter",
- 'element-ui': "'element-ui'"
- })
- }
- }
然后我们运行项目. 这里 CSS 的配置可以看官方的文档.
有没有发现, 我们的代码在继续减少. 已经是编程 2.3m 了, 其他都是 k 为单位了. CSS 文件我们也发现了. 这里我们还得需要提取一个 CSS 文件出来, 那就是 element-ui 的样式文件, 我们现在用的是本地引入 element-ui 的样式, 我们也改为免费资源的形式
这里我们需要把他注释掉. 然后在 HTML 文件中, 加入免费资源
然后运行项目. 找到一个 vendor 开头的 CSS 文件, 这里从 205k 减少到 8.3k
注意到的是我们这里还有 2.3M 的大文件. 我这里我们是必须继续优化的. 这里文件大的原因. 我们还引入了 vue-codemirror 这个组件, 我们也可以通过使用免费资源解决. 配置方式跟 vue, vuex, vue-router 这种方式配置, 我们就不在累赘说明. 这个组件用到了 codemirror 的样式. 也需要引入进来. 最后的效果.
已经是压缩到 1.4M 了. 经过上面的步骤, 效果还是比较明显的. 因为我们这里使用的是开发环境的模式, 其实有些代码是多出来的, 但这个环境下也是必须的. 比如热加载, webpack-dev-server 这些插件.
gzip 压缩.
gzip 压缩, 这里我们需要引入一个插件: compression-webpack-plugin. 来完成 JS 文件的压缩. 安装该插件:
NPM install --save-dev compression-webpack-plugin
然后引入相关代码:
- const CompressionWebpackPlugin = require('compression-webpack-plugin')
- const compress = new CompressionWebpackPlugin(
- {
- filename: info => {
- return `${info.path}.gz${info.query}`
- },
- algorithm: 'gzip',
- threshold: 10240,
- test: new RegExp(
- '\\.(' +
- ['js'].join('|') +
- ')$'
- ),
- minRatio: 0.8,
- deleteOriginalAssets: false
- }
- )
- module.exports = {
- CSS: {
- extract: true
- },
- configureWebpack: {
- plugins: [compress]
- },
- chainWebpack: config => {
- config.optimization.minimize(true);
- config.optimization.splitChunks({chunks: 'all'})
- config.externals({
- vue: 'Vue',
- vuex: 'Vuex',
- 'vue-router': "VueRouter",
- 'element-ui': "'element-ui'"
- })
- }
- }
这里我们只做 JS 文件的 gzip. 然后会生成一个. gz 的文件. 我们重新启动项目. 但是是无法看到效果的. 因为没有将 gz 文件让浏览器看到. 这时候, 我们需要配置下服务器. 目前现在的应用服务器, 比如 Nginx, apache 等都是支持 gzip 压缩的. 如果架设到这样的服务器上, 是不需要通过这个插件来压缩. 我们启用他们自身的 gzip 功能就可以了. 我们这样做的目的, 是为了更好的了解到 gzip 后, 文件的压缩效果. 在这里我们还需要加入 devServer 的配置:
- const compress = new CompressionWebpackPlugin(
- {
- filename: info => {
- return `${info.path}.gz${info.query}`
- },
- algorithm: 'gzip',
- threshold: 10240,
- test: new RegExp(
- '\\.(' +
- ['js'].join('|') +
- ')$'
- ),
- minRatio: 0.8,
- deleteOriginalAssets: false
- }
- )
- module.exports = {
- devServer: {
- before(App, server) {
- App.get(/.*.(JS)$/, (req, res, next) => {
- req.url = req.url + '.gz';
- res.set('Content-Encoding', 'gzip');
- next();
- })
- }
- // compress: true
- },
- CSS: {
- extract: true
- },
- configureWebpack: {
- plugins: [
- compress
- ]
- },
- chainWebpack: config => {
- config.optimization.minimize(true);
- config.optimization.splitChunks({chunks: 'all'})
- config.externals({
- vue: 'Vue',
- vuex: 'Vuex',
- 'vue-router': "VueRouter",
- 'element-ui': "'element-ui'",
- "vue-codemirror": "'vue-codemirror'"
- })
- }
- }
然后重新启动项目, 这时候你就会发现我们的 JS 文件已经压缩了, 从 1.4M 的文件到 300 多 k. 效果是很明显的.
整体的优化, 我们现在已经基本的完成. 更多的细节式优化, 有待大家去发掘. 注意: gzip 压缩里 devServer 可以直接设置成 **compress: true ** 就可以实现效果, 不必要去加入这个压缩创建, 也不需要自己去重新修改请求方式.
优化思考
从对 vue-cli3 项目框架来说, 他基本是基于 webpack 做的再次封装, 所以我们最主要的还是得了解 webpack 的相关优化配置, 来完成我们对项目的优化. 现在的插件越来越多, 但是最本质的优化方式, 还是不变. 跟以前项目优化方式是异曲同工的. 更多的细节化的操作, 大家可以继续研究. 希望对你们有所帮助. 有问题的地方, 欢迎大家指出.
附件: vue-cli3 项目框架优化 视频分享下载地址: https://pan.baidu.com/s/1q2ELgOrikuiwqjg2IfXk-g 密匙: qx1q
来源: https://juejin.im/post/5c85af5de51d451a5a520021