Vue路由和組件的懶加載

最新版的vue-cli + webpack構建的vue項目在結構上有了一些變化。比如build文件夾下的dev-server.js文件消失了等,當然細心點同學可能會在package.json文件中發(fā)現(xiàn)webpack-bundle-analyzer的身影,它的作用是分析項目打包后的各個資源的體積。
我們運行打包命令就知道它的功能了:

npm run build

結果如下圖(PS:config/index.js文件 => productionSourceMap: false):

打包后各個文件的大小

運行以下命令,即可查看可視化界面:

npm run build --report

如下圖所示:


文件大小的可視化界面

功能很強大,但也直戳痛點,為什么打包后的靜態(tài)文件這么大,有沒有方法優(yōu)化一下打包后的體積呢?答案顯然是有的。
下面進入正題,我總結了幾個優(yōu)化的方法:

1.路由懶加載

配合webpack支持的懶加載方法有:

  • 這種方法比較通用,而且支持性好
resolve => require([./Foo], resolve)
const Foo = () => import('./Foo')

注意:如果使用的是 Babel,需要添加syntax-dynamic-import 插件,才能使 Babel 可以正確地解析語法。

接下來我以官方文檔的寫法為例,演示一波:
原來沒有使用路由懶加載時,你的router/index.js可能是這樣的:

import Vue from 'vue'
import Router from 'vue-router'

import Home from 'pages/home'
...

Vue.use(Router)

export default new Router({
  routes: [
    {
        path: '/',
        name: 'home',
        component: Home
    }
    ...
  ]
})

當時有了路由懶加載,世界變得不同了:

import Vue from 'vue'
import Router from 'vue-router'

// 其它都不用變,就是這么簡單
const Home = () => import('./home')
...

Vue.use(Router)

export default new Router({
  routes: [
    {
        path: '/',
        name: 'home',
        component: Home
    }
    ...
  ]
})

設置路由懶加載后,我們再來看看打包的效果:

路由懶加載后

這時我們會看到,app.js這個文件幾乎減小了一半,但是會多出幾個js文件,那是我們的另外幾個路由頁面的js文件。這些文件會在我們需要的時候,通過異步的方式加載進來,因此它們不會為首屏的加載增加負擔。

2.組件懶加載

既然路由可以懶加載,那么組件可否懶加載呢?
答案當然是可行的。
套路還是一樣,使用:

const Foo = () => import('./Foo')

例如:

// 組件懶加載
const IconList = () => import('components/base/icon-list')

export default {
    components: {
        IconList
    }
}

那么組件懶加載之后,效果如何呢?見下圖:


組件懶加載后

厲害了,app.js文件直接變成了1.83KB,此時又多出了幾個js。
同上,這些js是自定義組件的js,我們可以用異步加載的方式加載進來的。
那么問題來了,難道用了懶加載真的可以為所欲為嗎?就沒有一點缺陷,答案當然是有的。
在實踐中,通過懶加載,會遇到如下問題:

  • 懶加載的元素將會延遲加載,這里的延遲指的是會出現(xiàn)滯后于其他同步元素的出現(xiàn),甚至會出現(xiàn)頁面閃一下的過程
  • 如果一個頁面中有許多嵌套的懶加載組件,那么網(wǎng)頁中的元素會分先后渲染,層次不齊

因此,在平常的vue項目中,建議:

  • 對于路由頁面,最好進行懶加載;
  • 對于路由頁面中的各個組件實行按需進行懶加載。
    如果組件不大并且使用不多,可直接在路由頁面中導入,若組件較大或者使用比較頻繁,建議使用組件懶加載。

3.各類組件庫按需引入(如果有用到的話)

現(xiàn)如今,關于vue的組件庫真是百花齊放,如mint-ui、element-ui、iview以及vux等...但是如果引入完整的組件庫文件,那么打包后的css和js文件將會變得很大。拿mint-ui舉個例子,引入完整的mint-ui和其css樣式,打包后,如下圖:


引入完整的mint-ui

那么,使用按需加載會怎么樣呢?先上代碼:

// main.js
// 按需加載
import { Spinner, Header, InfiniteScroll, Tabbar, TabItem, Lazyload } from 'mint-ui'

Vue.use(Lazyload)
Vue.use(InfiniteScroll)
Vue.component(Header.name, Header)
Vue.component(Spinner.name, Spinner)
Vue.component(Tabbar.name, Tabbar)
Vue.component(TabItem.name, TabItem)

當然,還需要安裝babel-plugin-component,這里省略了對.babelrc的配置,詳情參見mint-ui官方文檔
這樣,我們再來看看打包后的結果:

按需引入mint-ui

根據(jù)上面兩張圖可以看出,vendor.js減少了大約80KB,app.css減少了大約30KB,那么這個vendor.js是干什么的呢?
vendor.js是第三方庫的集成,也就是我們在package.json中"dependencies"對象中的那些庫以及一些必須的第三方庫,現(xiàn)在知道為什么按需引入會減小vendor.js的體積了吧。
這樣看來,如果項目中有引入vue的組件庫,最好還是按需引入為佳。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容