大家好,我是猫小白,本文基于vue2
,全文浏览大概须要3分钟。
谈到webpack优化大部分人可能都看腻了,无非就那几招嘛,我之前也是看过许多相似的文章,但都没有本人真正上手过,上面是我用公司的我的项目实在操练下来的,首屏加载速度晋升很大(刷刷的),心愿能帮到你。
废话不多说,先看看比照成绩!
类型 | 优化前 | 优化后 |
---|---|---|
js文件大小 | 24MB | 3MB |
主页首屏显示 | 9s | 1s |
这几乎太夸大了,晋升了8倍?能够设想以前是多慢,要等半天啊。蛮王这个真男人都开大2次了~
能够看到,优化前后首屏加载速度有质的晋升,之前始终想优化咱们我的项目的首屏加载工夫,有缓存还好,没有缓存屏幕白屏都要期待7、8s。特地是有的客户第一次关上这个零碎,那7、8秒犹如过了一个世纪,十分难堪。那么我做了那些惯例操作呢?
1.生产环境敞开productionSourceMap
、css sourceMap
家喻户晓,SourceMap
就是当页面呈现某些谬误,可能定位到具体的某一行代码,SourceMap
就是帮你建设这个映射关系的,不便代码调试。在生产环境中咱们齐全没必要开启这个性能(谁在生产环境调试代码?不会是你吧)
如下配置:
const isProduction = process.env.NODE_ENV === 'production' // 判断是否是生产环境module.exports = { productionSourceMap: !isProduction, //敞开生产环境下的SourceMap映射文件 css: { sourceMap: !isProduction, // css sourceMap 配置 loaderOptions: { ...其它代码 } }, ...其它代码}
此时再npm run build
打包,就会发现速度快了很多,体积霎时只有几兆了!
2.剖析大文件,找出内鬼
装置 npm install webpack-bundle-analyzer -D
插件,打包后会生产一个本地服务,分明的展现打包文件的蕴含关系和大小。
vue.config.js
配置:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports = { ...其它 configureWebpack: [ plugins: [ new BundleAnalyzerPlugin() // 剖析打包大小应用默认配置 ] }, ...其它}
自动弹出一个服务,清晰的展现打包后js的文件大小:
通过图中能够发现:
- element-ui和ant-design占了近1/4的大小:
1.53MB
。 - exceljs也是个大货色有:
1.3MB
- echarts.js文件也靠近
1MB
- moment.js也有
700KB
打包后js文件一共就5MB,这五个哥们就占了4M左右。不剖析好还,一剖析吓得够呛~
不要虚!找到刺了,一个一个来拔掉就好了。置信我拔掉的过程是很爽的。
一个一个解决,拔刺
1.把必须要用的第三方js通过cdn的形式援用
剖析发现,elementui、echarts
是必须应用的,打包又耗时且页面加载也较慢得很。能够通过cdn
间接引入,不便且速度快。
1.element-ui
是咱们我的项目用的次要框架,所以这个必定是少不了,然而我的项目外面ant-design
为什么会存在呢,原来是发现有个页面应用了antd
的进度条组件,因为elementui
的进度条不太好看。然而没想到这样把整个antd
都导进来了。
计划:
- 舍弃
antd
组件,本人去找一个相似的vue
插件或者罗唆本人实现一个。(这个办法短时间无奈实现,且不想去动以前代码,暂不思考) - 应用
antd
局部加载。只加载想要的进度条组件,能够缩小文件体积(这个办法简略粗犷,就是就义一些文件大小)。
咱们应用计划2,依据antd官网的文档配置局部组件的引入。
装置 npm install babel-plugin-import -D
1 main.js
导入须要的组件 Step
import { Steps } from 'ant-design-vue';Vue.component(Steps.name, Steps);Vue.component(Steps.Step.name, Steps.Step);
2 babel.config.js
加上配置:
module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ], //以下是按需加载的配置++++ plugins: [ [ "import", { libraryName: "ant-design-vue", libraryDirectory: "es", style: true } ] ]}
此时再剖析,antd
曾经小了很多。
2.应用cdn加载第三方js。
咱们我的项目外面第三方js
很多,有些打包下来会很大,而且加载速度较慢。咱们把这些js分离出来,通过cdn
的形式在html
中的script
标签中间接应用,一方面缩小打包体积,一方面进步了加载速度。
这里举荐一个收费的cdn
: BootCDN。也能够应用本人购买的付费cdn
服务,咱们到网站搜寻本人我的项目须要的js
。例如:vue
留神,肯定要抉择本人我的项目对应的版本,否则会呈现各种奇怪的问题
我的我的项目应用的是 "vue": "^2.6.12",
(package.json)
第一步:配置vue.config.js
,让webpack
不打包这些js,而是通过script
标签退出。
const isProduction = process.env.NODE_ENV === 'production' // 判断是否是生产环境//正式环境不打包公共jslet externals = {}//贮存cdn的文件let cdn = { css: [ 'https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.0/theme-chalk/index.min.css' // element-ui css 样式表 ], js: []}//正式环境才须要if (isProduction) { externals = { //排除打包的js vue: 'Vue', 'element-ui': 'ELEMENT', echarts: 'echarts', } cdn.js = [ 'https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js', // vuejs 'https://cdn.bootcdn.net/ajax/libs/element-ui/2.6.0/index.js', // element-ui js 'https://cdn.bootcdn.net/ajax/libs/element-ui/2.6.0/locale/zh-CN.min.js', 'https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js', ]}module.exports = {//...其它配置configureWebpack: { //罕用的公共js 排除掉,不打包 而是在index增加cdn, externals, //...其它配置 },chainWebpack: config => { //...其它配置 // 注入cdn变量 (打包时会执行) config.plugin('html').tap(args => { args[0].cdn = cdn // 配置cdn给插件 return args }) }//...其它配置 }
第二步:html模板中退出定义好的cdn变量应用的代码
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>web</title> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <!-- 引入款式 --> <% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%=css%>" > <% } %> <!-- 引入JS --> <% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <script src="<%=js%>"></script> <% } %></head><body style="font-size:14px"> <div id="app"></div></body></html>
能够发现cdn.js
中,我把vue、echarts、element-ui
这三个大头退出了。在externals
对象中左侧是npm
包的名称,右侧是在代码中裸露的全局变量。留神element-ui
对应的是 ELEMENT
。
没有ant-design-vue
是因为咱们下面应用了局部加载的形式,如果应用cdn
这种形式是加载全副的代码,有点节约。
没有应用exclejs
,是因为exceljs
在我的业务代码中不是间接援用的,而是一个叫table2excel
间接依赖的。所以就算我通过下面的办法排除掉它,在打包的时候还是会通过table2excel
的依赖找到它并打包。
那这种不可避免的状况,该如何优化,让加载速度不受影响呢?
答案是通过懒加载的形式:
1.script标签中正文掉 import Table2Excel from "table2excel.js";2.下载的办法中:download(){ //应用import().then()形式 import("table2excel.js").then((Table2Excel) => { new Table2Excel.default("#table").export('filename') //多了一层default })}
这样在进入零碎时,不会加载Table2Excel
和exceljs
,当须要时才会去加载,第一次会慢一点,前面就不须要加载了,会变快。
3 moment.js的优化
咱们发现monentjs
在我的项目中有应用来对工夫格式化,然而应用频率并不高,齐全能够本人实现一个format
办法,或者应用只有6kb
的day.js
.
但这里咱们暂不替换,把moment
变得瘦小一些即可,删除掉除中文以外的语言包。
第一步:vue.config.js
...其它配置 chainWebpack: config => { config.plugin('ignore') //疏忽/moment/locale下的所有文件 .use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)) }...其它配置
第二步:main.js
import moment from 'moment'//手动引入所须要的语言包import 'moment/locale/zh-cn';// 指定应用的语言moment.locale('zh-cn');
这次咱们看看moment
打包后多大:
只有174kb
了。不过,有一说一还是day.js
香~
做完下面这些动作咱们的js文件总大小:3.04MB
,其中蕴含 1.3MB
的懒加载js,剩下的1.7MB
左右的js基本上不会对页面造成很大的卡顿。
还有提高空间?
1.通过 compression-webpack-plugin
插件把代码压缩为gzip。然而!须要服务器反对
webpack
端 vue.config.js
配置如下:
//打包压缩动态文件插件const CompressionPlugin = require("compression-webpack-plugin")//...其它配置module.exports = { //...其它配置 chainWebpack: config => { //生产环境开启js\css压缩 if (isProduction) { config.plugin('compressionPlugin').use(new CompressionPlugin({ test: /\.(js)$/, // 匹配文件名 threshold: 10240, // 对超过10k的数据压缩 minRatio: 0.8, deleteOriginalAssets: true // 删除源文件 })) } } //...其它配置}
打包大小由3MB
到860KB
,感觉腾飞了~
服务器端配置这里就不具体阐明了能够谷百: nginx开启动态压缩 找到答案。
最初贴上优化前后的无缓存下的首屏加载工夫比照(chrome浏览器),相对包真:
优化前我的项目网站首屏加载数据:9.17s
优化后我的项目网站首屏加载数据:1.24s
这些都是在工作之余,本人抽时间去查阅各位大佬的帖子,尽管都是些耍栏了的技术,然而真的要在本人我的项目中施行还是须要一些工夫和精力,大多数都是为了实现性能疾速迭代而疏忽掉了做程序本来的目标,就是要让用户有一个良好的应用体验。
肯请各位大佬,不要忘了给我点赞
、评论
、珍藏
。
往期精彩:
1.什么是迭代器(iterator)?Generator和它有什么关联
2.微信小程序UI组件、图表、自定义bar这些坑都帮你踩了