美文网首页Web前端之路
深入了解虚拟DOM

深入了解虚拟DOM

作者: 尤小小 | 来源:发表于2019-06-19 11:43 被阅读4次

    如果让我们自己开发一个视图框架

    1. state 数据
    2. render 模版
    3. 数据 + 模版 = 生成DOM结构 (Modle + View = DOM
    4. 当数据更新了,生成新的DOM结构
    5. 然后新DOM结构 替换老的DOM结构 (特别消耗性能)

    将处理升级:

    1. state 数据
    2. render 模版
    3. 数据 + 模版 = 生成DOM结构 (Modle + View = DOM
    4. 当数据更新,生成新的DOM结构
    5. 比较新旧DOM结构差异 (input数据更新了)(DOM结构的比较diff 也很消耗性能)
    6. 然后将差异部分 替换成新的DOM结构

    上面的方法虽然改进了,不直接替换DOM少消耗性能了,但是新旧DOM结构的比较也很消耗性能。

    再次升级为虚拟DOM的处理:

    1. state 数据
    2. render 模版
    3. 数据 + 模版 = 生成DOM结构 (Modle + View = DOM
    4. 同时 生成 虚拟DOM 结构 (虽然生成虚拟DOM结构也消耗性能,但是用js生成一个js对象跟生成DOM结构相比,还是节省性能的)
    5. 当数据更新了,生产新的虚拟DOM结构 (也很快)
    6. 然后新旧虚拟DOM结构进行差异比较 (两个js对象或者数据比较 性能比 两个DOM结构比较高的多)
    7. 然后将差异部分进行替换

    其实虚拟DOM就是 一个大的js对象或者数组。用js生成一个js对或者,进行两个对象的比较。要比生成一个DOM对象,进行两个DOM结构的比较性能要好的多 。

    实际上react的实现:(3,4步是颠倒的)

    1. state 数据
    2. render 模版
    3. 数据 + 模版 = 生成 虚拟DOM 结构
    4. 虚拟DOM对象 生成真实的DOM (Modle + View = DOM
    5. 当state数据更新了
    6. 数据 + 模版 = 生成新的虚拟DOM结构 (极大地提升了性能)
    7. 然后新旧虚拟DOM结构进行差异比较 (两个js对象或者数据比较 性能比 两个DOM结构比较高的多)
    8. 然后将差异部分进行替换 操作DOM
    render () {
        // JSX 语法 -> creactElement -> 虚拟DOM(js对象) -> 真实的DOM 
        return <div><span>item</span></div>
        return React.creactElement('div', {}, React.creactElement('span', {}, 'item'))
    }
    

    虚拟DOM的优点:

    1. 性能提升了
    2. 它使的跨端应用得以实现 React Native (js对象在网页、原生应用也可以识别)

    虚拟DOM中的diff算法
    第7步 两个虚拟DOM的比对就叫做 diffrence 找步同

    思考:什么情况下会进行虚拟DOM的比对,🤔

    1. 数据更新了(state, props)
    2. 副组件的render执行了,子组件的render也执行

    setState是异步的

    为什么是异步的呢,是为了提升react底层的性能
    比如说我们进行了三次setState的调用,这三次调用的间隔特别小,react会进行三次数据的更新 ,执行三次render吗? 实际上react只执行了一次render

    diff算法 - 同层比对

    两个虚拟DOM在进行比对的时候,它会进行同层比对,假设第一层 一致 再比对第二层,如果第一层就更新了,下面就不会在比了,整个进行新虚拟DOM转化为真实DOM,
    可能会造成DOM的性能消耗。

    diff算法 - key比对 (为什么模版遍历需要加key值)

    without keys
    有这样一个数组['item', 'item', 'item', 'item'],生成的DOM, 再没有key的时候两个虚拟DOM进行比较,可能要进行两成循环遍历,比较麻烦,也比较消耗性能。

    with keys
    如果每个元素上有key值,在进行虚拟DOM比较的时候,会和key值像关联,快速比对,就很容易知道 添加了什么,删除了什么。

    在循环遍历的时候最好key值不要是index,能不用index做key, 就不要用index做key值。因为index的key值是不稳定的。
    0 - a
    1 - b
    2 - c

    现在把a删掉,此时
    0 - b,
    1 - c
    两个虚拟DOM在进行比对,这样的话,用index就失去了意义了。

    相关文章

      网友评论

        本文标题:深入了解虚拟DOM

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