优化策略
一、生成打包报告
打包时,为了直观地发现项目中存在的问题,可以在打包时生成报告。生成报告的方式有两种:
1.通过命令行参数的形式生成报告
/通过vue-c1i的命令选项可以生成打包报告,--report
选项可以生成 report.html以帮助分析包内容
vue-cli-service build --report
2.通过可视化的U面板直接查看报告(推荐)
在可视化的U面板中,通过控制台和分析面板,可以方便地看到项目中所存在的问题。
输入vue ui
命令即可启动可视化环境,build
项目就能生产打包报告
主要看两个地方:
-
仪表盘:可以清晰的看到状态,错误,警告,依赖项,资源等等
-
分析:以饼状图形式展示了各个文件的体积,包括插件如elementUI,各个依赖,项目打包文件等
知道了这些体积较大的文件后,就要想办法减少这些文件的体积,优化项目
3.仪表盘各文案介绍:
额外补充的知识点
- 状态——编译状态,成功/失败
- 错误——错误数量,右上角输出栏可查看日志,优化点
- 警告——警告数量,右上角输出栏可查看日志 ,优化点
- 资源——整个项目的大小,最底下会有详细列表,优化点
- 模块——模块的大小,优化点
- 依赖项——安装的依赖总大小,最底下会有详细列表 ,优化点
- 速度统计——不同平台及网络环境下,项目启动或编译耗时,优化点
二、第三方库启用CDN
1.知识点:
通过 externals加载外部CDN资源(只需生产环境配置)
默认情况下,通过import语法导入的第三方依赖包,最终会被打包合并到同一个文件中,从而导到打包成功后,单文件体积过大的问题。
为了解决上述问题,可以通过webpack的externals节点,来配置并加载外部的CDN资源。
凡是声明在externals中的第三方依赖包,都不会被打包
构建过程:
- 当开始构建项目时,执行到 import语句时,会优先去 externals节点中找该import的内容是否配置
- 如果已经配置,则不会将import的依赖打包到一个集体文件中 (如js/chunk-0417f7b8.68dd8166.js)
具体项目运行时,如果导入依赖,则去全局window对象中找到该import对象并直接使用,因为已经通过CDN获取了对应的依赖资源
2.实战:
第一步:在vue.config.js中加入 externals节点配置,如下:
// 生产环境配置
config.when(process.env.NODE_ENV === 'production', config => {
// 链式编程 先获取名为'app'的默认打包入口,然后清除掉,接着再添加自定义的入口文件
config.entry('app').clear().add('./src/main-prod.js')
// 通过externals节点加载外部CDN资源
config.set('externals', {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})
})
值得注意的是:element-ui 并没有在以上配置中,这是因为它直接引入CDN链接就可以,不需要这样配置
第二步:在public/index.html 首页文件中引入外部CSS
<!-- nprogress 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
<!-- 富文本编辑器 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
<!-- element-ui 的样式表文件 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
第三步:在public/index.html 首页文件中引入外部js
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.19.2/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.15/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.7.0/echarts.min.js"></script>
<script src="https://cdn.bootcss.com/less.js/3.11.1/less.min.js"></script>
<script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
<!-- 富文本编辑器的 js 文件 -->
<script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.13.0/index.js"></script>
第四步:main-prod.js中删除不必要的导入
如以下这些import都可以删除
// 导入富文本编辑器组件及样式
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
// 导入elementUI
import './plugins/element.js'
3.可能遇到的问题
按上述步骤都弄完了,项目编译成功,也能运行,但是页面却不渲染,空白一片,以下是问题描述:
Uncaught TypeError: Cannot redefine property: $router
at Function.defineProperty (<anonymous>)
at Function.install (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:1251)
at Function.e.use (vue:6)
at eval (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:3014)
at Module../node_modules/vue-router/dist/vue-router.esm.js (chunk-vendors.js:4646)
at __webpack_require__ (app.js:854)
at fn (app.js:151)
at eval (webpack-internal:///./src/router/index.js:5)
at Module../src/router/index.js (app.js:1225)
at __webpack_require__ (app.js:854)
webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:8428 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
大意是:无法读取$router
属性,读取vue-router
的配置有问题
问题根源:
页面导入的版本过低,而package.lock.json中的版本高
本质上就是二者的版本不一致,冲突了。
我在改为同版本后,依然有这个问题
解决办法:
-
开发模式下,加引入的
vue-router js
文件注释掉 -
生产环境记得改回来
如果有更好的解决办法请留言,万分感激
三、Element-U组件按需加载
开发的时候按需import
,不要一次性将全量组件都引入
// 按需引入UI组件
import Vue from 'vue'
import {
Button,
Input,
Message,
MessageBox
} from 'element-ui'
Vue.use(Button)
Vue.use(Input)
Vue.prototype.$message = Message
Vue.prototype.$confirm = MessageBox.confirm
注意:
Message
和MessageBox
引入方式比较特殊,以vue prototype
对象形式引入
四、路由懒加载
当打包构建项目时,JavaScript包会变得非常大,影响页面加载。
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
具体需要3步:
1. 安装依赖,是开发依赖
依赖名:@babel/plugin-syntax-dynamic-import
2. 在 babel.config.js配置文件中声明该插件。
'@babel/plugin-syntax-dynamic-import',
3. 将路由改为按需加载的形式,示例代码如下:
// 路由懒加载
const Login = () => import(/* webpackChunkName: "Login_Home_Welcome" */ '../components/Login.vue')
const Home = () => import(/* webpackChunkName: "Login_Home_Welcome" */ '../components/Home.vue')
const Welcome = () => import(/* webpackChunkName: "Login_Home_Welcome" */ '../components/Welcome.vue')
/* webpackChunkName: "Login_Home_Welcome" */
这个类似注释的代码,表示路由组,说明对应的组件会加载到该路由组的js下