DOM Diff(差分)算法
1. 算法由来
React调用render()方法后,会生成一个React元素组成的树。
再次调用,生成一个新的树。React比较两者的差异,然后更新UI。
如果单纯使用算法,来查找两个DOM树的差异值,算法复杂度为O(n^3)。
为了提高渲染效率,假定:
1)元素类型不同,是不同的树
2)子元素可以通过key值来判断是否稳定
这样算法复杂度降低到O(n)
2. 算法比较步骤
1. 比较根节点
如果类型不同,卸载整个DOM节点,重新加载;
如果类型相同
1)如果是普通的html标签类型,比较属性,更新变化的属性。
2)如果是组件类型,更新props,引发componentWillReceiveProps和componentDidUpdate方法调用
2. 比较子节点(无key)
如果类型不同,卸载字节点,重新加载;
如果类型相同,依次比较字节点内容
1)这种情况下,追加元素开销最小,因为前面都相同;
2)头部插入元素开销最大;因为比较来看,第一个开始至最后一个都不相同。
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul> <ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
3. 比较子节点(有key非index)
对于上面的情况,如果同一列表的所有子元素有一个唯一值key值。
React先比较key值,如果相同的key值存在,但是位置不同,只移动位置。
元素移动位置只能在兄弟之间移动。
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul> <ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
4. 比较子节点(有key是index)
˙这种情况,如果字节点顺序改变,可能会引起错误。
比如子列表中含有非受控组件input。此时如果触发排序,会导致input的state出现互相篡改。
DOM Diff(差分)算法的更多相关文章
- 虚拟DOM与DOM diff算法
虚拟DOM是什么? 一个虚拟DOM(元素)是一个一般的js对象, 准确的说是一个对象树(倒立的) 虚拟DOM保存了真实DOM的层次关系和一些基本属性,与真实DOM一一对应,如果只是更新虚拟DOM, 页 ...
- bsdiff差分算法
bsdiff的基本原理 bsdiff是由Conlin Percival开源的一个优秀的差分算法,而且是跨平台的.在Android系统中所使用的imgdiff本质上就是bsdiff. bsdiff的依据 ...
- 深入Vue2.x的虚拟DOM diff原理
一.前言 Vue的核心是双向绑定和虚拟DOM(下文我们简称为vdom),关于双向绑定可以参阅木琴的文章<剖析Vue原理&实现双向绑定MVVM>,vdom是树状结构,其节点为vnod ...
- 最近发现了一篇讲解Vue的虚拟DOM,diff很棒的文章,特定记录转载一下
本文章是转载的,为了方便以后复习,特地记录一下.他人请去原地址观看!!! 文章原地址:https://blog.csdn.net/m6i37jk/article/details/78140159 作者 ...
- 七天接手react项目 —— 生命周期&受控和非受控组件&Dom 元素&Diffing 算法
生命周期&受控和非受控组件&Dom 元素&Diffing 算法 生命周期 首先回忆一下 vue 中的生命周期: vue 对外提供了生命周期的钩子函数,允许我们在 vue 的各个 ...
- 虚拟 DOM 与 DOM Diff
虚拟 DOM 与 DOM Diff 本文写于 2020 年 9 月 12 日 虚拟 DOM 在今天已经是前端离不开的东西了,因为他的好处实在是太多了. 在<高性能 JavaScript>一 ...
- Myers差分算法的理解、实现、可视化
作者:Oto_G QQ: 421739728 目录 简介 基础 差异的描述 好的差异比较 算法介绍 名词解释 两个定理 绘制编辑图 感谢 简介 本文章对Myers差分算法(Myers Diff Alg ...
- 洛谷 [USACO17OPEN]Bovine Genomics G奶牛基因组(金) ———— 1道骗人的二分+trie树(其实是差分算法)
题目 :Bovine Genomics G奶牛基因组 传送门: 洛谷P3667 题目描述 Farmer John owns NN cows with spots and NN cows without ...
- 【matlab】运动目标检测之"背景差分算法“
clear; clc; i1=imread('D:\Work\1.png'); i2=imread('D:\Work\2.png'); i1=rgb2gray(i1); i2=rgb2gray(i2) ...
随机推荐
- 从零开始学Flask框架-003
index.py from flask import Flask,render_template from flask_bootstrap import Bootstrap #初始化 app = Fl ...
- C++打印水仙花数
#include <iostream> #include <Windows.h> using namespace std; int main(void) { int a, b, ...
- docker 实践七:docker-machine
本篇是关于 docker 三剑客中的 docker machine. 注:环境为 CentOS7,docker 19.03. docker-machine 是 docker 官方三剑客项目之一,它是一 ...
- Jackson之LocalDateTime转换,无需改实体类
[问题] Demo: LocalDateTime dt = LocalDateTime.now(); ObjectMapper mapper = new ObjectMapper(); try { S ...
- hoj 棋盘问题 状压入个门
大概题意是:有一个n*m的棋盘,在这个棋盘里边放k个旗子,要求每一行每一列都不能存在一对旗子相邻,问最后总共的方案数. 我们先来考虑个简单的,假如说只有一行,要求在这一行里边填充k个旗子,要求任意两个 ...
- Java单例最好的设计模式:Spring 之 GlobalAdvisorAdapterRegistry
先上代码: public abstract class GlobalAdvisorAdapterRegistry { /** * Keep track of a single instance so ...
- 实现CodeFirst自动数据迁移无需手动执行命令
本主题假设您掌握了实体框架中 Code First 迁移的基本知识. 借助自动迁移功能,您无需对您所做的每一个更改都在程序包管理器控制台中手动Update-Database . 启用迁移 只需执行一次 ...
- 编写Postgres扩展之二:类型和运算符
原文:http://big-elephants.com/2015-10/writing-postgres-extensions-part-ii/ 编译:Tacey Wong 在上一篇关于编写Postg ...
- mysql把A表数据插入到B表数据的几种方法
web开发中,我们经常需要将一个表的数据插入到另外一个表,有时还需要指定导入字段,设置只需要导入目标表中不存在的记录,虽然这些都可以在程序中拆分成简单sql来实现,但是用一个sql的话,会节省大量代码 ...
- SQL SERVER-Job中Operators搬迁脚本
选中operators按F7,然后选中对象,生成脚本 USE [msdb] GO /****** Object: Operator [DB_ITDESK] Script Date: 5/30/2019 ...