精华内容
下载资源
问答
  • 虚拟DOM和diff算法

    2019-07-29 21:18:10
    文章目录虚拟DOM和diff算法什么叫虚拟DOM传统DOM和虚拟DOM操作的区别简单的dufffetch模拟数据实现方式?深入响应式原理 【 数据驱动原理/ 双向数据绑定原理 】 虚拟DOM和diff算法 什么叫虚拟DOM 虚拟DOM是在DOM的...

    虚拟DOM和diff算法

    什么叫虚拟DOM

    虚拟DOM是在DOM的基础上在内存建立了一个抽象层,对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到DOM中

    传统DOM和虚拟DOM操作的区别

    【传统DOM操作(例如:innerHtml)】:render html => 重建所有DOM元素
    传统DOM操作(例如:innerHtml)通过重建所有DOM元素
    【虚拟DOM】:render 虚拟DOM + diff算法 => 更新必要的DOM元素
    虚拟DOM + diff算法 是 更新必要的DOM元素

    虚拟DOM因为是纯粹的JS对象,所以操作它会很高效,但是虚拟DOM的变更最终会转换成DOM操作,为了实现高效的DOM操作,一套高效的虚拟DOM diff算法显得很有必要。

    在这里插入图片描述

    简单的duff

    简单的diff算法可以这样设计:
            1. 逐个遍历DOM树的所有节点,找到它在原始DOM树中的位置
            2. 找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。
            3. 遍历完成之后如果原始DOM树中还有没处理过的节点,则说明这些节点在新DOM树中被删除了,删除它们即可。
    

    *仔细思考一下,几乎每一步都要做移动DOM的操作,这在DOM整体结构变化不大时的开销是很大的,实际上DOM变化不大的情况现实中经常发生,很多时候我们只需要变更某个节点的文本而已。

    1. 验证: axios它底层封装的Promise?
    2. axios使用方式?
    3. axios会将我们请求的来的数据进行一层封装
    4. axios提供的官网文档有些问题

    fetch

    1. fetch是原生javascript提供的,我们可以直接向全局变量一样使用

    2. fetch也是Promise

    3. fetch返回的结果是没有进行封装的,是直接暴露的

    4. fetch数据格式化的方式有哪些/

      • json()
      • text()
      • blob() 格式化二进制 【 视频 图像 音频 】
    5. post请求有坑

    6. 总结:

      • axios vs fetch post请求都是有一些问题的
      • 处理方式:
          1. 先设置请求头
          1. 通过 new URLSearchParams来进行传参

    模拟数据实现方式?

    1. 为什么要写模拟假数据?
      • 前后端分离, 前后端同步开发,接口时没有的
      • 模拟假数据的字段一定要和后端沟通好
    2. mock.js生成 http://mockjs.com/
      • 使用经验:
        • 我们使用的时候,找案例,找和我们字段结构相近的,然后复制语法,然后对应修改
    3. 拷贝线上相近的json
      • 浏览器开发者工具/ netWork / XHR / copy response
    4. easy mock https://easy-mock.com/login

    深入响应式原理 【 数据驱动原理/ 双向数据绑定原理 】

    1. 深入响应式原理
      • 数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新
    2. 数据驱动
      • 数据改变,视图改变
    3. 双向数据绑定原理
      • 我们使用v-model这个指令来实现,数据改变,视图改变,视图改变,数据也随之改变

    公共答案:

    vue是通过数据劫持和订阅发布来进行深入响应的,数据劫持指的是,vue通过es5的Object.defineProperty属性对data选项中的数据进行getter和setter设置,订阅发布指的是vue通过之定义自定义事件将data的变化反映到视图上去,vue通过observer观察者对象反应数据的变化,然后通知vue生成新的Virtual DOM ,进而渲染视图

    关键词:

    数据劫持
    
    订阅发布
    
    es5   Object.defineProperty  getter  setter
    
    observer对象
    
      将data选项中的数据全部做一遍getter和setter设置,然后他们的变化就会被observer监听到
    
    Vue3.0会将 es5的Object.defineProperty 改用 es6/7 的observer 
    
    展开全文
  • 虚拟Dom和Diff算法

    2020-03-24 22:35:47
    虚拟Dom和Diff算法 首先,我们需要了解什么是虚拟Dom,又为什么需要虚拟Dom虚拟Dom即Virtual Dom,他是用JS对象记录一个Dom节点的副本,当Dom发生更改时候,先用虚拟Dom进行Diff,算出最小差异,然后再修改真实Dom...

    虚拟Dom和Diff算法

    首先,我们需要了解什么是虚拟Dom,又为什么需要虚拟Dom。虚拟Dom即Virtual Dom,他是用JS对象记录一个Dom节点的副本,当Dom发生更改时候,先用虚拟Dom进行Diff,算出最小差异,然后再修改真实Dom。我们之所以是使用Dom必定是因为他存在一定的优点,在我们用传统的方式操作Dom的时候,我们的浏览器会从构建DOM树开始从头到尾执行一遍过程,效率较低。

    	<ul id="aa">
    		<li class="a1">我是li1</li>
    		<li class="a2">我是li2</li>
    		<li class="a3">我是li3</li>
    	</ul>
    

    以上面代码为例,按照传统的方式操作Dom我们就需要使用

    	var a = document.createElement('li')
    	document.querySelector('#aa').appendChild(a)
    

    在js里面输入上面两行代码就会在我们的ul里面追加一个li标签,但是在我们的开发过程中对节点的操作并不少,因此大批量的数据更新会导致浏览器的运行速度减慢,这是使用传统方式的一个弊端,面对这种情况,我们的Vue提供了虚拟Dom。
    虚拟Dom就是在我们遇到了数据较大、复杂文档的Dom结构,提供了一种便捷的工具。简单的说,就是我们的虚拟Dom工具的任务就是将虚拟的Dom转换成真是的Dom,当我们的数据发生改变的时候或者页面需要进行重新渲染的时候,会生成一个新的虚拟Dom,使用我们的diff算法,拿我们的新的虚拟Dom和旧的虚拟Dom做对比,找到不一样的地方,将需要更新的地方直接更新,没有更改的地方就无须进行操作。这样我们就可以大量减少真实的Dom操作,提高性能。
    下面将通过以下代码来大致了解以下Vue的虚拟Dom:

    	<div id="app">
            <my-component></my-component>
        </div>
    
        <template id="my-component">
            <div id = "vd">
                <ul>您好</ul>
                <ol class = "ol"></ol>
            </div>
        </template>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <script>
    
            
            // 1.首先,我们需要内存中生成一个虚拟Dom树
            //这是他的内部操作
            // var vD = {
            //     // 标签
            //     tag:"div",
            //     attr:{
            //         id:"vd"
            //     },
            //     children:[
            //         {tag:"ul",content:"你好"},
            //         {tag:"ol",attrs:{className:"ol"}}
            //     ]
            // }
    
    
            // 其次,我们将内存中的虚拟dom树初始化渲染成真实dom树
            Vue.component('my-component', {
                template:"#my-component",
                // functional: true,
                // Props 是可选的
                props: {
                // ...
            },
            // 为了弥补缺少的实例
            // 提供第二个参数作为上下文
            })
    		// var data = {
    		//	arr:[]
    		// }
    
            // 当需要追加一条数据的时候
            // data.arr.push('<li>我是新加进去的</li>')
    
    
            // 再将之前的虚拟Dom结合新的数据渲染成一个新的虚拟Dom
            //var newD = {
                // 标签
            //    tag:"div",
            //    attr:{
            //        id:"vd"
            //    },
            //    children:[
            //       {tag:"ul",content:"你好"},
            //       {tag:"ol",attrs:{className:"ol"},children:[
            //           {tag:"li",content:"我是新加进去的"}
            //      ]}
            //   ]
            //  }
    
            // 使用Diff算法将新生成的Dom树与之前的Dom数进行比较,将对比之后不同的数据进行真实Dom的数据渲染
    		
    		//实例化对象
            new Vue({
                el:"#app",
                data:{
                }
            })
    

    以上就是我们的虚拟Dom转换成真实的Dom,其实他的渲染在内部是依靠一个叫做render的函数,具体参照文档render
    当我们说到虚拟Dom的时候,我们知道我们的新旧Dom树是依靠Diff算法进行对比的,那么什么是Diff算法,他为什么会有这样的功能呢?
    Diff算法的作用是用来计算出 Virtual DOM 中被改变的部分,然后针对该部分进行原生DOM操作,而不用重新渲染整个页面。下图是我们的diff算法的对比过程:
    diff算法
    对比之后将我们的真实Dom渲染在页面上。上图是数据层面的比较,但是当我们的数据结构发生变化的时候,我们需要对它一层一层的进行比较,这个时候我们需要给一个key值,就像我们在电影院买票一样,每张票对应了一个座位,即使我们没有没人来的早,但是那个位置是在我的电影票生效的时候是属于我自己的,当我们需要在同级的结构下面操作,就需要用到key,这样不会取代别的结构的位置。
    diff
    上图就是将我们的F插入到B和C之间。
    我们内部当数据变化,生成一颗新的虚拟dom树,与上一次的虚拟dom树结构进行对比。也就是说,当数据变化的时候,大量操作的是虚拟dom,而虚拟dom属于内存数据,操作起来性能要高的多。而真实的dom操作,只有在追加的那一刻才会进行操作,大大提升了性能。

    展开全文
  • 虚拟DOM Diff 算法

    2019-05-28 19:55:18
    虚拟DOM Diff 算法 什么是虚拟DOM? vdom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息 var vdom1 = { tag: 'DIV', attr: { className: 'box' }, children: ...

    虚拟DOM 和 Diff 算法

    1. 什么是虚拟DOM?
    • vdom可以看作是一个使用javascript模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息
    var vdom1 = {
            tag: 'DIV',
            attr: {
                className: 'box'
            },
            children: [{
                tag: 'UL',
                children: [{
                    tag: 'LI',
                    content: '1',
                    attr: {
                        className: 'item'
                    }
                }, {
                    tag: 'LI',
                    content: '1',
                    attr: {
                        className: 'item'
                    }
                }, {
                    tag: 'LI',
                    content: '1',
                    attr: {
                        className: 'item'
                    }
                }]
            }]
        }
    
    1. 使用虚拟DOM有什么好处?

      • 越多的真实dom操作,越损耗性能

      • 操作数据要大大的减少性能损耗,提高渲染效率

    2. 什么是Diff 算法?

      1. diff算法是比较两个文件的差异,并将两个文件不同之处,将这个不同之处生成一个补丁对象(patch)
      2. diff算法来源后端
      3. 前端将其应用于虚拟dom的diff算法
      4. vue中将 虚拟dom的diff算法放在了 patch.js文件中
      5. 使用js来进行两个对象的比较( vdom 对象模型)
      6. diff算法是同级比较
      7. 给每一个层级打一个标记,这个标记是一个数字( 这个数字就是 key )
    3. diff算法是用来做什么的?

    ** Vue 2.x版本使用的就是 VDOM ( 虚拟DOM ) **

    • VDOM的渲染流程

      1. 获取数据
      2. 根据数据创建VDOM (相当于给对象赋值)
      3. 根据VDOM渲染生成真实DOM ( 根据createElmeent(‘DIV’) )
      4. 当数据发生改变后,又会生成新的VDOM
      5. 通过 diff 算法 比对 多次生成的 VDOM, 将不同的内容比对出来,然后在进行真实DOM渲染,
        一样的内容是不会进行渲染的,这就是VDOM 的 ‘就地复用’ | ‘惰性原则’
    1. jsx 在vue采用的原因

      VDOM对象树态繁琐了, 如果能像hom结构一样书写就好了, 这就引入了 jsx

    2. render函数是做什么的

      但是jsx始终还是不能直接去用的,必须转换成 对象 才能使用,
      vue中 使用render 函数 解析jsx语法, 然后换成 对象结构 ,在通过 createElment 生成节点,渲染成
      真实DOM

    展开全文
  • 虚拟dom和diff算法

    2020-11-02 14:58:15
    虚拟DOMdiff算法 什么是虚拟dom react元素就是一个虚拟dom 小结: 直接操作dom元素,效率远远低于操作数据(虚拟dom) react中创建出来的元素,其实不是真实的dom元素,是虚拟dom react如何渲染视图层: 根据之前的结构,...

    虚拟DOM的diff算法

    什么是虚拟dom

    react元素就是一个虚拟dom

    小结:

    直接操作dom元素,效率远远低于操作数据(虚拟dom)

    react中创建出来的元素,其实不是真实的dom元素,是虚拟dom

    react如何渲染视图层: 根据之前的结构,生成一个旧的虚拟dom. 然后代码发生变化,也就意味着新的虚拟dom结构发生变化.这个时候react底层会比较这两个虚拟dom结构.然后根据比较的结构,修改真实的dom.真实dom被修改了,视图就会跟着发生变化

    什么是diff算法

    一种对比新/旧虚拟DOM树的高效算法,能快速计算哪些虚拟DOM树发生了变化,从而只更新局部DOM。

    传统的 diff 算法性能开销大,无法满足大规模 DOM 操作需求。 React 通过制定大胆的策略,将性能开销降到最低。

    diff 策略

    1. Web UI 中 DOM 节点跨层级的移动操作特别少,可以忽略不计。
    2. 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。
    3. 对于同一层级的一组子节点,它们可以通过唯一 id 进行区分。

    基于以上三个前提策略,React 分别对 tree diff、component diff 以及 element diff 进行算法优化,事实也证明这三个前提策略是合理且准确的,它保证了整体界面构建的性能。

    tree diff

    基于策略一,React 对树的算法进行了简洁明了的优化,即对树进行分层比较,两棵树只会对同一层次的节点进行比较。

    既然 DOM 节点跨层级的移动操作少到可以忽略不计,针对这一现象,只会对相同颜色方框内的 DOM 节点进行比较,即同一个父节点下的所有子节点。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。

    问题:如果出现了 DOM 节点跨层级的移动操作,性能不好!

    如上图所示:React diff 的执行情况:create A -> create B -> create C -> delete A

    由此可发现,当出现节点跨层级移动时,并不会出现想象中的移动操作,而是以 A 为根节点的树被整个重新创建,这是一种影响 React 性能的操作,因此 React 官方建议不要进行 DOM 节点跨层级的操作。

    注意:在开发组件时,保持稳定的 DOM 结构会有助于性能的提升。例如,可以通过 CSS 隐藏或显示节点,而不是真的移除或添加 DOM 节点。

    component diff

    React 是基于组件构建应用的,对于组件间的比较所采取的策略也是简洁高效。

    • 如果是同一类型的组件,按照原策略继续tree diff。
    • 如果不是,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点。
    • 对于同一类型的组件,有可能其 Virtual DOM 没有任何变化,如果能够确切的知道这点那可以节省大量的 diff 运算时间,因此 React 允许用户通过 shouldComponentUpdate() 来判断该组件是否需要进行 diff。

    element diff

    如下图,老集合中包含节点:A、B、C、D,更新后的新集合中包含节点:B、A、D、C,此时新老集合进行 diff 差异化对比,发现 B != A,则创建并插入 B 至新集合,删除老集合 A;以此类推,创建并插入 A、D 和 C,删除 B、C 和 D。

    React 发现这类操作繁琐冗余,因为这些都是相同的节点,但由于位置发生变化,导致需要进行繁杂低效的删除、创建操作,其实只要对这些节点进行位置移动即可。

    针对这一现象,React 提出优化策略:允许开发者对同一层级的同组子节点,添加唯一 key 进行区分,虽然只是小小的改动,性能上却发生了翻天覆地的变化!

    新老集合所包含的节点,如下图所示,新老集合进行 diff 差异化对比,通过 key 发现新老集合中的节点都是相同的节点,因此无需进行节点删除和创建,只需要将老集合中节点的位置进行移动,更新为新集合中节点的位置,此时 React 给出的 diff 结果为:B、D 不做任何操作,A、C 进行移动操作,即可。

    问题:如下图所示,若新集合的节点更新为:D、A、B、C,与老集合对比只有 D 节点移动,而 A、B、C 仍然保持原有的顺序,理论上 diff 应该只需对 D 执行移动操作,然而由于 D 在老集合的位置是最大的,造成 D 没有执行移动操作,而是 A、B、C 全部移动到 D 节点后面的现象。

    建议:在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响 React 的渲染性能。

    总结

    • React 通过分层求异的策略,对 tree diff 进行算法优化;
    • React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略,对 component diff 进行算法优化;
    • React 通过设置唯一 key的策略,对 element diff 进行算法优化;
    • 建议,在开发组件时,保持稳定的 DOM 结构会有助于性能的提升;
    • 建议,在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响 React 的渲染性能。
    展开全文
  • 虚拟DOM和Diff算法

    2018-12-16 22:00:54
    虚拟DOM 虚拟DOM其实就是在真实DOM之前加了一层JS对象生成的DOM 用JS对象模拟DOM ... diff算法 Diff 比较两个虚拟DOM的区别(比较两个对象的区别) 根据两个虚拟对象的区别,创建出补丁(patch...
  • 虚拟DOM和 Diff算法

    2020-09-21 09:16:57
    虚拟DOM 1、用js来模拟DOM中的节点。...5、将数据变化后的虚拟dom 之前的虚拟dom 通过differ 算法 进行比对 6、比对之后更新视图 一样的不变 不一样重新渲染 <!DOCTYPE html> <html lang="en"
  • 虚拟DOM和DIFF算法

    2021-03-29 17:53:42
    认识虚拟DOM 虚拟DOM不是真实的DOM,而是一个JS对象。 它的作用是判断DOM是否改变、哪些部分需要被重新渲染,配合DIFF算法使用 DIFF算法 diff 算法的本质:找出两个对象之间的差异,然后针对该部分进行原生DOM操作...
  • 虚拟Dom和diff算法

    2021-01-14 13:53:17
    虚拟Dom 概念:虚拟Dom本质就是js对象,用js来模拟DOM中的节点。一个能代表dom树的对象,...虚拟dom借助Dom diff 可以吧多余的操作省掉,比如添加1000个节点,只有10个是新增的(检测原有的就添加没有的10个) 2.跨平

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,075
精华内容 3,630
关键字:

虚拟dom和diff算法