Vue.js中的延迟加载和代码拆分

这是我们的*Vue.js Performance系列中的第1部分。

虽然移动优先方法成为标准且不确定的网络条件是我们应该始终考虑的事情,但是保持应用程序快速加载变得越来越困难。在本系列中,我将深入研究我们在Vue Storefront中使用的Vue性能优化技术,并且您可以在Vue.js应用程序中使用它们使它们立即加载并顺利执行。我的目标是让这个系列成为关于Vue应用程序性能的完整而完整的指南。

Webpack bundling如何工作?

本系列中的大多数技巧都将集中在使我们的JS包。要了解它,首先我们需要了解Webpack如何捆绑所有文件。

捆绑我们的资源时,Webpack正在创建一个称为依赖图的东西(点击这里查看它的样子)。它是一个基于导入链接所有文件的图表。假设我们main.js在webpack配置中有一个被指定为入口点的文件,它将成为我们依赖图的根。现在,我们将在此文件中导入的每个js模块将成为图中的节点,并且在这些节点中导入的每个模块都将成为其节点。

Webpack使用此依赖关系图来检测它应该包含在输出包中的文件。输出包只是一个(或我们将在后面的部分中看到的多个)javascript文件,其中包含依赖图中的所有模块。

该捆绑包本质上是我们整个应用程序的JavaScript。

我们可以用下图来说明这个过程:

Vue.js中的延迟加载和代码拆分_第1张图片

现在我们知道捆绑是如何工作的,很明显我们的项目越大,初始JavaScript包就越大。

更大的捆绑包,下载和解析我们的用户所需的时间越长。用户必须等待的时间越长,他离开我们网站的可能性就越大。事实上,根据谷歌的数据,53%的移动用户留下的页面加载时间超过3秒。

总而言之,更大的捆绑=更少的用户,这可以直接转化为潜在收入的损失。Bing就是一个很好的例子 - 延迟2秒导致每位访客的收入损失4.3%

延迟加载

那么当我们仍然需要添加新功能并改进我们的应用程序时,我们如何切断捆绑包大小?答案很简单 -  延迟加载和代码分割。

顾名思义,延迟加载是延迟加载应用程序的部件(块)的过程。换句话说,只有在我们真正需要的时候才加载它们。代码分割就是将应用程序分割成这些延迟加载的块的过程。

Vue.js中的延迟加载和代码拆分_第2张图片

在大多数情况下,当用户访问您的网站时,您不需要立即使用Javascript包中的所有代码。

例如,我们不需要花费宝贵的资源来为首次访问我们网站的访客加载“我的页面”区域。或者可能存在每个页面上不需要的模态,工具提示和其他零件和组件。

当只需要几个部分时,在每个页面加载时下载,解析和执行整个包的所有内容都是浪费。

延迟加载允许我们拆分捆绑包并仅提供所需的部分,这样用户就不会浪费时间下载和解析不会使用的代码。

要查看我们网站中实际使用了多少JavaScript代码,我们可以转到devtools -> cmd + shift + p -> type coverage - >hit ‘record’.。现在我们应该能够看到实际使用了多少下载的代码。

Vue.js中的延迟加载和代码拆分_第3张图片

标记为红色的所有内容都是当前路线上不需要的东西,可以延迟加载。如果您正在使用源映射,则可以单击此列表中的任何文件,并查看未调用哪些部分。正如我们所看到的,甚至vuejs.org还有很大的改进空间。

通过延迟加载适当的组件和库,我们设法将Vue Storefront的捆绑大小减少了60%!这可能是获得性能提升的最简单方法。

好的,我们知道延迟加载是什么,它非常有用。现在是时候看看我们如何在我们自己的Vue.js应用程序中使用延迟加载。

动态导入

Vue.js中的延迟加载和代码拆分_第4张图片

我们可以使用webpack动态导入轻松地加载我们应用程序的某些部分。让我们看看它们的工作原理以及它们与常规进口的区别。

如果我们以这样的标准方式导入JavaScript模块:

// cat.js
const Cat = {
  meow: function () {
    console.log("Meowwwww!")
  }
}
export default Cat

// main.js
import Cat from './cat.js'
Cat.meow()

它将作为main.js依赖关系图中的a的节点添加并与其捆绑在一起。

但是,如果我们Cat仅在某些情况下需要我们的模块,例如对用户交互的响应,该怎么办?将此模块与我们的初始捆绑包捆绑在一起是一个坏主意,因为它始终不需要。我们需要一种方法告诉我们的应用程序什么时候应该下载这段代码。

这是动态导入可以帮助我们的地方!现在看一下这个例子:

// main.js
const getCat = () => import('./cat.js')
// later in the code as a response to some user interaction like click or route change
getCat()
  .then({ meow } => meow())

我们来看看这里发生的事情:

Cat我们创建了一个返回import()函数的函数,而不是直接导入模块。现在,webpack会将动态导入的模块的内容捆绑到一个单独的文件中。表示动态导入模块的函数返回一个Promise,它将使我们在解析时访问模块的导出成员。

然后,我们可以在需要时下载此可选块。例如,作为对某个用户交互的响应(如路由更改或单击)。

通过动态导入,我们基本上隔离了Cat将被添加到依赖图中的给定节点(在这种情况下)并在我们决定需要时下载该部分(这意味着我们也切断了导入的模块Cat.js)。

让我们看另一个更好地说明这种机制的例子。

假设我们有一个非常小的网上商店,有4个文件:

  • main.js 作为我们的主要捆绑
  • product.js 对于产品页面中的脚本
  • productGallery.js 用于产品页面中的产品库
  • category.js 对于类别页面中的脚本

如果不深入研究细节,让我们看看这些文件是如何在整个应用程序中分布的:

// category.js
const category = {
  init () { ... }
}
export default category

// product.js
import gallery from ('./productGallery.js')

const product = {
  init () { ... }
}
export default product
// main.js
const getProduct = () => import('./product.js')
const getCategory = () => import('./category.js')

if (route === "/product") {
  getProduct()
    .then({init} => init()) // run scripts for product page
}
if (route === "/category") {
  getCategory()
    .then({init} => init()) // run scripts for category page
}

在上面的代码中,根据当前路由,我们动态导入其中的一个productcategory模块,然后运行init由它们两者导出的函数。

知道动态导入是如何工作的我们知道product并且category最终会以单独的捆绑包结束,但是productGallery未动态导入的模块会发生什么?正如我们所知,通过使模块动态导入,我们正在削减依赖图的一部分。在此部件中导入的所有内容都将捆绑在一起,因此productGallery最终将与product模块捆绑在一起。

换句话说,我们只是为依赖图创建某种新的入口点。

Vue.js中的延迟加载和代码拆分_第5张图片

延迟加载Vue组件

现在我们知道延迟加载是什么以及为什么需要它。现在是时候看看我们如何在Vue应用程序中使用它了。

好消息是它非常简单,我们可以懒得加载整个单一文件组件,它的CSS和HTML使用与以前相同的语法!

const lazyComponent = () => import('Component.vue')

......这就是你所需要的!现在只有在请求时才会下载组件。以下是调用Vue组件动态加载的最常用方法:

  • 调用带导入的函数
const lazyComponent = () => import('Component.vue')
lazyComponent()
  • 请求组件呈现



请注意,仅当请求组件在模板中呈现时,才会调用lazyComponent函数。例如这段代码:

 

在DOM中需要组件之前,组件将不会加载,只要v-if值更改为true即可。

总结和接下来会发生什么

延迟加载是使您的Web应用程序更高效并减少捆绑包大小的最佳方法之一。我们学习了如何使用Vue组件进行延迟加载。

在本系列的下一部分中,我将向您展示在任何Vue.js应用程序上获得显着性能提升的最有用(也是最快)的方法。

您将学习如何使用异步路由拆分Vue代码以及此过程的建议最佳实践。

Vue.js中的延迟加载和代码拆分_第6张图片

转:https://vueschool.io/articles/vuejs-tutorials/lazy-loading-and-code-splitting-in-vue-js/?source=post_page---------------------------

你可能感兴趣的:(Vue.js中的延迟加载和代码拆分)