Vue的依赖收集和性能问题

news2024/11/26 12:34:24

什么是依赖收集

Vue能够实现当一个数据变更时,视图就进行刷新,而且用到这个数据的其他地方也会同步变更;而且,这个数据必须是在有被依赖的情况下,视图和其他用到数据的地方才会变更。 所以,Vue要能够知道一个数据是否被使用,实现这种机制的技术叫做依赖收集。

每个组件实例都有相应的watcher实例 - 渲染组件的过程,会把属性记录为依赖 - 当我们操纵一个数据时,依赖项的setter会被调用,从而通知watcher重新计算,从而致使与之相关联的组件得以更新。

Vue2用defineProperty来劫持属性,生成watcher实例来响应属性的变化。

注意,Dep的target是watcher实例

依赖收集与观察者模式

在Vue依赖收集里:谁是观察者?谁是观察目标? 显然: - 依赖的数据是观察目标(Watcher) - 视图、计算属性、侦听器这些是观察者Watcher

依赖收集分析

依赖收集的三个类:
  • Dep:发布者。扮演观察目标的角色,每一个数据都会有Dep类实例,它内部有个subs队列,subs就是subscribers的意思,保存着依赖本数据的观察者,当本数据变更时,调用dep.notify()通知观察者

  • Watcher:观察者。扮演观察者的角色,进行观察者函数的包装处理。如render()函数,会被进行包装成一个Watcher实例

  • Observer:观测类。辅助的可观测类,数组/对象通过它的转化,可成为可观测数据

每一个数据都有的Dep类实例:

由于JavaScript是单线程模型,所以虽然有多个观察者函数,但是一个时刻内,就只会有一个观察者函数在执行,那么此刻正在执行的那个观察者函数,所对应的Watcher实例,便会被赋给Dep.target这一类变量,从而只要访问Dep.target就能知道当前的观察者是谁。 在后续的依赖收集工作里,getter里会调用dep.depend(),而setter里则会调用dep.notify()

Watcher观察者

一个组件里可以有多个Watcher类实例,Watcher类包装观察者函数,而观察者函数使用数据。 观察者函数经过Watcher是这么被包装的:

- 模板渲染:this._watcher = new Watcher(this, render, this._update)

- 计算属性:

computed: {
    name() {
        return `${this.firstName} ${this.lastName}`;
    }
}
/*
会形成
new Watcher(this, function name() {
    return `${this.firstName} ${this.lastName}`
}, callback);
*/

在Watcher类里做的事情,概括起来则是:

1、传入组件实例、观察者函数、回调函数、选项:

先解释清楚4个变量:deps、depIds、newDeps、newDepIds,它们的作用如下:

- deps:缓存上一轮执行观察者函数用到的dep实例

- depIds:Hash表,用于快速查找

- newDeps:存储本轮执行观察者函数用到的dep实例

- newDepIds:Hash表,用于快速查找

2、进行初始求值,初始求值时,会调用watcher.get()方法

3、watcher.get()会做以下处理:初始准备工作、调用观察者函数计算、事后清理工作

①在初始准备工作里,会将当前Watcher实例赋给Dep.target,清空数组newDeps、newDepIds

②执行观察者函数,进行计算。由于数据观测阶段执行了defineReactive(),所以计算过程用到的数据会得以访问,从而触发数据的getter,从而执行watcher.addDep()方法,将特定的数据记为依赖

③对每个数据执行watcher.addDep(dep)后,数据对应的dep如果在newDeps里不存在,就会加入到newDeps里,这是因为一次计算过程数据有可能被多次使用,但是同样的依赖只能收集一次。并且如果在deps不存在,表示上一轮计算中,当前watcher未依赖过某个数据,那个数据相应的dep.subs里也不存在当前watcher,所以要将当前watcher加入到数据的dep.subs里

④进行事后清理工作,首先释放Dep.target,然后拿newDeps和deps进行对比,接着进行以下的处理:

- newDeps里不存在,deps里存在的数据,表示是过期的缓存数据。相应的,从数据对应的dep.subs移除掉当前watcher

- 将newDeps赋给deps,表示缓存本轮的计算结果,这样子下轮计算如果再依赖同一个数据,就不需要再收集了

⑤当某个数据更新时,由于进行了setter拦截,所以会对该数据的dep.subs这一观察者队列里的watchers进行通知,从而执行watcher.update()方法,而update()方法会重复求值过程(即为步骤3-7),从而使得观察者函数重新计算,而render()这种观察者函数重新计算的结果,就使得视图同步了最新的数据

Vue的依赖收集,是观察者模式的一种应用。其原理总结如图:

    • 配置依赖观测
    • 收集依赖
    • 数据值变更

依赖收集带来的问题:

依赖收集需要对数据元进行递归绑定。当数据元数据量过大(例如明细表或透视表数十万条数据),会严重影响前端的性能效率。

解决方法:

①避开依赖收集:

不使用this.xxx = data绑定数据

对数据使用Object.freeze进行冻结(避免依赖收集,Vue2对configurable为false的对象不进行数据劫持)或者将数据绑定为class私有属性

②将数据对象约定为数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/167272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

逻辑思维训练1200题-蓝桥杯计算思维参考

黑格尔曾说过,逻辑是一切思考的基础。逻辑思维能力强的人能迅速、准确地把握住问题的实质,面对纷繁复杂的事情能更容易找到解决的办法。《逻辑思维训练1200 题》介绍了排除法、递推法、倒推法、作图法、假设法、计算法、分析法、类比法、推理法、判断法、…

自动化 | 这些常用测试平台,你们公司在用的是哪些呢?

本文节选自霍格沃兹测试学院内部教材测试管理平台是贯穿测试整个生命周期的工具集合,它主要解决的是测试过程中团队协作的问题。在整个测试过程中,需要对测试用例、Bug、代码、持续集成等等进行管理。下面分别从这四个方面介绍现在比较流行的管理平台。6…

四、template模板

模板 之前的案例中&#xff0c;能够返回简单的字符串信息给浏览器。那如果想要返回html页面给浏览器该怎么做呢&#xff1f; 当然&#xff0c;我们可以这么写&#xff1a; def index(request):return HttpResponse(<h1 style"color:red">我是硬编码的</h…

23年3月如何准备pmp考试?

首先要把PMP考试如何报名、考试内容等都要了解清楚&#xff0c;再去备考。<<PMP入门知识>>PMP考试时长&#xff1a;230分钟。PMP考试形式&#xff1a;笔试。PMP考试题型&#xff1a;题型包括单选题和多选题&#xff0c;多选题将说明需选择几个正确选项。PMP考试题量…

NEUQ week11题解

P1796 汤姆斯的天堂梦 汤姆斯的天堂梦 题目描述 汤姆斯生活在一个等级为 000 的星球上。那里的环境极其恶劣&#xff0c;每天 121212 小时的工作和成堆的垃圾让人忍无可忍。他向往着等级为 NNN 的星球上天堂般的生活。 有一些航班将人从低等级的星球送上高一级的星球&#…

【Java寒假打卡】Java基础-网络编程UDP和TCP

【Java寒假打卡】Java基础-网络编程UDP和TCP网络编程的三要素网络编程的常见命令InetAddress类端口协议UDP发送数据UDP接受数据UDP通信程序的练习TCP通信程序-发送数据TCP通信程序-接受数据网络编程的三要素 网络编程的常见命令 ipconfig 查看本机IP地址ping IP地址&#xff1…

【系列03】方法的学习 方法重载 命令行传参 递归 简单计算机 [有目录]

方法的学习 什么是方法 方法是解决一类问题的步骤的有序组合包含于类或者对象之中方法在程序中被创建,在其他地方被引用 就比如输出方法如:System.out.println(); 就是被封装好的方法 方法设计原则:一个方法完成一个功能,利于后期扩展 [原子性] 使用方法: public class D…

vue中使用echarts 动态渲染数据

一、业务场景&#xff1a; 最近在vue中使用echarts时 引入的时候怎么也引不上&#xff0c;后面发现需要绑定在原型上就可以完美解决(也可以直接在需要引入的页面用ES5中的require引入require&#xff08;‘echarts’&#xff09;) 为了避免大家走弯路&#xff0c;下面整合了一下…

FLStudio水果21最新Daw (宿主软件)电音混音编曲制作工具

对许多音乐爱好者来说&#xff0c;从单独欣赏作品过渡到按自己的心情创作作品&#xff0c;是一种奇妙而令人高兴的体验。 音乐的编曲&#xff0c;特别是电子的编曲&#xff0c;Daw (宿主软件)是重要的要素。 编曲软件有很多。 “专业”这个词取决于你是否在行业的某个部分。 就…

MyBatis 详解 (1) -- 环境搭建、查询操作

MyBatis 详解 1 -- 环境搭建、查询操作一、MyBatis 是什么二、为什么学习 MyBatis三、MyBatis 查询3.1 前言3.2 创建数据库和表3.3 添加 MyBatis 框架支持添加 MyBatis 和 MySQL 驱动3.4 配置连接字符串 和 MyBatis3.4.1 配置连接字符串3.4.2 配置 MyBatis 中的 XML 路径3.5 添…

CSS造成阻塞的原理

目录 1.原理解析 A.webkit渲染过程 B.Gecko渲染过程 C.解析原理 接上篇文章CSS会造成阻塞吗&#xff1f; 我们来说一下CSS造成阻塞的原理 1.原理解析 那么为什么会出现上面的现象呢&#xff1f;我们从浏览器的渲染过程来解析下。 不用浏览器使用的内核不同&#xff0c…

leetcode 648. 单词替换【python3哈希集与两种字典树的方法的思考过程整理】

题目 在英语中&#xff0c;我们有一个叫做 词根(root) 的概念&#xff0c;可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如&#xff0c;词根an&#xff0c;跟随着单词 other(其他)&#xff0c;可以形成新的单词 another(另一个)。…

UI自动化测试模块与环境管理全面打通,MeterSphere开源持续测试平台v2.6.0发布

2023年1月16日&#xff0c;MeterSphere一站式开源持续测试平台正式发布v2.6.0版本。 在这一版本中&#xff0c;MeterSphere的UI自动化测试模块与环境管理全面打通&#xff0c;更好地满足了用户一个脚本同时跑多个环境的测试需求。在测试跟踪模块中&#xff0c;测试计划关联测试…

怎么系统的阅读文献

文章目录一、文献阅读1、综述类文献 review article2、研究类文章 research article3、方法学的文章第一部分 综述类文章的阅读第二部分 研究型文章的阅读a. 研究型论文结构b. 如何有选择阅读文献c. 如果整理笔记Citation和Reference的区别二、文献阅读工具1、Connected Papers…

python-while循环

文章目录一、程序的三种结构二、while循环1.1&#xff1a;死循环1.2&#xff1a;循环计数习惯案例1.3&#xff1a;循环计数2.0&#xff1a;break终止循环3.0&#xff1a;人造死循环4.0&#xff1a;continue5.0循环嵌套一、程序的三种结构 1&#xff1a;顺序 代码自上而下执行 …

四旋翼无人机学习第20节--PCB自动保存文件labview设计

0 前言 在设计PCB的过程中&#xff0c;通常一个项目的的PCB文件只有一个&#xff0c;如果保存完文件后想要回滚到自己的版本是比较难的&#xff0c;虽然allergo软件可以设置autosave功能来自动对PCB文件进行备份&#xff0c;但是备份文件只会保存最后一次的版本。 1 labview编…

JavaWeb基础(二) HTTP、Tomcat、Servlet介绍

JavaWeb基础(二) HTTP、Tomcat、Servlet介绍 1&#xff0c;Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&#xff0c;也称为万维网(www)&#xff0c;能够通过浏览器访问的网站。 在我们日常的生活中&#xff0c;经常会使用浏览器去访问百度、京东、传智官网等这些网站&a…

Dubbo调用

Dubbo调用 0. 概述 Dubbo 服务调用过程比较复杂&#xff0c;包含众多步骤&#xff0c;比如发送请求、编解码、服务降级、过滤器链处理、序列化、线程派发以及响应请求等步骤。 1. 客户端发送请求时序图 InvokerInvocationHandler.invoke 1. 对于Object中的方法toString, has…

IDEA常用配置整理说明

文章目录IDEA常用配置整理说明1、 IDE配置1.1 设置相关1.1.1 忽略大小写开关1.1.2 取消单行显示tabs的操作1.1.3 项目文件编码1.1.4 滚轴修改字体大小1.1.5 设置显示行号和方法间的分隔符1.1.6 新建类头注释信息1.1.7 JavaDoc注释&#xff08;就是方法上加的注释&#xff09;1.…

蓝桥杯:整数分解

题目链接 问题描述 答案提交 本题答案&#xff1a;691677274345。 思路分析 问题描述 将 3 分解成两个正整数的和, 有两种分解方法, 分别是312 和 321 。注意顺序不同算不同的方法。 将 5 分解成三个正整数的和, 有 6 种分解方法, 它们是 113 122 131 212 221 311。…