使用v-memo缓存模板子树提高应用性能详解

目录
  • 引言
  • v-memo 是做什么的?
  • 事例
    • 错误的使用方式
    • 管理更新
    • 与 v-for 结合使用
    • 无意中停止了子组件触发的更新
  • 总结

引言

Vue3 为我们提供了几项开箱即用的重大性能改进,但也引入了一些额外的手动功能,可以帮助提高我们的应用性能。

在这节课中,我们介绍一下,在 Vue 3.2 中引入新指令 v-memo。引入这个指令的目的是帮助我们提高中型/大型 Vue 应用程序的性能,小项目大家根据需要自行决定。

v-memo 是做什么的?

官网对 v-memo 定义是这样的:

缓存一个模板的子树。在元素和组件上都可以使用。为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。举例来说:

看起来有点绕,但实际上,很好理解。v-memo 所做的与我们现有的计算属性一样,只不过 v-memo 的对象是 DOM。

这个新指令将缓存它所控制的DOM部分,如果一个特定的值发生变化,只需运行更新并重新渲染。这些值是由我们自己手动设置。

事例

<template>
  <div>
    ..the rest of the component
    <div v-memo="[myValue]">
      <svg >
        <title>{{MyValue}}</title>
        ...
      </svg>
      <vue-custom-element :value="myValue"></vue-custom-element>
    </div>
  </div>
</template>

对上面解释一下: v-memo 通常是作为组件的一部分来使用的,它只是影响组件 dom 的一个子集。

<div v-memo="[myValue]">

接着,我们将 v-memo分配给了一个特定的 DIV 和它的所有子元素。当调用 v-memo 时,需要传递一个值数组,以控制子树的渲染。

数组接受一个或多个值 v-memo="[valueOne, valueTwo]",也接受像 v-memo="myValue === true"这样的表达。

另外:用一个空数组调用 v-memo相当于使用v-once,只会渲染该部分组件一次。

<svg >
  <title>{{MyValue}}</title>
  ...
</svg>
<vue-custom-element :value="myValue"></vue-custom-element>

同在看下子树的内容。在我们的例子中,使用了一个 svg 元素和一个自定义 Vue 组件 vue-custom-element。这样做是为了说明一件事:v-memo 包含任何元素。

错误的使用方式

<div v-memo="[myValue]">
  <p>Static content, no vue values here</p>
</div>

在上面的例子中,包含在 v-memo 中的子树不需要被缓存,因为它是静态的,不会改变(它不包括任何Vue变量)。Vue3 会对静态进行一个提升,以便提高性能。

在一个静态的HTML上添加 v-memo 是没啥作用,不管这个HTML有多复杂。

管理更新

在有些情况下,v-memo不仅可以用来提高性能,还可以通过控制组件的更新周期,实际改善UX(用户体验)。

<div v-memo="[allFieldChanged]">
  <p>{{ field1 }}</p>
  <p>{{ field2 }}</p>
  <p>{{ field3 }}</p>
  <p>{{ field4 }}</p>
</div>

在上面的例子中,改变一个单独的字段,例如 field1,并不会导致重新渲染。新的字段将在所有字段都被更新后显示。

最近遇到一个情况,一个子组件会对一个大的JSON数据集进行更新和响应。在这种情况下,使用 v-memo 真的很有帮助,当所有的变化都完成后,就可以触发更新。

与 v-for 结合使用

使用 v-memo 的一个最常见的用例是在处理使用 v-for 渲染的非常大的列表时。

<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
  <p>...more child nodes</p>
</div>

如果不在上面的代码中使用 v-memoselected 变量的每一次改变都会导致列表的完全重新渲染。新指令提供的缓存,允许只更新表达式 item.id === selected 发生变化的行,也就是当某个项被选中或者取消时。

如果我们考虑一个有 1000 条数据的列表。使用上述代码的 v-memo,可以为每一个变化节省998个条重新渲染。

无意中停止了子组件触发的更新

我们知道 v-memo 会停止子树渲染更新,但需要注意的是,使用这个指令实际上会停止任何可能被更新触发的代码的执行,如 watch 函数等。

<div v-memo="[points > 1000]">
  <myComponent :points="points" />
</div>
//myComponent
<isLevel1 v-if="points <= 1000">....</isLevel1>
<isLevel2 v-if="points > 1000">...</isLevel2>
<script>
...,
watch: {
  points() {
    logPointChange();
  }
}

在上面的代码中,如果我们的 points 值是 1000 以内变化,那么 watch 函数不会被执行,直到 points 的值大于 1000 才会触发 watch 函数的执行。

总结

这个新的指令对于要求性能极高的项目有很在帮助了,一般是在比较大型的项目中使用的,当然小型项目,大家可以根据项目需要进行食用。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

更多关于v-memo缓存模板子树的资料请关注我们其它相关文章!

(0)

相关推荐

  • Vue浅析讲解动态组件与缓存组件及异步组件的使用

    目录 1.什么是动态组件 2.如何实现动态组件渲染 3.如何实现缓存组件 4.异步组件 1.什么是动态组件 当我们希望页面中的某个地方,在不同组件之间进行动态切换,这时候除了条件渲染,还可以使用动态组件. 2.如何实现动态组件渲染 vue提供了一个内置的组件,专门用来实现动态组件的渲染:通过 is 属性动态指定要渲染的组件 因为要渲染的组件是不确定的,所以要通过data申明一个变量用来接收组件的名称,用 :is 动态绑定这个变量到组件中,通过按钮添加事件改变变量的值来切换相应组件 案例: //父

  • vue虚拟滚动性能优化方式详解

    目录 引言 虚拟滚动(Virtual Scrolling) 理解虚拟滚动 虚拟 滚动 实现虚拟滚动 核心步骤 效果预览 最后 引言 一个简单的情景模拟(千万别被带入): A: 假设现在有 10 万条数据,你作为前端该怎么优化这种大数据的列表? B: 针对大数据列表一般不会依次性加载,会采用上拉加载.分页加载等方式实现优化. A: 那假如加载到最后一条数据的时候,页面上只是列表部分的数据就至少对应 10 万个 dom 节点,你觉得一个页面渲染至少 10 万个 dom 节点的性能如何? A: 如果这

  • Vue 项目性能优化方案分享

    目录 前言 一.代码层面的优化 1.1.v-if 和 v-show 区分使用场景 1.2.computed 和 watch  区分使用场景 1.3.v-for遍历必须为item添加key,且避免同时使用v-if 1.4.长列表性能优化 1.5.事件的销毁 1.6.图片资源懒加载 1.7.路由懒加载 1.8.第三方插件的按需引入 1.9.优化无限列表性能 1.10.服务端渲染 SSR or 预渲染 二.Webpack 层面的优化 2.1.Webpack 对图片进行压缩 2.2.减少 ES6 转为

  • Vue keepAlive实现不同的路由共用一个组件component的缓存问题(推荐)

    不同的路由共用一个组件component,并用keepAlive实现不同的页面缓存 实现功能:使用列表页面检索的数据跳转到对应的详情页面,从详情页回到列表页能记住上次检索的数据,再次切换到详情页时能正常取到对应的数据 实现方式使用Vue keepAlive实现页面缓存,整理了一些资料和其他的博客在这里记录一下.... keepAlive原理: 1,保留组件的状态,在重新进入页面时避免重新渲染.2.是抽象组件,它自身不会渲染DOM元素,也不会出现在父组件链中.3.当组件在 内被切换,它的 acti

  • vue性能优化之cdn引入vue-Router的问题

    目录 cdn引入vue-Router问题 vue引入外部cdn报错 'XXX is not defined' 及事件处理 解决办法 cdn引入vue-Router问题 关于vue的性能优化,有一个非常重要的点,就是用cdn的方式引入vue.vue- router.ElementUI.vuex.axios.jquery,那么到底怎么引呢? 1.打开国内cdn服务网址: https://www.bootcdn.cn/ 2.查看你的项目 package.json ,查看你安装的是哪个版本 3.在cdn

  • Vue如何解决每次发版都要强刷清除浏览器缓存问题

    目录 每次发版都要强刷清除浏览器缓存问题 原理 vue 强制清除浏览器缓存 (1)最基本的方法就是 (2)在html文件中加入meta标签 (3)需要后端陪着,进行nginx配置 (4)在脚本加载时加入一个时间戳 每次发版都要强刷清除浏览器缓存问题 原理 将打包后的js和css文件,加上打包时的时间戳 1.index.html 在 public 目录下的index.html文件里添加如下代码: <meta http-equiv="pragram" content="no

  • 使用v-memo缓存模板子树提高应用性能详解

    目录 引言 v-memo 是做什么的? 事例 错误的使用方式 管理更新 与 v-for 结合使用 无意中停止了子组件触发的更新 总结 引言 Vue3 为我们提供了几项开箱即用的重大性能改进,但也引入了一些额外的手动功能,可以帮助提高我们的应用性能. 在这节课中,我们介绍一下,在 Vue 3.2 中引入新指令 v-memo.引入这个指令的目的是帮助我们提高中型/大型 Vue 应用程序的性能,小项目大家根据需要自行决定. v-memo 是做什么的? 官网对 v-memo 定义是这样的: 缓存一个模板

  • PHP中加速、缓存扩展的区别和作用详解(eAccelerator、memcached、xcache、APC )

    PHP中有eAccelerator.memcached.xcache.APC 4个加速.缓存扩展,下面给大家介绍下其区别,一起看看吧! 折腾VPS的朋友,在安装好LNMP等Web运行环境后都会选择一些缓存扩展安装以提高PHP运行速度,常被人介绍的有 eAccelerator.memcached.xcache.Alternative PHP Cache这几个缓存扩展,它们之间有什么区别?分别的作用又是什么?我们如何选择?这是本文给于大家的答案. 1.eAccelerator eAccelerato

  • C++ 标准模板库 STL 顺序容器详解

    C++ 标准模板库 STL 顺序容器 容器 数据结构 顺序性 重复性 支持迭代器 vector 动态数组 无序 可重复 随机访问迭代器 deque 双向队列 无序 可重复 随机访问迭代器 list 双向链表 无序 可重复 双向迭代器 动态数组 vector ​ vector #include <vector> 动态数组:其元素在内存中是连续存放的,随机存取任何元素都可以在常数时间内完成,在该容器的尾部增删元素也几乎能够在常数时间内完成具有较好的性能. ​ 一个 vector 常用函数使用实例如

  • 微信小程序本地缓存数据增删改查实例详解

    微信小程序本地缓存数据增删改查实例详解 数据如: var user = { name: 'Lion', sex: 'guy' } CRUD: // 添加 wx.setStorageSync('user', user); // 查询 var developer = (wx.getStorageSync('user') || []); // 更改 developer.name = 'Lion01'; wx.setStorageSync('user', user); // 删除 wx.removeSt

  • 对angular 实时更新模板视图的方法$apply详解

    有的时候在回调里面写了更新scope的里面的内容,视图上面竟然没有同时更新,这就用到了$apply Scope的特性 接下来,看看Scope有哪些特性呢? Scope提供$watch方法监视Model的变化. Scope提供$apply方法传播Model的变化. Scope可以继承,用来隔离不同的application components和属性访问权限. Scope为Expressions的计算提供上下文. 最简单的使用方法,就是在需要传递变化的地方写上以下代码 $scope.$apply()

  • 基于模板引擎Jade的应用(详解)

    有用的符号: | 竖杠后的字符会被原样输出 · 点表示下一级的所有字符都会被原样输出,不再被识别.(就是|的升级版,实现批量) include 表示引用外部文件 短杠说明后面跟着的字符只是一段代码(与|的区别就是,|后面的内容会被显示,而短杠后面的内容直接不显示了!) 例子: js: const jade = require('jade'); console.log(jade.renderFile('./xxx.jade',{pretty:true,name:'singsingasong'}))

  • 对python实现模板生成脚本的方法详解

    最近项目需要,针对主项目提取一个小的基础版本,供于在新建项目时使用,所以就有这个python模板生成脚本,其作用如下: 1.通过配置文件来控制模板中的数据.格式化的过滤条件 2.执行后会把目录下所有的文件都会执行一篇 #!/usr/bin/python #encoding: utf-8 import json import codecs import os def get_files(root_path): for dir in os.walk(root_path): if dir[2]: fo

  • Django模板标签中url使用详解(url跳转到指定页面)

    django {% url %} 模板标签使用 inclusions/_archives.html ... {% for date in date_list %} <li> <a href="{% url 'blog:archive' date.year date.month %}" rel="external nofollow" > {{ date.year }} 年 {{ date.month }} 月 </a> </l

  • Java SpringBoot模板引擎之 Thymeleaf入门详解

    目录 模板引擎简介 引入Thymeleaf模板引擎 分析Thymeleaf模板引擎 测试Thymeleaf模板引擎 1.编写一个TestController 2.编写一个测试页面 test.html 放在 templates 目录下 3.启动项目请求测试 4.结论 Thymeleaf入门: 1.修改测试请求,增加数据传输 2.使用thymeleaf 3.我们去编写下前端页面 4.启动测试! thymeleaf语法学习 1.使用任意的 th:attr 来替换Html中原生属性的值! 2.表达式语法

  • Java本地缓存工具之LoadingCache的使用详解

    目录 前言 环境依赖 代码 演示一下 总结 前言 在工作总常常需要用到缓存,而redis往往是首选,但是短期的数据缓存一般我们还是会用到本地缓存.本文提供一个我在工作中用到的缓存工具,该工具代码为了演示做了一些调整.如果拿去使用的话,可以考虑做成注入Bean对象,看具体需求了. 环境依赖 先添加maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</arti

随机推荐