解读vue3源码-2

提示:看到我 请让滚去学习

vue3编译模版的提升

文章目录

  • vue3编译模版的提升
    • 静态节点提升
    • 补丁标志和block的使用
    • 附录:


template explorer可以将我们的源模版转化成渲染函数代码,vue2中就有,而Vue3 template explorer 功能更加丰富。

静态节点提升

请添加图片描述
当我们开启静态提升,可以发现静态节点确实被从渲染函数中提升以便可以在每个渲染器上重用它,所以在每次组件更新时,我们都会重新调用render函数,但是_hoisted_1都将被重用。

请添加图片描述
这样有两点好处:

1.避免重新创建对象,然后删除

2.在模版算法中,当看到两个节点在同一位置时,在严格平等的情况下,我们可以跳过它,因为我们知道它永远不会改变

补丁标志和block的使用

请添加图片描述

Vue 3 template explorer中当我们绑定一个监听器,编译器会生成一个补丁标志,表明这个节点有动态props需要修补下,以及需要修补的名称是onclick。通常使用简单的虚拟dom渲染算法,在div上绑定的元素,整个对象必须作为一个整体来diff,所以如果div上绑定了一个静态的id属性,我们还是会对比整个对象,确保它不会改变,因为运行时并不能确定它是否改变。但是vue3的编译器通过补丁和关键字结合可以为运行时提供足够信息,确定可以改变的是哪些属性。所以渲染是可以跳过编译器那些推断的永远不会改变的props。

上述在虚拟dom发生改变时,不会检查整个节点的所有属性方法,而是结合补丁标志检查可改变的东西。但实际上,我们更多时候绑定一个事件监听器,并不会更改事件处理程序,所以vue3默认开启cacheHandlers

请添加图片描述

开启cacheHandlers会把我们的事件变成一个内联函数,并在第一次渲染时将其缓存,在此后渲染中,我们将始终使用同一个内联处理程序,但是里面的函数会访问ctx.onClick,所以即时onClick发生变化,我们不需要对vnode本身做任何事,所以上述代码在更新过程中现在可以完全跳过整个节点。

所有这些在vue2父子组件中,即使子组件什么都没有改变,也会导致所有子组件在父组件重新渲染时,所有接受到那个props的子组件重新渲染,在大型应用中,会引起连锁反应,因为你在向下传递函数,在每次渲染时,都会创建一个新的内联函数,会导致所有收到那个props的子组件重新渲染,所以vue3中使用句柄缓存,可以避免在大型组件树中发生不必要的渲染

当我们调用render函数会生成一个类似以下的vdom

请添加图片描述

当vdom某些数据发生改变时,渲染器并不知道发生了什么改变,所以它会递归遍历整棵树,进行新旧快照对比,对比新旧节点找出改变了什么,这显然会导致更多的性能问题。

请添加图片描述

例如上述代码我们每次更新发生变化的只有span标签,编译器会使用_openBlock(),将模版的根变成我们所称的块(block),上图中的_openBlock(),当块打开时,所有的节点表达式都会被评估是否是动态的,当节点创建时携带有补丁表示的东西(动态)都会被跟踪,并且添加到当前打开的block作为动态子节点。所以在render方法整个调用后,根div将有一个额外的属性,称为动态子节点,它是只包含了携带补丁标识的子节点的扁平化数组。不管dom节点层级多深,块都只跟踪其上的动态节点。

请添加图片描述

另外如果使用v-if等结构指令,它会改变节点结构,当v-if值切换时节点会从dom树上消失,所以对于根节点的block,使用v-if的节点下的节点将不再安全。所以v-if节点会变成一个块,这个块会变成父节点的动态快被跟踪,所以有嵌套的块,将在扁平化数组中跟踪他自己的动态子对象。

所以对于整个dom树在跟新时不再需要再检查每个vnode的变化,而是递归去找block,得到block内可能发生变化的信息。

在这里插入图片描述

补丁信息本身还编码了关于什么样工作信息,例如TEXT表示在你试图区分这个节点时,只需要检查它的文本内容而不需要关注例如props等其他信息

附录:

vue2在线模版编译器:[https://vue3js.cn/vue-template-explorer/]{.underline}

vue3在线模版编译器:[https://template-explorer.vuejs.org/#]{.underline}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开发nfc读卡器应用出现报错Unhandled Exception: SCARD_E_NO_SERVICE

使用flutter开发ACR122U的nfc读卡器的时候,报错: [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: Error while establing context. Reason: SCARD_E_NO_SERVICE #0 PCSCBinding._checkAndThrow (package:fl…

Vue 框选区域放大(纯JavaScript实现)

需求:长按鼠标左键框选区域,松开后放大该区域,继续框选继续放大,反向框选恢复原始状态 实现思路:根据鼠标的落点,放大要显示的内容(内层盒子),然后利用水平偏移和垂直偏…

ABB码垛机器人IRB260通讯板维修

ABB码垛机器人在现代制造业中发挥着重要作用,而机器人通讯板维修对于确保机器人的正常运行至关重要。 通讯板是ABB码垛机器人与控制系统之间进行数据传输的桥梁。它负责接收控制系统的指令,并将机器人的运行数据反馈给控制系统。如果通讯板出现故障&…

ESP32开发板定义硬串口

ESP32 的默认串口 UART序号Rx PINTx PIN是否可用UART0GPIO3GPIO1是UART1GPIO9GPIO10是&#xff0c; 但与SPI flash相关联需要重新定义UART2GPIO16GPIO17是 下面我们定义2、4GPIO引脚为串口1&#xff1a; #include <HardwareSerial.h> HardwareSerial S1(1); 初始化 …

C语言 | Leetcode C语言题解之第120题三角形最小路径和

题目&#xff1a; 题解&#xff1a; int minimumTotal(int** triangle, int triangleSize, int* triangleColSize) {int f[triangleSize];memset(f, 0, sizeof(f));f[0] triangle[0][0];for (int i 1; i < triangleSize; i) {f[i] f[i - 1] triangle[i][i];for (int j …

【VTKExamples::PolyData】第五十四期 SelectVisiblePoints

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例SelectVisiblePoints,并解析接口vtkSelectVisiblePoints,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动…

[Linux系统编程]文件IO

一.系统调用 什么是系统调用? 只有系统调用(系统函数)才能进入内核空间&#xff0c;库函数也是调用系统函数&#xff0c;才得以访问底层。 系统调用由操作系统实现并提供给外部应用程序的编程接口。是应用程序同系统之间数据交互的桥梁。 换句话说&#xff0c;系统调用就是操…

yolov5-ros模型结合zed2相机部署在 Ubuntu系统

前言 本篇文章主要讲解yolov5-ros模型结合zed2相机进行实时检测&#xff0c;经改进实现了红绿灯检测&#xff0c;并输出检测类别与置信度&#xff01; 目录 一、环境配置二、zed2驱动安装三、yolov5-ros功能包配置四、运行官方权重文件四、运行自己权重文件 一、环境配置 1、…

14-alert\confirm\prompt\自定义弹窗

一、认识alert\confirm\prompt 下图依次是alert、confirm、prompt&#xff0c;先认清楚长什么样子&#xff0c;以后遇到了就知道如何操作了。 二、alert操作 先用driver.switch_to.alert方法切换到alert弹出框上&#xff1b;可以用text方法获取弹出的文本信息&#xff1b;acce…

【介绍下运维,什么是运维?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

C++ | Leetcode C++题解之第120题三角形最小路径和

题目&#xff1a; 题解&#xff1a; class Solution { public:int minimumTotal(vector<vector<int>>& triangle) {int n triangle.size();vector<int> f(n);f[0] triangle[0][0];for (int i 1; i < n; i) {f[i] f[i - 1] triangle[i][i];for (…

RK3588+FPGA+AI高性能边缘计算盒子,应用于视频分析、图像视觉等

搭载RK3588&#xff08;四核 A76四核 A55&#xff09;&#xff0c;CPU主频高达 2.4GHz &#xff0c;提供1MB L2 Cache 和 3MB L3 &#xff0c;Cache提供更强的 CPU运算能力&#xff0c;具备6T AI算力&#xff0c;可扩展至38T算力。 产品规格 系统主控CPURK3588&#xff0c;四核…

【QEMU中文文档】1.1 支持的构建平台

本文由 AI 翻译&#xff08;ChatGPT-4&#xff09;完成&#xff0c;并由作者进行人工校对。如有任何问题或建议&#xff0c;欢迎联系我。联系方式&#xff1a;jelin-shoutlook.com。 原文&#xff1a;Supported build platforms — QEMU documentation QEMU 旨在支持在多个主机…

Webrtc支持HEVC之FFMPEG支持HEVC编解码(一)

一、前言 Webrtc使用的FFMPEG(webrtc\src\third_party\ffmpeg)和官方的不太一样,使用GN编译,各个平台使用了不一样的配置文件 以Windows为例,Chrome浏览器也类似 二、修改配置文件 windows:chromium\config\Chrome\win\x64 其他平台: chromium\config\Chrome\YOUR_SYS…

Dynamics 365:安全的客户参与应用程序

客户参与应用程序使用Microsoft Dataverse提供了一个丰富的安全模型&#xff0c;可以适应许多业务场景。本节为您提供了应考虑的安全措施的特定于产品的指导。 Dataverse安全模型有以下目标&#xff1a; 只允许用户访问他们工作所需的信息。按角色对用户进行分组&#xff0c;并…

Sping源码(九)—— Bean的初始化(非懒加载)— FactoryBean

FactoryBean 先来介绍一下FactoryBean是什么。以及BeanFactory和FactoryBean的区别。 举个栗子&#xff1a; MyFactoryBean.class public class MyFactoryBean implements FactoryBean<User> {Overridepublic User getObject() throws Exception {return new User(&qu…

CAPL如何发送一条UDP报文

UDP作为传输层协议,本身并不具有可靠性传输特点,所以不需要建立连接通道,可以直接发送数据。当然,前提是需要知道对方的通信端点,也就是IP地址和端口号。 端口号是传输层协议中最显著的特征,传输层根据它来确定上层绑定的应用程序,以达到把数据交给上层应用处理的目的。…

五种主流数据库:常用数据类型

在设计数据库的表结构时&#xff0c;我们需要明确表中包含哪些字段以及字段的数据类型。字段的数据类型定义了该字段能够存储的数据种类以及支持的操作。 本文将会介绍五种主流数据库中常用的数据类型以及如何选择合适的数据类型&#xff0c;包括 MySQL、Oracle、SQL Server、…

基于Springboot + vue实现的文化民俗网站

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

uni-app的网络请求库封装及使用(同时支持微信小程序)

其实uni-app中内置的uni.request()已经很强大了&#xff0c;简单且好用。为了让其更好用&#xff0c;同时支持拦截器&#xff0c;支持Promise 写法&#xff0c;特对其进行封装。同时支持H5和小程序环境&#xff0c;更好用啦。文中给出使用示例&#xff0c;可以看到使用变得如此…