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

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

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

Webpack bundling如何工作?

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

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

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

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

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

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

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

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

延迟加载

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

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

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

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

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

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

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

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

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

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

动态导入


我们可以使用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组件

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

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

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

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

  • 调用带导入的函数
const lazyComponent = () => import('Component.vue')
lazyComponent()
  • 请求组件呈现
<template>
  <div> 
    <lazy-component />
  </div>
</template>

<script>
const lazyComponent = () => import('Component.vue')
export default {
  components: { lazyComponent }
}

// Another syntax
export default {
  components: {
    lazyComponent: () => import('Component.vue')
  }
}
</script>

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

<lazy-component v-if="false" /> 

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

总结和接下来会发生什么

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

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

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


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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,154评论 0 1
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    柴东啊阅读 15,857评论 2 140
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    你猜_3214阅读 11,069评论 0 118
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,455评论 1 77
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,495评论 0 72