Virtual DOM 详解

内容提要

  • 虚拟DOM是什么
  • 为什么需要虚拟DOM
  • jsx语法糖,实现虚拟DOM
  • Diff算法
  • render 成真实DOM

一、虚拟DOM是什么

vdom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息,例如:
<button class="btn btn-blue">
    <em>Confirm</em>
</button>
复制代码

上边的DOM结构,都在下面的树结构里面

{
    type: 'button',
    props: {
        className: 'btn btn-blue',
        chidren: [
            {
                type: 'em',
                props: {
                    chidren: 'Confirm'
                }
            }
        ]
    }
}
复制代码

二、为什么需要虚拟DOM

这个得从浏览器渲染一个html 文件需要做哪些事说起

这里主要说明浏览器渲染的过程,包括5步
  1. 浏览器将获取的html文档解析成DOM树
  2. 处理css,构成层叠样式表模型CSSOM(CSS Object Model)
  3. 将上面的DOM树和样式表,关联起来,构建一颗Render树。这一过程又称为Attachment。每个DOM节点都有attach方法,接受样式信息,返回一个render对象(又名renderer)。这些render对象最终会被构建成一颗Render树。
  4. 渲染树的每个元素包含的内容都是计算过的,它被称之为布局layout。浏览器使用一种流式处理的方法,只需要一次pass绘制操作就可以布局所有的元素。
  5. 将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting.

当你用传统的源生api或jQuery去操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程。比如当你在一次操作时,需要更新10个DOM节点,理想状态是一次性构建完DOM树,再执行后续操作。但浏览器没这么智能,收到第一个更新DOM请求后,并不知道后续还有9次更新操作,因此会马上执行流程,最终执行10次流程。显然例如计算DOM节点的坐标值等都是白白浪费性能,可能这次计算完,紧接着的下一个DOM更新请求,这个节点的坐标值就变了,前面的一次计算是无用功。

虚拟DOM就是为了解决这个浏览器性能问题而被设计出来的。例如前面的例子,假如一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attach到DOM树上,通知浏览器去执行绘制工作,这样可以避免大量的无谓的计算量。

三、jsx语法糖,实现虚拟DOM

有 JSX 的地方,在文件开头就需要引入 React,因为实际上 JSX 是使用了 React.createElement,JSX 只是一个JS 的语法糖,所以需要引入 React 包,否则会报错。
// 方法3:JSX
import React from 'react';
import ReactDOM from 'react-dom';
const title = (
  <h1>Hello React (method 3)</h1>
);
ReactDOM.render(title, document.getElementById('root'));
复制代码

这段jsx代码,实际是 React.createElement 创建一个 React DOM 对象,完全等同于下面这行代码。

const title = React.createElement("h1", {className: "main"}, "Hello React (method 3)");
复制代码

四、Diff算法

缘由:计算一颗树形结构转换成另外一颗树形结构的最少操作

传统 diff 算法通过循环递归对节点进行依次对比,效率低下,算法复杂度达到 O(n^3),其中 n 是树中节点的总数。O(n^3) 到底有多可怕,这意味着如果要展示1000个节点,就要依次执行上十亿次的比较。代价太高。

React diff优化

转载于:https://juejin.im/post/5d1b1548f265da1bcc195bb1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值