virtual dom的理解

本文主要是自己对https://www.zhihu.com/question/31809713一贴中各位大神分享的学习记录,不一定对,希望通过不断学习加深理解。

问题:为什么需要virtual dom?

先的说说virtual dom 是什么,virtual dom就是原生dom在内存中的js对象映射,但不是完全复制,它比真实dom节点在属性上简化了,也就是说是更加轻量级,相当于是数据和原生dom的一层缓存。

在司徒正美的回复中有例子。这里就不罗列了。

之前一直有一种说法,说是virtual dom操作比原生dom快。

先说原生dom,dom发生变化后,就需要重新布局,绘制,渲染等等,一般说的原生dom慢,主要是说重新渲染,绘制的消耗。

对于初始渲染,其实没有大的差别,毕竟virtual dom最终也是要渲染成原生dom的。主要的差异体现在后续的变更上。

我们可以比较一下 innerHTML vs. Virtual DOM 的重绘性能消耗:

innerHTML:  render html string O(template size) + 重新创建所有 DOM 元素 
O(DOM size)

Virtual DOM: render Virtual DOM + diff O(template size) + 必要的 DOM 更新 O(DOM change)。

但是如上面讲到的,主要的消耗在dom的重绘,渲染,相比之下js diff的计算,虽然会耗一部分时间,但是其整体占比不多,因此也还不错。像react还提供了shouldComponentUpdate用来优化这种场景,因此可以说使用了Virtual DOM,在大部分场景下性能还是可以接受的。

“可以看到,innerHTML 的总计算量不管是 js 计算还是 DOM 操作都是和整个界 面的大小相关,但 Virtual DOM 的计算量里面,只有 js 计算和界面大小相关,DOM 操作是和数据的变动量相关的。前面说了,和 DOM 操作比起来,js 计算是极其便宜的。这才是为什么要有 Virtual DOM:它保证了 1)不管你的数据变化多少,每次重绘的性能都可以接受;2) 你依然可以用类似 innerHTML 的思路去写你的应用”

Virtual DOM和MVVM

相比起 React,其他 MVVM 系框架比如 Angular, Knockout 以及 Vue、Avalon 采用的都是数据绑定:通过 Directive/Binding 对象,观察数据变化并保留对实际 DOM 元素的引用,当有数据变化时进行对应的操作。MVVM 的变化检查是数据层面的,而 React 的检查是 DOM 结构层面的。

MVVM 实现的一个共同问题就是在列表渲染的数据源变动时,尤其是当数据是全新的对象时,如何有效地复用已经创建的 ViewModel 实例和 DOM 元素。假如没有任何复用方面的优化,由于数据是 “全新” 的,MVVM 实际上需要销毁之前的所有实例,重新创建所有实例,最后再进行一次渲染!这就是为什么题目里链接的 angular/knockout 实现都相对比较慢。相比之下,React 的变动检查由于是 DOM 结构层面的,即使是全新的数据,只要最后渲染结果没变,那么就不需要做无用功。 Angular 和 Vue 用了 track by $index 用来优化这种场景。

性能

Virtual DOM从来都不是单独存在的。Virtual DOM、脏检查 MVVM、数据收集 MVVM 在不同场合各有不同的表现和不同的优化需求。Virtual DOM 为了提升小量数据更新时的性能,也需要针对性的优化,比如 shouldComponentUpdate 或是 immutable data。

  • 初始渲染:Virtual DOM > 脏检查 >= 依赖收集

  • 小量数据更新:依赖收集 >> Virtual DOM + 优化 > 脏检查(无法优化) > Virtual DOM无优化

  • 大量数据更新:脏检查 + 优化 >= 依赖收集 + 优化 > Virtual DOM(无法/无需优化)>> MVVM 无优化。

其实如果一定要说这个为什么? 那就是Virtaul DOM是作为一定场景下,解决性能问题提出来的解决方案。

他山之石

虚拟DOM快在哪里

然后,js计算肯定要比DOM操作快啊,每次DOM操作都很有可能引起回流(Reflow)和重绘(Repaint)啊。当然浏览器也不傻,不是你每次操作DOM浏览器都重绘一次,一般浏览器会按照时间或次数间隔进行DOM操作的批处理。那问题来了,到底是浏览器优化后的DOM批处理快,还是React的虚拟DOM+优化diff算法快。这个我没有测试过,根据博客上内容,React的优化更人性化、也更快。速度快肯定是虚拟DOM的一个优点,另外一点,浏览器对DOM操作批处理的主动权不在前端人员手中,React将这种批处理的时机选择交到了我们手中,看我们什么时候想render页面。这个和AJAX+回调带来的问题一样,当我们发送一个AJAX,然后指定一个回调函数时候,对回调里代码的控制权就交给浏览器了,所以前端人员常常感觉AJAX不可控,不知道回调什么时候执行完了,页面一大堆flag。
https://blog.csdn.net/qiqingjin/article/details/51804138

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容