當您的網站/應用程式很小時,您可以將所有版面配置/頁面/元件載入到初始套件中,並在啟動時提供所有內容。但是,當您的程式碼變得複雜且具有許多版面配置/頁面/元件時,這樣做將不是最佳選擇,因為它會嚴重影響載入時間。幸運的是,有一種方法可以解決這個問題。
我們將介紹如何延遲載入/程式碼分割應用程式的各個部分,以便它們僅在需要時自動請求。這是透過動態匯入完成的。讓我們從一個範例開始,然後轉換它,以便我們使用延遲載入 – 我們將把這個範例重點放在載入頁面上,但相同的原理可以應用於載入任何東西(資源、JSON 等)。
延遲載入路由頁面
正常情況下,使用 Vue Router 時會像下面這樣呼叫靜態元件。
警告
Quasar 文件假設您已經熟悉 Vue Router。下面僅描述如何在 Quasar CLI 專案中使用它的基本知識。如需完整的功能列表,請造訪 Vue Router 文件。
import SomePage from 'pages/SomePage'
const routes = [
{
path: '/some-page',
component: SomePage
}
]
現在讓我們變更它,使頁面僅在使用動態匯入時才按需載入
const routes = [
{
path: '/some-page',
component: () => import('pages/SomePage')
}
]
很簡單,對吧?這樣做的目的是為 /src/pages/SomePage.vue
建立一個單獨的區塊,然後僅在需要時才載入。在這種情況下,當使用者造訪 '/some-page' 路由時。
延遲載入元件
通常,您會匯入一個元件,然後將其註冊到頁面、版面配置或元件。
<script>
import SomeComponent from 'components/SomeComponent'
export default {
components: {
SomeComponent,
}
}
</script>
現在讓我們變更它,使元件僅在使用動態匯入時才按需載入
<script>
import { defineAsyncComponent } from 'vue'
export default {
components: {
SomeComponent: defineAsyncComponent(() => import('components/SomeComponent')),
}
}
</script>
動態延遲載入
如您在上面注意到的,我們正在使用動態匯入 (import('..resource..')
) 而不是常規匯入 (import Resource from './path/to/resource'
)。動態匯入本質上是傳回您可以使用的 Promise
import('./categories.json')
.then(categories => {
// hey, we have lazy loaded the file
// and we have its content in "categories"
})
.catch(() => {
// oops, something went wrong...
// couldn't load the resource
})
使用動態匯入而不是常規匯入的一個優點是,匯入路徑可以在執行階段確定
import('pages/' + pageName + '/' + id)
供應商匯入的注意事項
預設情況下,即使您的程式碼動態匯入 node_modules
中的套件,Quasar 也會將它們包含在供應商區塊中。這會增加供應商區塊的大小,但由於您通常不會變更您的依賴項,因此瀏覽器將使用此區塊的快取版本,並在後續造訪時實際加快應用程式的載入速度。
例如,如果您已安裝一個套件(我們稱之為 my-package
),您可以像這樣動態匯入它
import('my-package')
.then(myPackage => {
// use the package
})
但是,如果您希望 Quasar CLI 將 my-package
放入其自己的區塊中,您必須編輯 /quasar.config
檔案
return {
vendor: {
remove: [ 'my-package' ]
}
}
如需更多詳細資訊,請參閱 /quasar.config
檔案的 vendors 區段。
動態匯入的注意事項
當將動態匯入與可變部分一起使用時,例如在先前的範例中,有一個注意事項。當網站/應用程式被捆綁時(即在編譯時),我們無法判斷執行階段的確切匯入路徑是什麼。因此,將為每個可能符合可變路徑的檔案建立區塊。您可能會在建置記錄中看到不必要的文件。
那麼,我們如何限制在這種情況下建立的區塊數量呢?想法是盡可能限制可變部分,以便符合的路徑盡可能少。
- 新增檔案副檔名,即使沒有副檔名也可以運作。這將僅為該檔案類型建立區塊。當該資料夾包含許多檔案類型時很有用。
// bad
import('./folder/' + pageName)
// much better
import('./folder/' + pageName + '.vue')
- 嘗試建立一個資料夾結構,以限制該可變路徑中可用的檔案。使其盡可能具體
// bad -- makes chunks for any JSON inside ./folder (recursive search)
const asset = 'my/jsons/categories.json'
import('./folder/' + asset)
// good -- makes chunks only for JSONs inside ./folder/my/jsons
const asset = 'categories.json'
import('./folder/my/jsons/' + asset)
嘗試從僅包含檔案的資料夾中匯入。以先前的範例為例,想像一下 ./folder/my/jsons 進一步包含子資料夾。我們透過指定更具體的路徑使動態匯入變得更好,但在這種情況下仍然不是最佳選擇。最好使用僅包含檔案的終端資料夾,以便我們限制符合路徑的數量。
使用 Webpack magic comments
webpackInclude
和webpackExclude
,使用正規表示式約束捆綁的區塊,例如
await import(
/* webpackInclude: /(ar|en-US|ro)\.js$/ */
'quasar/lang/' + langIso
)
.then(lang => {
Lang.set(lang.default)
})
將導致僅捆綁您的網站/應用程式所需的語言包,而不是捆綁所有語言包(超過 40 個!),這可能會阻礙命令 quasar dev
和 quasar build
的效能。
請記住,符合路徑的數量等於產生的區塊數量。