虚拟DOM

作者: bansers | 来源:发表于2020-04-03 17:05 被阅读0次
    真实DOM解析流程

    浏览器渲染的过程主要包括以下五步:

    浏览器获取到 HTML 文档并解析 DOM 树
    • 解析 CSS 构建层叠样式表模型CSSOM(CSS Object Model)
    • 将 DOM Tree 和 CSSOM 合并成一个 Render Tree
    • 有了Render Tree,浏览器便能获取到每个节点的 CSS 定义和从属关系,从而可以计算出每个节点的现实位置
    • 通过上一步的计算规则进行绘制页面
    image.png
    虚拟DOM产生的背景

    用原生 js 或 jquery 去操作 DOM 时,浏览器会从构建 DOM 树到绘制全部执行一遍。
    当我们频繁操作 DOM 的时候,浏览器并不知道下一次操作 DOM 是什么时候,所以每次 DOM 有更新的时候,浏览器都会执行一遍上面的流程,比如计算 DOM 坐标值时可能就会大量的浪费性能,在计算完这次的坐标的时候,紧接着 DOM 的位置又发生变化,又要重新计算,前一次计算所消耗的性能就白白浪费了,操作太频繁的话还会造成页面卡顿。虚拟 DOM 的出现就是为了解决这个问题。

    虚拟DOM原理

    虚拟DOM就是利用js运行速度快的这一优点对操作DOM进行优化的,用js模拟DOM树,在js中处理DOM的操作再渲染,简单概括分为以下三点:

    • 用javascript对象模拟DOM树并且渲染DOM树;
    • 通过 diff算法 比较新旧DOM树,得到差异的对象;
    • 将差异的对象应用到渲染的DOM树中。

    真实DOM:

    <div id="app">
        哈哈
        <p>123</p>
    </div>
    

    虚拟DOM:

    var vNode = {
        tag: 'div',
        props: {id: 'app'},
        children: [
            {
                tag: 'p',
                props: {},
                children: [],
                context: '123'
            }
        ],
        context: '哈哈'
    }
    

    虚拟DOM实现:

    function createComponent(tag) {
        let child = [];
        for(let i = 0; i < tag.children.length; i++) {
            if(tag.children[i].children.length <= 0) {
                child[i] = {
                    tag: tag.children[i].nodeName.toLowerCase(), 
                    props: tag.children[i].attributes, 
                    context: tag.children[i].innerText,
                    children: []
                };
            } else {
                child[i] = createComponent(tag.children[i]);
            }
        }
        let vNode = {
            tag: tag.nodeName.toLowerCase(), 
            props: tag.attributes, 
            children: child,
            context: tag.childNodes[0].nodeValue
        }
        return vNode;
    }
    

    相关文章

      网友评论

          本文标题:虚拟DOM

          本文链接:https://www.haomeiwen.com/subject/celkphtx.html