React 虚拟 DOM 的差异检测机制
|
React 使用虚拟 DOM 将计算好之后的更新发送到真实的 DOM 树上,减少了频繁操作真实 DOM 的时间消耗,但将成本转移到了 JavaScript 中,因为要计算新旧 DOM 树的差异嘛。所以这个计算差异的算法是否高效,就很关键了。React 中其计算差异的过程叫 Reconciliation,可理解成调和前后两次渲染的差异。 正式讨论前,先来看个问题。 问题假设我们有一个展示百分比的柱状条组件,其宽度由是传入的数值决定。并且它带动画,如果传入的值变化,那么柱状条应该由 0 动画到需要展示的宽度。 即想要实现的效果如下:
预期的百分比柱状条效果 所以我们写了如下的柱状条组件: function Bar({ score }) {
因为要实现动画,所以一开始我们并不将组件接收到的值应用到样式上,而是先将宽度设置为 0,等组件完成初始化之后,再在 调用: const data1 = [10, 20]; 实际得到的结果:
实际得到的结果 每次的动画不会从 0 开始,第二个元素根本就没有动画。通过查看打印到控制台的信息,可发现在数据发生变化后, 你可能会说,这里应该在每次渲染前,也就是 useEffect(() => {
每次动画前初始化 可以看到,并没有什么用。依然会有一个减小的动画。如果将 React 的 diff 机制对于树的差异检测,按照这个论文中描述的算法实现,其时间复杂度为 O(n3) 。而页面中 DOM 节点很容易上千,这样一次渲染需要 diff 的操作超过十亿,显然不可行。所以 React 在进行 diff 时作了两个假设前提:
基于这两点假设,在进行 diff 时可以少很多工作量,
这样假设之后,React 的 diff 算法做到了时间复杂度为 O(n)。 DOM 节点的 diff区分为节点类型变化与没变化两种情况, 对于前后再次渲染中,同一位置元素类型变化的情况,如前文所述,对该元素及其子节点整个更新。比如由 对于类型没变的情况则比较元素的属性,得出差异后只更新相应属性,比如 组件节点的 diff对于自己写的组件,类型变化时同 DOM 节点一样,将整个组件实例销毁,其中各状态将丢失,所有子节点也都销毁,这些组件的 如果该位置组件类型没变,说明只需要根据变化的 子节点的遍历及
|
React 虚拟 DOM 的差异检测机制的更多相关文章
- React虚拟DOM浅析
在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(Virtual DOM)的机制. 什 ...
- React虚拟DOM具体实现——利用节点json描述还原dom结构
前两天,帮朋友解决一个问题: ajax请求得到的数据,是一个对象数组,每个对象中,具有三个属性,parentId,id,name,然后根据这个数据生成对应的结构. 刚好最近在看React,并且了解到其 ...
- react虚拟dom diff算法
react虚拟dom:依据diff算法 前端:更新状态.更新视图:所以前端页面的性能问题主要是由Dom操作引起的,解放Dom操作复杂性 刻不容缓 因为:Dom渲染慢,而JS解析编译相对非常非常非常快! ...
- REACT——虚拟DOM
深入了解虚拟DOM 实际顺序 jsx->createElemnt ->虚拟DOM(JS 对象)->真实DOM 虚拟DOM中的Diff算法 :当react查找差异的时候,就会采用dif ...
- 关于react虚拟DOM的研究
1.传统的前端是这样的,我在学校也都是这样做的,html(jsp)主要负责提供所有的DOM节点,而javascript负责动态效果,比如按钮点击,图片轮播等,这样的话javascript如何组织结构是 ...
- react系列一,react虚拟dom如何转成真实的dom
react,想必作为前端开发一定不陌生,组件化以及虚拟dom使得react成为最受欢迎额前端框架之一.我们知道react是基于虚拟dom的,但是什么是虚拟dom呢,其实就是一组js对象,那么我们今天就 ...
- 浅谈React虚拟DOM
为什么要使用虚拟DOM 因为浏览器的DOM渲染是非常消耗性能的,很低效,我们使用虚拟DOM是为了提高DOM的渲染性能: 什么是虚拟DOM 虚拟DOM就是把真实的DOM树通过createElement转 ...
- 深入理解React虚拟DOM
一.什么是虚拟DOM 虚拟DOM可以看做一棵模拟了DOM树的JavaScript对象树.比如: var element = { element: 'ul', props: { id:"uli ...
- React/虚拟DOM
在说虚拟DOM之前,先来一个引子,从输入url到展现出整个页面都有哪些过程? 1.输入网址 2.DNS解析 3.建立tcp连接 4.客户端发送HTPP请求 5.服务器处理请求 6.服务器响应请求 7. ...
随机推荐
- linux配置https站点
配置https站点呢,那就需要https证书,证书从何而来,花钱买?no,no,no,阿里有免费的,只是比较难发现,下面就图文解说一下怎么买免费的阿里https证书 首先阿里云,登录,购买链接———— ...
- python爬虫错误总结
这几天突然想到学习爬虫,于是就从python开始,python教程瞄了两眼,就去网上找别人写的爬虫(爬音乐网站的歌曲) 磕磕绊绊中渐渐地熟悉了python中常用的库和模块. 1.python 2.x( ...
- mybatis源码解读(三)——数据源的配置
在mybatis-configuration.xml 文件中,我们进行了如下的配置: <!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境常用: ...
- ES 在聚合结果中进行过滤
ES查询中,先聚合,在聚合结果中进行过滤 { "size": 0, "aggs": { "terms": { "terms&quo ...
- html5 标签在 IE 下使用
(function(){if(!/*@cc_on!@*/0)return;var e = "abbr,article,aside,audio,bb,canvas,datagrid,datal ...
- Oracle12c中分区(Partition)新特性之TRUNCATEPARTITION和EXCHANGE PARTITION级联功能
TRUNCATE [SUB]PARTITION和EXCHANGE [SUB]PARTITION命令如今可以包括CASCADE子句,从而允许参照分区表向下级联这些操作.为确保该选项正常,相关外键也必须包 ...
- C语言 > 构造素数表
#include <stdio.h> #define NUMBER 1000 int main(){ int isPrime[NUMBER]; ; i < NUMBER; i++){ ...
- Python中的 socket示例
linux send与recv函数详解 1 #include <sys/socket.h> 2 ssize_t recv(int sockfd, void *buff, size_t ...
- linux查看系统的日志------健康检查特性
last https://www.cnblogs.com/anruy/articles/5541675.html Nginx反向代理,健康状态检测,过载保护及配置文件详 ...
- Struts2中数据封装方式
一.通过ActionContext类获取 public class ActionContextDemo extends ActionSupport { @Override public S ...




