Vue 上线优化方案
#1 为什么要引入外部CDN
最近博客上线,但是在首次加载的时候,需要消耗很多时间,大概在50秒左右,就是说第一页登录页面,就需要用户等待50秒(服务器是最低配置也是一个原因),看了一下network,发现有两个文件加载的时间特别长,一个是vendor.js,一个是app.js,打包的时候,这两个文件也提示文件过大
最终,结合网上的前辈们的解答,首屏加载时间过长重要有以下几点:
- 图片,登录页面(打开网站的第一个页面)静态图片过多也会在首屏中加载出来,消耗时间
- Vue代码里面Router没有使用懒加载
- 使用npm安装第三方库
#2 如何优化?
根据以上三点,具体优化步骤如下 :
#2.1 登录页面(打开网站的第一个页面)图片
主要的处理方式就是减小图片的大小 我这里直接把登录页面的背景图片全部去掉,这样子直接可以省很多时间
#2.2 Router懒加载
webpack默认将所有js源代码打包成一个js文件,导致JS包会变得非常大,影响页面首次加载速度 按需加载能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件的js文件
- 没有优化前的路由:
// 优化前的路由
import Home form "@/views/home/home"
import Listblog form "@/views/listblog/listblog"
import Createblog form "@/views/createblog/createblog"
import Login form "@/views/login/login"
import Test form "@/views/test/test"
export default new VueRouter({
routes: [
{
path: '/',
name: 'Home',
component:Home
redirect:"/dashboard",
children:[
{
path: "/listblog",
component: Listblog,
},
{
path: "/createblog",
component: Createblog
},
]
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/test',
name: 'Test',
component: Test
},
]
})
- 优化后的路由:
// 优化后的路由
export default new VueRouter({
routes: [
{
path: '/',
name: 'Home',
component:(resolve) => require(["@/views/home/home"], resolve)
redirect:"/dashboard",
children:[
{
path: "/listblog",
component: (resolve) => require(["@/views/listblog/listblog"], resolve),
},
{
path: "/createblog",
component: (resolve) => require(["@/views/createblog/createblog"], resolve)
},
]
},
{
path: '/login',
name: 'Login',
component: (resolve) => require(["@/views/login/login"], resolve)
},
{
path: '/test',
name: 'Test',
component: (resolve) => require(["@/views/test/test"], resolve)
},
]
})
优化前和优化后的路由对比,优化后,使用箭头函数,将组件导入,而不是在文件开头,将所有的组件一次全部倒入,一次全部倒入会导致加载时间长,对用户体验不友好
#2.3 引入外部CDN
CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
引入外部CDN,就是说,不需要npm下载对应的库,从而减小vendor.js的体积,但是又不会影响库的正常使用,因为这些库放到CDN上之后,下载速度非常快,而且是并行的下载,下面就说说如何引入外部CDN
我的项目这几个库需要外部引入CDN
代码语言:javascript复制vue
vuex
axios
vue-router
view-design
element-ui
echarts
countup
引入外部CDN大致需要三部:
- 配置文件webpack.base.conf.js
- 去掉原来npm引入库的那些代码
- 在index.html引入CDN链接
- 配置webpack.base.conf.js
bulid/webpack.base.conf.js
代码语言:javascript复制加上 externals
...
module.exports = {
...
module: {
...
},
externals:{
"vue": 'Vue',
"vuex":"Vuex",
"axios":"axios",
"vue-router":"VueRouter",
"view-design":"ViewUI",
'element-ui': 'ELEMENT',
'echarts': 'echarts',
'countup': 'countup',
},
...
}
- 去掉npm引入的那些代码(Vue不能去掉)
src/main.js
代码语言:javascript复制...
import Vue from 'vue' // 这个不变
// import ViewUI from 'view-design'; // 使用CDN后注释掉
// import 'view-design/dist/styles/iview.css'; // 使用CDN后注释掉
// import 'element-ui/lib/theme-chalk/index.css'
// import element from './other_ui/element/index'
// Vue.use(ViewUI);
// Vue.use(element);
store/index.js
代码语言:javascript复制去掉Vuex的npm导入方式
// import Vue from 'vue'
// import Vuex from 'vuex' // 使用CDN后注释掉
// Vue.use(Vuex); // 使用CDN后注释掉
axios/index.js
代码语言:javascript复制去掉axios的npm导入方式
// import axios from 'axios'
router/index.js
代码语言:javascript复制去掉vue-router的npm导入方式
// import Vue from 'vue'
// import VueRouter from 'vue-router'
// Vue.use(VueRouter);
代码语言:javascript复制相应的countup和echarts在使用的时候也不需要import,直接注释掉
// import echarts from 'echarts'
// import countup from 'countup'
- index.html引入CDN
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2"></script>
<script src="https://unpkg.com/vuex@3.1.1"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.12.0/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui@2.12.0/lib/index.js"></script>
<link rel="stylesheet" type="text/css" href="http://unpkg.com/view-design@4.0.0/dist/styles/iview.css">
<script type="text/javascript" src="http://unpkg.com/view-design@4.0.0/dist/iview.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.0.4/echarts.min.js"></script>
<script src="https://cdn.bootcss.com/countup.js/1.8.2/countUp.min.js"></script>
为了避免升级版本的问题,请在引入CDN的时候加上版本号,没有版本号,默认是最新的库,不同的库,不同的CDN,引入版本号的方式不一样,需要具体到对应的网站上查看如何锁定版本
#2.4 启用 Gzip 压缩
vue 默认不启用 Gzip 压缩,但我们知道,压缩后的文件体积会大大减少,这适用于线上部署。 如何启用也很简单: 首先,在 config 中将 build.productionGzip 设置为 true 然后,确认 webpack.prod.conf.js 中有如下代码(默认是有的,没有的手动添加):
代码语言:javascript复制if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\.('
config.build.productionGzipExtensions.join('|')
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
下面只要使用 npm install --save-dev compression-webpack-plugin 安装 webpack 插件
代码语言:javascript复制npm install --save-dev compression-webpack-plugin@1.1.12
这样,你在 build 项目时,webpack 会帮你压缩文件。 如果没有的话,你只要把上面代码复制到 webpack 配置文件的 plugins 下即可。 如何方面查看build之后的文件大小呢?我们可以使用另外一个 webpack 插件:webpack-bundle-analyzer ,如何使用呢?默认 Vue 会导入这个插件,我们只需要调用即可:在 package.json 文件中增加以下命令: “analyzer”: “NODE_ENV=production npm_config_report=true npm run build”,
运行 npm run analyzer ,等待一会,就可以看到整个项目的打包情况了。
nginx配置一句话即可
代码语言:javascript复制nginx.conf文件
http{
...
gzip_static on; #静态压缩
...
}
#3 验证
#3.1 打包
虽然这两个文件的体积已经减少了不少,但是webpack还是提示文件big,还有待优化呀!!!