导致首屏加载时间长主要因为打包后的 vendor.js
文件过大,或者在首屏加载过多的异步请求,本文主要是记录一下怎么减小打包体积,从而缩短下载 js 文件的时间。
可以看到最大的还是 vendor.js 文件,还有就是多了写 map 文件,这些 sourceMap 的作用主要是用于代码错误提示。通常,js代码出错,控制台会提示第几行第几列代码出错。但是webpack
打包压缩后的代码,都被压缩到了一行,变量也变成了a,b,c,d。代码出错,控制台就没法正确的提示错误位置。
sourceMap
就是用来解决这个问题的。sourceMap
就是一个信息文件,里面储存着打包前的位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。更多关于 sourceMap,可以看下阮一峰的文章。
一般在生产环境我们可以不生成 sourceMap ,修改 webpack 的 productionSourceMap 属性为 false
可关闭该功能。config/index.js文件中设置
productionSourceMap为
false
第一步:修改config/index.js
文件下 productionGzip:true ;
第二步:安装依赖: npm install --save-dev compression-webpack-plugin
也许你会遇到报错,一般都是 compression-webpack-plugin 版本问题,降低版本即可
可以看到多出了 .gz
文件,这怎么还多出文件了呢,对比一下 js 压缩后只有 650kb
了,比 vendor.js
的 2.05MB
是不是小了很多呢,当我们在服务器的 Nginx 配置中开启 gzip 模式后他就会直接访问 gz 文件而不是未压缩的 vendor.js
。
开启 nginx gzip 只需在 nginx.conf 配置文件中做如下配置:
http:{
#启用或禁用gzipping响应。#
gzip on;
#设置用于压缩响应的缓冲区number和size。默认情况下,缓冲区大小等于一个内存页面。这是4K或8K,具体取决于平台。#
gzip_static on;
#启用或禁用gzipping响应。#
gzip_buffers 4 16k;
#设置level响应的gzip压缩。可接受的值范围为1到9。#
gzip_comp_level 5;
#设置将被gzip压缩的响应的最小长度。长度仅由“Content-Length”响应头字段确定。#
gzip_min_length 100;
#匹配MIME类型进行压缩,text/html默认被压缩。#
gzip_types text/plain application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
}
可以在 terminal 输入一下命令检验:
curl -I -H"Accept-Encoding: gzip, deflate" "https://www.sixtyden.com" // 改成你的域名或者服务器ip
如果有: Content-Encoding: gzip
则已成功开启
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
// 以下两行配置,关闭 debug 和 console
drop_debugger:true,
drop_console:true
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。
new Vue({
components: {
'my-component': () => import('./my-async-component')
}
})
优化后扔服务器后加载速度确实快了不少,但是路由之间切换的时候会有短暂的「花屏」就是有个过渡啥也没有,这里得优化一个loading 出来,下面再把依赖包全部换成 cdn ,进一步缩小首屏需要下载的 js 文件大小。
有个问题,如果有某个 cdn 加载很慢的话,还是会卡主的,所以用cdn之前看看有没有国内比较快的。
先在 index.html
里加上 cdn,查找开源库的 cdn 可以去 这里
<link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.min.css" rel="stylesheet">
<link href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.6.0/styles/atom-one-dark.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.5.1/vuex.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/javascript.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/bash.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/xml.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/css.min.js"></script>
<script src="https://cdn.bootcss.com/highlight.js/9.12.0/languages/markdown.min.js"></script>
然后修改build/webpack.base.conf.js文件,externals外部扩展,通过这种方式引入依赖库,不需要webpack处理。
module.exports = {
...
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'highlight.js': 'highlight.js'
}
...
}
加了这些 CDN 后打包效果如下:
vendor 小了不少,但是还是感觉太大,我们用 webpack-bundle-analyzer
查看一下具体问题,
yarn add webpack-bundle-analyzer -D
然后在 package.json
中 scripts 中加入
analyz": "NODE_ENV=production npm_config_report=true npm run build
得到如下结果:
可以看到主要是 lodash 和 mavon-editor 太大,我们想办法优化一下。
关于 lodash
我们直接使用 lodash-es
来代替,并以以下方式按需引用:
import isArray from 'lodash-es/isArray'
效果如下:
然后直接去掉 mavon-editor
用 markd
来代替
效果还可以,先暂时优化到这了。