logo
Laucher

Laucher

Laucher

2020年 08月 30日

0

加速 Vue.js 应用程序的 6 种方法

让您的Vue项目程序快如闪电

封面图

如果您曾经使用过 Google 的 Pagespeed Insights 或 Google Lighthouse,那么您就会看到这个网页性能评估:

czhlove
czhlove
你会收到一组统计数据,然后是一些关于你的网站有多快(或多慢)的诊断。

一些诊断可能非常有用,指示一些简单的修复、未使用的文件以及缓慢或占用大量空间的请求。

其他诊断,例如主线程工作和 JavaScript 执行时间确实会显示问题,但它们并不能真正帮助您解决问题。

在本文中,我将给您介绍可以遵循的步骤,以确保您的 Vue 应用程序尽可能加快运行。通过这些步骤,您将确切地知道要修复什么,而不必猜测任何事情。

1.只更新需要的

使用 VueJS 可能遇到的最棘手的问题之一是渲染相同的元素或元素列表的次数超过需要的次数。要理解为什么或如何发生这种情况,我们必须了解 Vue 中的响应性。

此示例来自官方 Vue.js 文档,它显示了哪些属性是响应性的,哪些不是。Vue 中有许多响应式元素:分配给数据对象的属性、计算属性或依赖于响应式属性的方法。

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` is now reactive
vm.b = 2
// `vm.b` is NOT reactive

但是普通的 JavaScript 代码,例如{{ 'value' }}or {{ new Date() }},不会被 Vue 作为响应式属性进行跟踪。

那么响应性与重复渲染有什么关系呢?

假设您的data对象中有这样一组对象:

values: [{id: 1, t: 'a'}, {id: 2, t: 'b'}]

你正在使用它在v-for上渲染:

<div v-for="value in values" :key="value.id">{{ value.t }}</div>

当一个新元素被添加到列表中时,Vue 将重新渲染整个列表。不相信?尝试这样写:

<div v-for="value in values" :key="value.id">
  {{ value.t }}
  {{ new Date() }}
</div>

JavaScript的Date对象不是响应性的,因此它不会影响渲染。仅当必须再次渲染元素时才会调用它。您将在此示例中看到的是,每次从新日期添加或删除值时,values都会在所有呈现的元素上弹出。

在更优化的页面中您应该期待什么?您应该只期望新的或更改的元素显示新的Date,而根本不应该呈现其他元素。

那么,我们key做了什么,为什么要通过它?该key属性帮助 Vue 了解哪个元素是哪个。如果数组的顺序发生变化,key帮助 Vue 将元素进行定位,而不是再次一个接一个地遍历它们。

指定 key很重要,但这还不够。为了确保获得最佳性能,您需要创建Child组件。没错————解决方案非常简单。你只需要将你的 Vue 应用程序分成小的、轻量级的组件。

<item :itemValue="value" v-for="item in items" :key="item.id"></item>

该项目组件仅在特定项目发生反应性更改时才会更新(例如使用Vue.set

使用组件呈现列表的性能提升是巨大的。如果在数组中添加或删除元素,Vue 将不会再次逐个渲染所有组件。如果数组是有序的,Vue 只是依靠提供的key去定位渲染。

如果组件真的很轻,你可以做得更好。与其传递一个完整的对象,不如value传递一个原始属性(string或number),比如:itemText="value.t”。 有了它,<item> 只有在您传递的原始值发生变化时才会重新渲染。这意味着即使是被动更改也会导致更新——但这不是必需的!

2.消除重复渲染

渲染完整列表或重元素的次数超过需要的次数是一个相当“狡猾”的问题,但它很容易实现。

假设您有一个组件entities并且在数据对象中有一个属性。

如果您执行了上一步,那么您可能有一个子组件来呈现每个entity

<entity :entity="entity" v-for="entity in entities" :key="entity.id" />

实体模板看起来像这样:

<template>
  <div>
    <div>{{ user.status }}</div>
    <div>{{ entity.value }}</div>
  </div>
</template>

它输出entity.value,但它也使用user状态vuex。现在假设您有一个auth刷新用户令牌的函数,或者以任何方式更改了全局用户属性。这会导致整个视图在任何时候发生变化时更新,即使user.status保持不变!

有几种方法可以处理它。一个简单的方法是将user.status值作为userStatusprop 从父级传递。如果该值未更改,Vue 将不会再次渲染它,因为它没有必要。

这里的关键是要注意渲染依赖性。任何更改的属性、数据值或计算值都可能导致重新渲染。

如何识别重复渲染?

首先下载官方的Vue.js 开发工具,如果您可以访问google可以直接点击下载否则可以在网上搜索Vue.js devtools进行下载!

然后使用“性能选项卡”来衡量您的 Vue 应用程序的性能。按开始和停止运行性能检查,最好是在应用程序加载期间。

vuetool
vuetool

然后转到“组件渲染”选项卡。如果您的页面呈现 100 个组件,那么您应该看到 100 个created事件。

这里需要注意的是updated事件。如果更新的事件多于创建的事件,而实际值没有更新,则很可能有重复更改导致重复渲染。

如果您的代码entities多次更改值而不是批处理更新,就会发生这种情况。或者,如果您使用某种实时数据库(如 Firestore)并且您获得的快照比预期的多,则可能会发生这种情况。(Firestore 可以在每次更新时发送许多快照,尤其是当您有更新相关文档的 Firestore 触发器时)。

这里的解决方案是避免多次更改实体。对于 Firestore 快照,您可以使用 debounce 或 throttle 函数来避免entities过于频繁地更改属性。

3.优化事件处理

并非所有事件都是平等创建的,因此您必须确保针对每个事件都进行了正确的优化。

两个很好的例子是@mouseoverwindow.scroll事件。即使正常使用,这两种类型的事件也可以多次触发。如果您现有的事件处理程序进行代价高昂的计算,这些计算将每秒运行多次,从而导致您的应用程序出现延迟。一种解决方案是使用防抖功能来限制处理这些事件的次数。

4. 删除或减少慢速组件

自己创建新组件时,尤其是导入第三方组件时,您需要确保它们运行良好。

您可以使用 Vue.js 开发工具的性能选项卡来估计您正在使用的每个组件的渲染时间。添加新组件时,您可以看到与自己的组件相比渲染需要多少时间。

如果新组件比您自己的组件花费更多时间,那么您可能需要查看替代组件、删除它或尝试减少它的使用。

czhlove
czhlove

5.渲染一次

czhlove
czhlove

这来自官方 Vue.js 文档。如果你的元素一旦被挂载,就应该只渲染一次,你可以使用 v-once 指令。

假设您的应用程序中有一个部分要求数据在整个会话期间都不会更改。通过使用 v-once 指令,您可以确保此部分仅呈现一次。

6.虚拟滚动

这是优化 Vue 应用程序性能的最后一步。您可以无限滚动,而不会降低页面速度。但是如果你有一个巨大的列表要在你的 Vue 应用程序中呈现,你会看到页面加载变慢。

如果你决定实现无限滚动而不是分页,你可以而且应该使用这两个开源项目之一来实现虚拟滚动器和呈现大量项目列表: https://github.com/tangbc/vue-virtual-scroll-list https://github.com/Akryum/vue-virtual-scroller 我都用过,根据我的经验,vue-virtual-scroll-list它更好,因为它更易于使用,并且不依赖于可能破坏 UI 的绝对位置。

结论

尽管本文章并未涵盖所有场景,但这六种方法涵盖了 Vue 应用程序的许多常见性能问题。

实现出色的前端性能比您可能意识到的更重要。与最终使用您的应用程序的用户相比,开发人员通常拥有更好的计算机。您的用户甚至可能不使用计算机,而是使用速度慢且过时的智能手机。

因此,作为开发人员,我们有责任尽我们最大的努力并提供最佳的用户体验。您可以将这六种方式用作检查清单,以帮助确保您的 Vue 应用程序为所有用户顺利运行。

评论