当您的网站/应用程序很小时,您可以将所有布局/页面/组件加载到初始包中,并在启动时提供所有内容。 但是,当您的代码变得复杂时,有大量的布局/页面/组件,这样做并不是最理想的,因为它会影响加载时间。 幸运的是,有一种方法可以解决这个问题。
我们将介绍如何延迟加载/编码拆分应用程序的部分,以便仅在需要时自动请求它们。 这是通过动态导入完成的。 让我们从一个例子开始,然后转换它,以便我们使用延迟加载 - 我们将聚焦这个加载一个页面的例子,但同样的原则可以应用于加载任何东西(资源、JSONs、…):
延迟加载路由页面
使用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
创建一个单独的块,只有在需要时才加载。 在这个例子中,指当用户访问’/same-page’的路由的时候。
延迟加载组件
通常,您将导入一个组件,然后将其注册到页面、布局或组件。
<script>
import SomeComponent from 'components/SomeComponent'
export default {
components: {
SomeComponent,
}
}
</script>
现在让我们改变这种方式,使用动态导入使组件按需加载:
<script>
export default {
components: {
SomeComponent: () => import('components/SomeComponent'),
}
}
</script>
延迟加载即时生效
正如你在上面注意到的那样,我们使用动态导入(import('.. resource ..')
)而不是常规导入(import resource from './path/to/resource'
)。 动态导入基本上返回一个您可以使用的Promise:
import('./categories.json')
.then(categories => {
// 嘿, 我们已经延迟加载了这个文件
// 并且我们有了"categories"中的内容
})
.catch(() => {
// 哦, 哪里出错了...
// 不能加载资源
})
使用动态导入而不是常规导入的一个优点是导入路径可以在运行时确定:
import('pages/' + pageName + '/' + 'id')
注意动态导入
在前面的例子中使用可变部分的动态导入时有一点需要注意。 当网站/应用程序被打包,在编译时我们无法知道运行时确切的导入路径。 因此,将为每个可以匹配变量路径的文件创建块。 您可能会在构建日志中看到不必要的文件。
那么我们如何限制在这种情况下创建的块的数量呢? 方法是尽可能地限制可变部分,因此匹配的路径尽可能少。 1.添加文件扩展名,即使它没有扩展名也能用。 这将仅为该文件类型创建块。 当该文件夹包含许多文件类型时很有用。
// 糟糕
import('./folder/' + pageName)
// 这样更好
import('./folder/' + pageName + '.vue')
2.尝试创建一个文件夹结构,以限制可变路径中的文件。 尽可能具体说明:
// 糟糕 -- 为在./folder中的所有JSON创建块 (递归查询)
const asset = 'my/jsons/categories.json'
import('./folder/' + asset)
// 很好 --仅为在./folder/my/jsons中的JSON创建块
const asset = 'categories.json'
import('./folder/my/jsons/' + asset)
3.尝试从仅包含文件的文件夹导入。 以前面的例子为例,假设./folder/my/jsons还包含子文件夹。 我们通过指定更具体的路径来使动态导入更好,但在这种情况下它仍然不是最优的。 最好是使用仅包含文件的终端文件夹,因此我们限制匹配路径的数量。
- 使用Webpack魔术注释的
webpackInclude
和webpackExclude
通过正则表达式约束捆绑的块,例如:
await import(
/* webpackInclude: /(ar|en-us|ro)\.js$/ */
'quasar/lang/' + langIso
)
.then(lang => {
Quasar.lang.set(lang.default)
})
将导致仅捆绑您网站/应用程序所需的语言包,而不是捆绑所有语言包(超过40种!),这可能会妨碍quasar dev
和quasar build
.命令的性能。
请记住,匹配路径的数量等于正在生成的组块的数量。