在此以前,咱們先談談前端項目的性能優化。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: 對於第三方庫來講,通常就是考慮大小了,若是庫比較笨重最好就提出來了