在此以前,咱们先谈谈前端项目的性能优化。javascript
优化前端项目无非就是2方面的优化:html
1、网络性能优化(重点)前端
2、运行性能优化vue
显而易见的,咱们前端除了一些游戏、WEBGL项目、有大量DOM操做项目以外,运行性能都不至于太差,因此咱们接下来谈论的是webpack对网络性能的优化:java
主要从“请求数量”和“请求资源大小”入手,咱们知道若是没有脚手架,通常咱们本身配置webpack,会把全部内容打包到一个js文件上,这个时候请求数量的确变少了,可是与此同时请求资源的大小也变大了,这就须要咱们来衡量了,何时须要将某些chunk模块移出去呢?node
当咱们用到vue-cli的时候咱们发现,打包完的文件中,js被分红了三个文件(原理就是咱们以前提到过的CommonsChunkPlugin),其中有两个文件是比较大的,一个是app.xxx.js(存放咱们写的代码)另外一个是vendor.xxx.js(存放从node_modules引入的第三方库)jquery
因此如今问题就转移到变成如何优化app和vendor了(咱们讨论的是vue-cli里面webpack打包的优化):webpack
app.xxx.js:web
这里的优化就是所谓的“懒加载(按需加载)”了vue-cli
1. 用 const test = () => import('@/components/test') 代替 import test from '@/components/test'
注意:这个语法糖是须要先安装 babel-plugin-syntax-dynamic-import,
而后配置babel plugins: ["syntax-dynamic-import"] 后才能使用的
分组:在import方法前面加入一个特殊的注释 /*webpackChunkName: "haha233"*/ ,就能够实现分组了
const nav = () => import(/*webpackChunkName: "haha233"*/'../nav/nav') const haha = () => import(/*webpackChunkName: "haha233"*/'../test/test')
2. 用 const test = resolve => require.ensure([],() => resolve(require('@/components/test'))) 代替 const test = require('@/components/test')
require.ensure(dependencies: String[], callback: function, chunkName: String)
这个是webpack官网提供的方法
分组:在ensure方法最后传相同的组名就能够实现分组了
const test = resolve => require.ensure([], () => resolve(require('@/components/test')),'haha233')
const nav = resolve => require.ensure([], () => resolve(require('@/components/nav')),'haha233')
所谓分组就是,build后发现多出来一个js文件(除了正常的app、vendor和manifest),里面会包含同组模块的内容(例如上面的例子就是 nav和test模块的内容)
上面两点都有特殊的语法,1.要先用箭头函数包裹import('~~~'),2.要用带resolve参数的箭头函数包裹require.ensure而后在第二个参数中用resolve来处理require(‘~~~’)
这两种特殊的语法都是把promise包裹一下,变成vueRouter能接受的形式,实行按路由模块分文件
vendor.xxx.js:
vendor是,vue-cli帮咱们配置好的,打包第三方库的文件,当咱们引入大量库的时候,这个vendor文件会变得异常巨大,咱们就须要主要优化这个文件,减少其大小
咱们固然能够用上面两种方法来加载第三方库了,例如JQ
var $ = null import(/* webpackChunkName: "JQ" */'jquery').then(res => { $ = res }, err => { console.log(err) })
可是对于第三方js库咱们通常不这么作,由于上面的方法是异步加载,有些库每每是咱们项目代码的依赖,必须先加载完成不可以使用异步加载,所以咱们来介绍下其余提取的方法:
1.咱们能够用以前提到过的CommonsChunkPlugin
2.固然咱们也能够本身动手,很简单,把库手动引入index.html,文件放在项目目录下的static/js下面,完成~
这样提出来的库要注意配置一下.eslintrc.js , 例如提取了jquery出来,应该加入以下配置
globals: { '$': false }
不配置的话,eslint-loader编译会报错说 ’$‘ is not defined
说到这里咱们又可能会有一个疑问了:咱们该何时把模块分出来呢?这个问题就关系到了衡量请求数量和请求资源大小对性能影响的平衡点了
咱们分开app和vendor来讨论吧
app: 咱们本身写的模块来讲,咱们通常按照路由来分
因此其实上面提到的”懒加载“技巧多用在router.js里面,这样就能够实现到当路由切换到某个组别的时候才去加载这个组的js
vendor: 对于第三方库来讲,通常就是考虑大小了,若是库比较笨重最好就提出来了