譯:Code Splitting with Vue.js And Webpack

  用webpack來打包你的單頁應用的一個可能的缺點是你可能會獲得一個很是大的打包文件,有時甚至會有幾兆大小。html

Asset Size
bundle.main.js 1.36MB

  隨之帶來的問題是用戶在屏幕上看到任何東西以前,必需要下載整個文件並運行它。若是用戶使用的是網絡鏈接很差的設備,這個過程可能須要很長時間。
  Code splitting 就是把打包文件分割成爲更小的文件,容許用戶在他們須要的時候下載須要的代碼塊的一個方法。
  例如,看看這個簡單的界面,咱們能夠識別出這個App中不須要初始載入的部分。vue

image

  若是咱們延遲加載這些代碼段直到初始渲染結束會怎樣?它可讓用戶更快的看到界面並進行交互。
  在這篇文章,我將向你展現如何使用 Vue.jsWebpack將單頁應用拆分紅能夠動態加載的更理想的大小。

異步組件

  Code splitting 的關鍵就是異步組件(async components),這個組件的定義就是異步加載(包括它的模板,數據,方法等等)。
  首先讓咱們用component APIVue.component(name, definition) 聲明一個組件。不一樣於將定義對象做爲第二個參數,異步組件有一個函數,這個函數有兩個顯著的特色:webpack

  • 它執行 Promise,擁有一個 resolve 參數
  • 它是一個工廠函數,也就是說它返回一個對象(在本例中是組件定義)
Vue.component('async-component', (resolve) => {
  resolve({
    template: '<div>Async Component</div>',
    props: [ 'myprop' ]
  });
});
複製代碼

異步組件是 Code splitting 的第一步,由於咱們如今纔有了一個抽象的機制。web

動態模塊加載

  咱們還須要 webpack 的幫助,假設咱們將組件定義抽象爲ES6模塊文件:bash

AsyncComponent.js網絡

export default {
  template: '<div>Async Component</div>',
  props: [ 'myprop' ]
}
複製代碼

  咱們怎麼讓Vue.js加載它呢?你可能會想試試這樣的方法:架構

import AsyncComponent from './AsyncComponent.js'`;
Vue.component('async-component', AsyncComponent);
複製代碼

  可是這是靜態的而且在編譯時解析,若是咱們想要得到Code splitting 的好處,咱們須要的是在運行的應用中動態地加載。app

import()

  目前,用JavaScript來動態的加載模塊是不可能的。可是,ECMAScript有一個動態模塊加載函數叫作 import() 。   Webpack已經有了一個import()的實現,並將其做爲一個代碼分割點,在建立包時,將所請求的模塊放入一個單獨的文件中(一個單獨的chunk,實際上,如今把它看做單獨的一個文件)。
  import() 將文件名做爲一個參數並返回一個Promise。下面是咱們如何加載上面的模塊:異步

import(/* webpackChunkName: "async-component" */ './AsyncComponent.js')
  .then((AsyncComponent) => {
    console.log(AsyncComponent.default.template);
    // Output: <div>Async Component</div>
  });
複製代碼

注:若是你使用Babel,你須要添加 syntax-dynamic-import 插件***以便Babel能夠正確的解析。***async

如今,但你構建項目的時候,你會注意到這些模塊出如今它本身的文件中了:

Asset Chuck Name
bundle.main.js main
bundle.0.js async-component

你能夠給動態導入的模塊加一個名字,讓它更容易識別;只需在文件名前面添加一個註釋,就像我在上面的例子中所作的那樣。

動態組件加載

  由於 import() 返回一個Promise,咱們能夠將它和 Vue 的異步組件功能結合使用。Webpack將單獨打包異步組件,並經過AJAX將其動態加載到應用程序中。

main.js

import Vue from 'vue';

Vue.component('async-component', (resolve) => {
  import('./AsyncComponent.js')
    .then((AsyncComponent) => {
      resolve(AsyncComponent.default);
    });
});

new Vue({ 
  el: '#app' 
});
複製代碼

index.html

<div id="app">
  <p>This part is included in the page load</p>
  <async-component></async-component>
</div>
<script src="bundle.main.js"></script>
複製代碼

頁面初始加載時:

<div id="app">
  <p>This part is included in the page load</p>
</div>
複製代碼

當main.js運行的時候,它將啓動異步組件模塊的請求(這是自動實現的,由於 webpackimport() 包含了AJAX加載模塊的代碼)。
若是Ajax成功返回模塊,Promise 完成而且渲染組件,頁面將會被渲染成這樣:

<div id="app">
  <p>This part is included in the page load</p>
  <div>Async Component</div>
</div>
複製代碼

下圖能夠更好地幫助你理解:

image

single file component

  Vue 實現 Code Splitting 的特殊方式就是使用 single file component。下面是使用single file component的代碼重構:

AsyncComponent.vue

<template>
  <div>Async Component</div>
</template>
<script>
  export default {
    props: [ 'myprop' ]
  }
</script>
複製代碼

導入的語法也更加簡潔

new Vue({ 
  el: '#app',
  components: {
    AsyncComponent: () => import('./AsyncComponent.vue')
  }
});
複製代碼

Code Splitting 架構

  這是無關技術的部分,問題就是咱們怎麼爲一個app構建一個code splitting ?
  最直接的方法就是按照界面來,好比,你的app上有兩個界面,一個home,一個about。這兩個界面是由兩個組件(home.vue about.vue)構成,那麼這兩個組件就能夠是拆分的點。
  另外,你也能夠對任何有條件的組件(選項卡、彈窗、下拉菜單等等)或者是footer進行拆分。

原文地址:Code Splitting with Vue.js And Webpack
譯者:Damer Wang

相關文章
相關標籤/搜索