vue異步組件 懶加載& webpack按需加載——性能優(yōu)化

利用webpack對代碼進(jìn)行分割是懶加載的前提醉顽,懶加載就是異步調(diào)用組件,需要時(shí)候才下載(按需加載)平挑。

為什么需要懶加載?
在單頁應(yīng)用中游添,如果沒有應(yīng)用懶加載,運(yùn)用webpack打包后的文件將會(huì)異常的大通熄,造成進(jìn)入首頁時(shí)唆涝,需要加載的內(nèi)容過多,延時(shí)過長棠隐,不利于用戶體驗(yàn)石抡,而運(yùn)用懶加載則可以將頁面進(jìn)行劃分,需要的時(shí)候加載頁面助泽,可以有效的分擔(dān)首頁所承擔(dān)的加載壓力,減少首頁加載用時(shí)嚎京。

vue開發(fā)過程中嗡贺,我們會(huì)做出特別多特別多的組件,包括login,header,footer,main等等鞍帝。
這樣使整個(gè)網(wǎng)站看起來就十分的龐大诫睬,當(dāng)我們在打開網(wǎng)頁的時(shí)候,突然一下子把這些所有的組件加載上來帕涌,這么多的請求全部同時(shí)開始請求摄凡,勢必會(huì)造成網(wǎng)頁打開很慢,使客戶得到的是非常差勁的體驗(yàn)蚓曼。

因此亲澡,vue為我們專門設(shè)立了異步組件,通過異步組件纫版,我們可以得到兩點(diǎn)好處:
1床绪、 用不到的組件不會(huì)加載,因此網(wǎng)頁打開速度會(huì)很快,當(dāng)你用到這個(gè)組件的時(shí)候癞己,才會(huì)通過異步請求進(jìn)行加載膀斋;
2、 緩存組件痹雅,通過異步加載的組件會(huì)緩存起來仰担,當(dāng)你下一次再用到這個(gè)組件時(shí),絲毫不會(huì)有任何的疑遲绩社,組件很快會(huì)從緩存中加載出來惰匙。

異步組件=原理同webpack的按需加載
好處:
1)按需加載,可以節(jié)省首次加載時(shí)間铃将,提高速度项鬼,性能優(yōu)化
2)第一次加載完成會(huì)緩存

異步組件的描述:

Vue允許將組件定義為一個(gè)異步解析(加載)組件定義的工廠函數(shù),即Vue只在實(shí)際需要渲染組件時(shí)劲阎,才會(huì)觸發(fā)調(diào)用工廠函數(shù)绘盟,并且將結(jié)果緩存起來,用于將來再次渲染悯仙。

A湔薄!锡垄!ps:要使用異步組件沦零,一個(gè)比較推薦的方式就是配合webpack代碼分離功能。

例子:(全局|局部)
法一:結(jié)合webpack

//1)全局:
 Vue.component('component-name',function(resolve){
 //require 語法告訴 webpack自動(dòng)將編譯后的代碼分割成不同的塊
 //這些塊將通過 Ajax 請求自動(dòng)下載
   require(['./my-async-componnet'],resolve)
 })
 //注冊全局組件名货岭,但只有一個(gè)名字路操,沒有實(shí)體,相當(dāng)于空的
//當(dāng)需要這個(gè)組件時(shí)千贯,調(diào)用上面的工廠函數(shù)屯仗,觸發(fā)webpack的異步加載模塊方法
//然后異步請求一個(gè)模塊,請求成功后搔谴,這個(gè)模塊內(nèi)容即為組件實(shí)體部分魁袜,并對應(yīng)地方渲染,加載內(nèi)容也緩存下來敦第。

//2)局部
 new Vue({
   components: {
        'component-name':function(resolve) {
           require(['./my-component'], resolve)
        }
   }
 })

法二:通過webpack2+es2015返回一個(gè)promise

//1)全局:
Vue.component('component-name',
 ()=> import('./my-async-componnet')
 )
//2) 局部:
 new Vue({
   components: {
       'component-name': () =>  import('./my-async-componnet')
   }
 })

高級異步組件(即處理加載狀態(tài))
工廠對象可以返回一個(gè)對象峰弹,對象里面的一些配置參數(shù)

    const asyncComponent = () => ({
    // 需要加載的組件 (應(yīng)該是一個(gè) `Promise` 對象)
    component: import('./my-async-componnet'),
    //異步加載時(shí)使用的組件(加載中的效果)
    loading: loadingComponent,
    //加載失敗時(shí)使用的組件
    error: ErrorComponent,
    //展示加載中組件的延時(shí)時(shí)間,默認(rèn)200毫秒
    delay: 200,
    //超時(shí)時(shí)間芜果,超過該時(shí)間顯示加載失敗的組件
    timeout: 3000
    })

單文件組件+vue-router案例:
2個(gè)組件:first鞠呈、second代表2個(gè)頁面, 路由文件異步組件方式:

     //傳統(tǒng)寫法:import First from '@/components/First'
    方法一:
            const first = () => import("../components/first.vue")
            const second = () => import("../components/second.vue")
    方法二:
            const first = resolve => require.ensure([], () => resolve( require(../components/first.vue)),  'chunkname1')
            const second = resolve => require.ensure([], () => resolve( require(../components/second.vue)),  'chunkname2')
      //其余配置如以往一樣
      const routes = [
          {
              path: '/',
              component: first
           },
            {
              path: '/',
              component: second
           }
      ]

webpack中利用require.ensure()實(shí)現(xiàn)按需加載

require.ensure()(webpack異步加載|代碼分割)

  • 解釋1:把js模塊獨(dú)立導(dǎo)出一個(gè)個(gè)js文件,然后使用這個(gè)模塊時(shí)师幕,webpack會(huì)構(gòu)造這個(gè)script dom元素粟按,加入到document.head中诬滩,由瀏覽器自動(dòng)發(fā)起異步請求這個(gè)js文件,再寫個(gè)回調(diào)灭将,去定義得到這個(gè)js文件后的業(yè)務(wù)邏輯疼鸟。
  • 解釋2:webpack 在編譯時(shí),會(huì)靜態(tài)地解析代碼中的 require.ensure()庙曙,同時(shí)將模塊添加到一個(gè)分開的 chunk 當(dāng)中空镜。這個(gè)新的 chunk 會(huì)被 webpack 通過 jsonp 來按需加載。

require.ensure這個(gè)函數(shù)是一個(gè)代碼分離的分割線捌朴,表示 回調(diào)里面的require
是我們想要進(jìn)行分割出去的吴攒,即require(’./baidumap.js’),把baidumap.js分割出去砂蔽,形成一個(gè)webpack打包的單獨(dú)js文件洼怔。當(dāng)然ensure里面也是可以寫一些同步的require的,如:

    var sync = require('syncdemo.js')   //下面ensure里面也用到
    btn.click(function() {
        require.ensure([], function() {
              var map = require('./map.js') //map.js放在我們當(dāng)前目錄下
              //這個(gè)不會(huì)獨(dú)立出去左驾,因?yàn)樗呀?jīng)加載到模塊緩存中了
               var sync = require('syncdemo.js')  
    })
  })

===》ensure會(huì)把沒有使用過的require資源進(jìn)行獨(dú)立分成成一個(gè)js文件

ensure語法及參數(shù)解釋

require.ensure(dependencies: string[], callback: function(require),chunkName:string)

  • 第一個(gè)參數(shù):默認(rèn)[],放置當(dāng)前這個(gè)模塊所依賴的其他模塊镣隶。比如:假設(shè)A 和 B都是異步的,B中需要A诡右,則B下載之前安岂,先要下載A :require.ensure([‘A.js’], function...),!!!!需要注意:webpack會(huì)把參數(shù)里面的依賴異步模塊和當(dāng)前的需要分離出去的異步模塊給一起打包成同一個(gè)js文件,這里可能會(huì)出現(xiàn)一個(gè)重復(fù)打包的問題帆吻, 假設(shè)A 和 B都是異步的域那, ensure A 中依賴B,ensure B中 依賴A猜煮,那么會(huì)生成兩個(gè)文件次员,都包含A和B模塊。
  • 第二個(gè)參數(shù):當(dāng)所有依賴都加載完成后友瘤,webpack會(huì)執(zhí)行這個(gè)回調(diào)函數(shù)翠肘。require對象的一個(gè)實(shí)現(xiàn)會(huì)作為一個(gè)參數(shù)傳遞給這個(gè)回調(diào)函數(shù)。因此辫秧,我們可以進(jìn)一步require()依賴和其他模塊提供下一步的執(zhí)行。
  • 第三個(gè)參數(shù)被丧,chunkname打包后代碼塊的名字:chunk提供給這個(gè)特定的require.ensure()的chunk的名稱盟戏。通過提供 require.ensure() 不同執(zhí)行點(diǎn)相同的名稱,我們可以保證所有的依賴都會(huì)一起放進(jìn)相同的 文件束(bundle)甥桂。

使用 vue-cli構(gòu)建的項(xiàng)目,在 默認(rèn)情況下 ,執(zhí)行 npm run build 會(huì)將所有的js代碼打包為一個(gè)整體柿究。如果想要讓build之后的代碼更便于識(shí)別,可配置webpack代碼黄选,單獨(dú)打包自己定義的名字(需要配置chunkFileName和publicPath)

  module.exports = {
        entry:  './src/main.js',
        output: {
              path: path.resolve(__dirname, './dist'),
              publicPath: '/dist/', //是按需加載單獨(dú)打包出來的chunk是以publicPath為基準(zhǔn)來存放的
              filename: 'build.js',
              chunkFilename: 'js/[name]-[chunkhash:8].js' //最終生成的路徑和名字
          }
    }
打包結(jié)果.png
目錄結(jié)果.png

參考地址:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝇摸,一起剝皮案震驚了整個(gè)濱河市婶肩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌貌夕,老刑警劉巖律歼,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啡专,居然都是意外死亡险毁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門们童,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畔况,“玉大人,你說我怎么就攤上這事慧库□喂颍” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵齐板,是天一觀的道長吵瞻。 經(jīng)常有香客問我,道長覆积,這世上最難降的妖魔是什么听皿? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮宽档,結(jié)果婚禮上尉姨,老公的妹妹穿的比我還像新娘。我一直安慰自己吗冤,他們只是感情好又厉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著椎瘟,像睡著了一般覆致。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肺蔚,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天煌妈,我揣著相機(jī)與錄音,去河邊找鬼宣羊。 笑死璧诵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仇冯。 我是一名探鬼主播之宿,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苛坚!你這毒婦竟也來了比被?” 一聲冷哼從身側(cè)響起色难,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎等缀,沒想到半個(gè)月后枷莉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡项滑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年依沮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枪狂。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡危喉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出州疾,到底是詐尸還是另有隱情辜限,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布严蓖,位于F島的核電站薄嫡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颗胡。R本人自食惡果不足惜毫深,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望毒姨。 院中可真熱鬧哑蔫,春花似錦、人聲如沸弧呐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俘枫。三九已至腥沽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸠蚪,已是汗流浹背今阳。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茅信,地道東北人酣栈。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像汹押,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子起便,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345