在mvvm这个框架领域,到现在仍然存在一个及其热门的面试问题:为什么要使用虚拟DOM?

一般的回答如下:

本文将通过另一个视角,给出不同的答案,本文不局限于点对点看待问题本硕本身,而是放在一个足够长的、合理的上下文中进行讨论。

什么是虚拟 DOM?

在 React 中,render 执行的结果得到的并不是真正的 DOM 节点,结果仅仅是轻量级的JavaScript 对象,我们称之为 virtual DOM。虚拟DOM本质上是JS和DOM之间的映射缓存,在形态上是一个能够描述DOM结构的JS对象。

虚拟 DOM 是 React 的一大亮点,具有 batching(批处理) 和高效的 Diff 算法。这让我们可以无需担心性能问题而” 毫无顾忌” 的随时“ 刷新” 整个页面,由虚拟 DOM 来确保只对界面上真正变化的部分进行实际的 DOM 操作。在实际开发中基本无需关心虚拟 DOM 是如何运作的,但是理解其运行机制不仅有助于更好的理解 React 组件的生命周期,而且对于进一步优化 React 程序也会有很大帮助。

虚拟DOM在在挂载阶段和更新阶段分别的作用如下:

历史长河中的DOM操作解决方案

原生JS下“人肉DOM”时期

此时前端页面的“展示”属性远远高于“交互”属性,这就导致JS只是辅助功能。前端工程师会花大量时间去实现静态DOM,待一切结束后,补充少量JS代码进行交互。此时的前端工作虽然“一无所有”,但却很快乐,简单的需求决定了我们不需要做过多的DOM操作。

解放生产力的先导阶段: jQuery 时期

大量DOM操作需求带来的前端开发工作量的激增,jQuery首先解决的就是“API 不好使”这个问题,将DOM API封装为了相对简单和优雅的形式,同时一口气做掉了跨浏览器的兼容工作,并且提供了链式API调用、插件扩展等一系列能力用于进一步解放生产力。虽然现在看来并不完美,但是在当年能够一统江湖,确实当之无愧。

民智初启:早期模板引擎方案

jQuery并不能从根本上解决DOM操作量过大情况下前端侧的压力。就像手持吸尘器,虽然可以帮助我们更加方便快速地清洁某一处的灰尘, 要想清洁多个位置的灰尘,你仍然需要拿着它四处奔走,还是避免不了跑断腿的结局。

模板引擎方案,正是“扫地机器人”的雏形。模板引擎更倾向于点对点解决烦琐DOM操作的问题,它在能力和定位上既不能够也不打算替换掉jQuery,两者是和谐共存的。因此这里不存在“模板引擎时期”,只有“模板引擎方案”。

<table>{% staff. forEach(function(person){ %] <tr><td>{% student.name %}</td> <td>{% student. age %}</td></tr> {% }); %}
</table>
//数据和模板融合出HTML代码
var targetDOM = template({data: students})
//添加到页面中去
document. body.appendChild(targetDOM)

1.读取HTML模板并解析它,分离出其中的JS信息
2.将解析出的内容拼接成字符串,动态生成JS代码
3.运行动态生成的JS代码,吐出“ 目标HTML”
4.将“目标HTML”赋值给innerHTML,触发渲染流水线,完成真实DOM的渲染

使用模板引擎方案来渲染数据需要关注的仅仅是数据和数据变化本身,模板引擎实际的应用场景基本局限在“实现高效的字符串拼接”这一一个点上,因此不能指望它去做太复杂的事情。它在性能上的表现并不尽人意。

本课时所讨论的“模板引擎”概念,指的是虚拟DOM思想推而厂之以前,相对原始的一类模板引擎。

走“数据驱动视图”这条基本道路

既然操作真实DOM对性能损耗这么大,那我操作假的DOM不就行了?

真实历史中的虚拟DOM创作过程,到底有没有向模板引擎去学习,这个暂时无从考证。但是按照前端发展的过程来看,模板引擎和虚拟DOM确实在思想上存在递进关系。

在模板引擎下,是这样解决问题的

在虚拟DOM中,则是

这里的“模板”是因为,JS在使用虚拟DOM时不总是使用模板引擎,比如react使用JSX

虚拟DOM的工作流程:

虚拟DOM和Redux -样,不依附于任何具体的框架,学习React必须了解虚拟DOM
虚拟DOM源码仓库:https://github.com/Matt-Esch/virtual-dom

React选用虚拟DOM,真的是为了更好的性能吗?
开发者写得爽不爽,在于研发体验/研发效率,虚拟DOM是前端开发们为了追求更好的研发体验和研发效率而创造出来的高阶产物。

虚拟DOM能够在提供更爽、更高效的研发模式的同时仍然保持一个还不错的性能。

性能问题属于前端领域复杂度比较高的问题量化性能的时候要结合各种要素来作分情况的讨论

数据内容变化非常大(或者说整个发生了改变),促使差量更新计算出来的结果和全量更新极为接近(或者说完全一样) ,此时虚拟DOM需要进行JS计算,虚拟DOM的劣势主要在于JS计算的耗,DOM操作的能耗和JS计算的能耗根本不在一个量级,使得性能并不一定比模板引擎的全量更新更加快。

当然,这只是一种极端情况,在大多数情况下,更加高频的做法是每次setState的时候只修改少量的数据,模板渲染和虚拟DOM之间DOM操作量级的差距就完全拉开了虚拟DOM将在性能.上具备绝对的优势。

性能问题不能一概而论, 而且咱都讲到这个份上了,就不要再钻性能这个牛角尖了。jQuery、原生DOM在思维模式上来说和虚拟DOM截然不同,强行比较意义不大。

对 React 虚拟 DOM 的误解?

React 从来没有说过 “React 比原生操作 DOM 快”。React 给我们的保证是,在不需要手动优化的情况下,它依然可以给我们提供过得去的性能。

React 掩盖了底层的 DOM 操作,可以用更声明式的方式来描述我们目的,从而让代码更容易维护。下面还是借鉴了知乎上的回答:没有任何框架可以比纯手动的优化 DOM 操作更快,因为框架的 DOM 操作层需要应对任何上层 API 可能产生的操作,它的实现必须是普适的。针对任何一个 benchmark,我都可以写出比任何框架更快的手动优化,但是那有什么意义呢?在构建一个实际应用的时候,你难道为每一个地方都去做手动优化吗?出于可维护性的考虑,这显然不可能。

结论:虚拟DOM的价值不在性能,而在别处

虚拟DOM主要的价值有两点:

1.开发体验、开发效率

虚拟DOM能够在提供更爽、更高效的研发模式的同时仍然保持一个还不错的性能。

2.跨平台的问题

React:真正理解虚拟DOM相关推荐

  1. 第九篇:真正理解虚拟 DOM:React 选它,真的是为了性能吗?

    在过去的十年里,前端技术日新月异.从最早的纯静态页面,到 jQuery 一统江湖,再到近几年大火的 MVVM 框架--研发模式升级这件事情对于前端来说,好像成了某种常态.其实研发模式不断演进的背后,恰 ...

  2. React 中的虚拟 DOM 是什么?

    虚拟 DOM 是一个基本的 React 概念.如果您在过去几年编写过 React 代码,您可能听说过它.但是,你可能不明白它是如何工作的以及 React 为何使用它. 本文将介绍什么是虚拟 DOM,它 ...

  3. [react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?

    壹 ❀ 引 虚拟DOM(Virtual DOM)在前端领域也算是老生常谈的话题了,若你了解过vue或者react一定避不开这个话题,因此虚拟DOM也算是面试中常问的一个点,那么通过本文,你将了解到如下 ...

  4. [react] 为何说虚拟DOM会提高性能?

    [react] 为何说虚拟DOM会提高性能? 虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能 个人简介 我是歌谣,欢迎和大家一起交 ...

  5. React简介、虚拟DOM、Diff算法、创建React项目、JSX语法、组件、组件声明方式、组件传值props和state、组件的生命周期

    React简介: 前面只是简单介绍移动APP开发,后面还会继续深入介绍移动app开发:其中想要用ReactNative开发出更出色的应用,那么就得学好React,下面将介绍React: React 是 ...

  6. 前端学习(2560):理解虚拟dom和key

  7. React虚拟DOM的理解

    React虚拟DOM的理解 Virtual DOM是一棵以JavaScript对象作为基础的树,每一个节点可以将其称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲 ...

  8. 【React深入】深入分析虚拟DOM的渲染原理和特性

    导读 React的虚拟DOM和Diff算法是React的非常重要的核心特性,这部分源码也非常复杂,理解这部分知识的原理对更深入的掌握React是非常必要的. 本来想将虚拟DOM和Diff算法放到一篇文 ...

  9. 前端React教程第六课 虚拟DOM

    09 真正理解虚拟 DOM:React 选它,真的是为了性能吗? 在过去的十年里,前端技术日新月异.从最早的纯静态页面,到 jQuery 一统江湖,再到近几年大火的 MVVM 框架--研发模式升级这件 ...

最新文章

  1. Struts2中There is no Action mapped for namespace错误解决方法
  2. python 全局变量 局部变量
  3. [題解](最小生成樹)luogu_P2916安慰奶牛
  4. 一台服务器能承载多少用户_一台入门级服务器能为你的办公应用带来哪些效率?评测告诉你...
  5. firefox安装adobe flash插件
  6. linux 无线网卡休眠,无线网卡在Linux下活起来
  7. leetcode437. 路径总和 III
  8. tomcat常见报错
  9. word参考文献交叉引用
  10. 联合国首席AI顾问专访:我们期望AI应该是完美的,但这永远不会
  11. 在 HTML 中使用 ARIA 的规则
  12. Linux运维-ip地址配置
  13. 远程办公实践丨需重视以人为本的员工激励设计
  14. 虚拟机里的ubuntu设置1920x1080分辨率
  15. 网络分层,网络协议TCP/IP模型,OSI模型
  16. 移动端图片剪裁工具cropperjs
  17. python调用有道翻译_如何用python“优雅的”调用有道翻译?
  18. 手机python代码写好了怎么运行-如何优雅的在手机上进行Python编程
  19. Ubuntu中安装Matlab2010
  20. 使用Biopython比较基因组相似度:新冠(COVID19)与非典(SARS)、中东呼吸综合征(MERS)

热门文章

  1. Linux ls -l输出文件信息详解
  2. 空心字母金字塔(Java)
  3. 官网Instagram集成
  4. 淘宝/天猫API:item_list_weight-批量获取商品信息
  5. C语言——整型的截断与提升
  6. 35 个免费的响应式网站模板下载
  7. 5个问题讲清楚商业模式
  8. 【2DWT:2维离散小波变换(附Pytorch代码)】
  9. gitlab-ce搭建和数据迁移
  10. 细胞分类 识别 系统