【JS】922- Virtual DOM 认知中的一些误区

发表于 3年以前  | 总阅读数:371 次

在当下最流行的两个前端框架都存在 Virtual DOM 的前提下, 渐渐比较多的听到类似“使用 Virtual DOM 有什么优势?” 的面试题,但一直没有太在意。直到今天在写一个文档时,突让想到要把“为什么需要 Virtual DOM ?”也写进去,待我流畅的写好答案,略一思索——漏洞百出!也不知道是接纳了哪方的知识,让我一直有能轻松回答这个问题的错觉, 其实对于这个问题我是缺乏思考的。

你或许还不清楚我想说什么,但请耐下心来,先来看看网络上关于此问题的一些见解:

虚拟DOM同样也是操作DOM,为啥说它快?[1]

  1. 虚拟DOM不会进行排版与重绘操作;
  2. 虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗;
  3. 真实DOM频繁排版与重绘的效率是相当低的;
  4. 虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)。

Virtual Dom 的优势在哪里?[2]

  1. 具备跨平台的优势,由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。
  2. 操作 DOM 慢,js运行效率高。我们可以将DOM对比操作放在JS层,提高效率。因为DOM操作的执行速度远不如Javascript的运算速度快,因此,把大量的DOM操作搬运到Javascript中,运用patching算法来计算出真正需要更新的节点,最大限度地减少DOM操作,从而显著提高性能。
  3. 提升渲染性能 Virtual DOM的优势不在于单次的操作,而是在大量、频繁的数据更新下,能够对视图进行合理、高效的更新。

Virtual Dom的优势[3]

  1. 不会立即进行排版与重绘;
  2. VDOM频繁修改,一次性比较并修改真实DOM中需要修改的部分,最后在真实DOM中进行重排 重绘,减少过多DOM节点重排重绘的性能消耗;
  3. VDOM有效降低大面积真实DOM的重绘与重排,与真实DOM比较差异,进行局部渲染;

上面是从 Google 搜索到的三个平台中的分析摘选,总结下来大概四点:

  1. 操作 DOM 太慢,操作 Virtual DOM 对象快
  2. 使用 Virtual DOM 可以避免频繁操作 DOM ,能有效减少回流和重绘次数(如果有的话)
  3. 有 diff 算法,可以减少没必要的 DOM 操作
  4. 跨平台优势,只要有 JS 引擎就能运行在任何地方(Weex/SSR)

它们的理解正确吗?本文测试数据都基于 Chrome 86.0.4240.198

Virtual DOM 快?

有人认为操作 Virtual DOM 速度很快?Virtual DOM 是一个用来描述 DOM(注意,并不一定一一对应)的 Javascript 对象,Javascript 操作 Javascript 对象自然是快的。但 Virtual DOM 仍然需要调用 DOM API 去生成真实的 DOM ,而你其实是可以直接调用它们的,所有就有一个很有意思结论,正数再小也不可能比零还小——Virtual DOM 很快,但这并不是它的优势,因你本可以选择不使用 Virtual DOM 。除了速度不是优势,Virtual DOM 还有个最大的问题——额外的内存占用,以 Vue 的 Virtual DOM 对象为例,100W 个空的 Virtual DOM(Vue) 会占用 110M 内存。内存占用截图:

测试代码:

let creatVNode = function(type) {
  return {
    __v_isVNode: true,
    SKIP: true,
    type,
    props: null,
    key: null,
    ref: null,
    scopeId: 0,
    children: null,
    component: null,
    suspense: null,
    ssContent: null,
    ssFallback: null,
    dirs: null,
    transition: null,
    el: null,
    anchor: null,
    target: null,
    targetAnchor: null,
    staticCount: 0,
    shapeFlag: 0,
    patchFlag: 0,
    dynamicProps: null,
    dynamicChildren: null,
    appContext: null
  }
}

let counts = 1000000
let list = []
let start = performance.now()
// 创建 VNode(Vue)
// 10000: 1120k
for (let i = 0; i < counts; i++) {
  list.push(creatVNode('div'))
}

// 创建 DOM
// 10000: 320k
// for (let i = 0; i < counts; i++) {
//   list.push(document.createElement('div'))
// }

console.log(performance.now() - start)

_令人意外的是 100W 个空的 DOM 对象只占用 45M 内存,不清楚在 DOM 属性明显更多的情况下 Chrome 是如何优化的,或则是 Dev Tools 存在问题,希望有人能替我解惑。_你看 Virtual DOM 不但执行快没有用,还增加了大量的内存消耗,所以我们说它快自然是有问题的,因为没有 Virtual DOM 时更快。

Virtual DOM 减少回流和重绘?

也有人认为 Virtual DOM 能减少页面的 relayout 和 repaint ?通常有两个原因来支撑这个观点:

  1. DOM 操作会先改变 Virtual DOM ,所以一些无效该变(比如把文本 A 修改为 B ,然后再修改为 A)就不会调用 DOM API ,也就不会导致浏览做无效的回流和重绘。
  2. DOM 操作会先改变 Virtual DOM ,最终由 Virtual DOM 调用 patch 方法批量操作 DOM ,批量操作就不会导致过程中出现无意义的回流和重绘。

无效回流与重绘

第一个观点看着很有道理,但有个问题很难解释:浏览器的 UI 线程在什么时候去执行回流和重绘?要知道现代浏览器在设计上为了避免高复杂度,Javascript 线程和 UI 线程是互斥的,即如果浏览器要在 Javascript 执行期间触发 relayout/repaint 则必须先挂起 Javascript 线程,这是个连我都觉得蠢的设计,显然不会出现在各大浏览器身上。事实上也确实如此,无论你在一次事件循环中调用多少次的 DOM API ,浏览器也只会触发一次回流与重绘(如果需要),并且如果多次调用并没有修改 DOM 状态,那么回流与重绘一次都不会发生。Timeline 截图(没有回流和重绘发生):

测试代码:

<body>
  <div class="app"></div>
  <script> let counts = 1000
    let $app = document.querySelector('.app')
    setTimeout(() => {
      for (let i = 0; i < counts; i++) {
        $app.innerHTML = 'aaaa'
        $app.style = 'margin-top: 100px'
        $app.innerHTML = ''
        $app.style = ''
      }
    }, 1000) </script>
</body>

无意义的回流与重绘

第二个观点是比较有意思的,虽然看了上面的分析,你应该也知道它是错的,批量操作并不能减少回流与重绘,因为它们本身就只会触发一次。但我还是要列出来证明一下,因为这是我们当下众多前端的一个固有思维,我在准备写这篇文章前问了一下众神交流群的朋友们,他们几乎都掉进了这个认知陷阱中,认为批量操作会减少回流与重绘。批量操作并不能减少回流与重绘,原因也和上文一致,Javascript 是单线程且与 UI 线程互斥,所以直接放测试数据:Javascript 执行耗时(数据取3次平均值):

Layout 耗时(数据取3次平均值):

测试代码:

<body>
  <div class="app"></div>
  <script> let counts = 1000
    let $app = document.querySelector('.app')
    let start = performance.now()
    // 单独操作
    // for (let i = 0; i < counts; i++) {
    //   let node = document.createTextNode(`${i}, `)
    //   $app.append(node)
    // }

    // 批量操作
    let $tempContainer = document.createElement('div')
    for (let i = 0; i < counts; i++) {
      let node = document.createTextNode('node,')
      $tempContainer.append(node)
    }
    $app.append($tempContainer)

    console.log(performance.now() - start) </script>
</body>

可以看到的是,批量处理和单次处理再 Layout 期间耗时是几乎一致的,虽然在 script 执行阶段还是存在一定的性能优势(大概 30%),但大抵上只要你用好 DOM 操作,批量或不批量带来的性能影响是很小的( 10W 次调用多损耗 27ms )。题外话:这里提出一个问题,为什么在 script 执行阶段还是存在一定的性能差距?答案会在晚些时候公布(等我看完这部分逻辑)

Virtual DOM 有 diff 算法?

严格来说 diff 算法和 Virtual DOM 是两个独立的东西,二者互相之间也没有充分必要的关联,比如 svelte[4] 没有 Virtual DOM 也有其自己的 diff 算法。但由于前端框架存在 Virtual DOM 就总有 diff 算法,并且使用了 Virtual DOM 对 diff 算法也有两个助力:

  1. 得益于 Virtual DOM 的抽象能力,diff 算法更容易被实现和理解
  2. 得益于 Virtual DOM Tree 总是在内存中, diff 算法功能可以更强大(比如组件移动,没有完整的 Tree 结构是不可能实现的)

diff 算法能减少 DOM API 调用,显然是存在设计和性能优势的,而由于 Virtual DOM 的存在,diff 算法可以更方便且更强大,所以我认同这是 Virtual DOM 的优势,但不能用“Virtual DOM 有 diff 算法”这样的表述。

Virtual DOM 有跨平台优势?

上文提到的 svelte 没有 Virtual DOM ,但一样可以实现服务端渲染,这说明跨平台并不依赖于 Virtual DOM 。其实只要 Javascript 框架有实现平台 API 分发机制,就能在不同平台执行不同的渲染方法,即拥有跨平台能力。这个能力的根本,是 Javascript 代码能低代价地在各个平台运行(得利于浏览器在各个平台的普及和 NodeJS),也就是常说的 Javascript 的优势之一是跨平台。所以把跨平台当做 Virtual DOM 的优势,其实是不正确的,但我们或许应该去思考下他们为什么会这么认为。我的想法,可能是这两个原因:

  1. Virtual DOM 的优势,可以在不接触真实 DOM 的情况下操作 DOM,并且性能更好在 Virutal DOM 上的改动,最终还是会调用平台 API 去操作真实的 DOM ,所以没有 Virtual DOM 只是相当于少了一个中间抽象层,并不影响跨平台能力有无。但还是需要明白,就目前的分析来看,这个抽象层对跨平台能力还是提供了相当大的方便(或者说助力)的。
  2. Virtual DOM 在 Vue 中很重要,Vue 本身就是一个围绕 Virtual DOM 创建起来的框架,脱离了 Virtual DOM 其设计思想必然会和当下迥乎不同

总结

本文从互联网上摘选了部分对开发者对 Virtual DOM 优点的认知,也从现实生活中了解到一些误解,总结为 Virtual DOM 的四个“优势”,并分别对这四个“优势”进行了单独分析或举证。最终我们识别了几个关于 Virtual DOM 优势误区:

  1. 操作 DOM 太慢,操作 Virtual DOM 对象快 ❌ (Virtual DOM 很快,但这并不是它的优势,因你本可以选择不使用 Virtual DOM );
  2. 使用 Virtual DOM 可以避免频繁操作 DOM ,能有效减少回流和重绘次数 ❌ (无论你在一次事件循环中调用多少次的 DOM API ,浏览器也只会触发一次回流与重绘(如果需要),并且如果多次调用并没有修改 DOM 状态,那么回流与重绘一次都不会发生。批量操作也不能减少回流与重绘);
  3. Virtual DOM 有跨平台优势 ❌ (跨平台是 Javascript 的优势,与 Virtual DOM 无关)。

我们也提到了 Virtual DOM 真正的优点是其抽象能力和常驻内存的特性,让框架能更容易实现更强大的 diff 算法,缺点是增加了框架复杂度,也占用了更多的内存。

参考资料

[1]虚拟DOM同样也是操作DOM,为啥说它快? (https://segmentfault.com/q/1010000010303981)[2]Virtual Dom 的优势在哪里?( https://github.com/RomanHc/blog/issues/20) [3]Virtual Dom的优势 (https://juejin.cn/post/6844904179715014669) [4]svelte(https://github.com/sveltejs/svelte)

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/4ZQW1KVxfpRT1o7YPGPrGw

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录