ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-09 19:08:12  阅读:132  来源: 互联网

标签:dom react var 虚拟 props 组件


壹 ❀ 引

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

  • 虚拟DOM究竟是什么?
  • 虚拟DOM的优势是什么?解决了什么问题?
  • 虚拟DOM的性能比操作原生DOM要快吗?
  • react中的虚拟DOM是如何生成的?
  • react是如何将虚拟DOM转变成真实dom的?

阅读前建议与提醒:

  • 本篇文章可能比较长,建议挑一个空闲的时间段阅读,还请保持耐心,我将以通俗易懂的口吻带你了解这些问题。
  • 本文源码分析部分react版本为17.0.2,无须担心低版本源码分析对你之后面试帮助不大的问题。
  • 如果可以,泡上一杯性温的茶或者咖啡,保持一个舒服的姿势会让你阅读更加愉快。

那么本文开始。

贰 ❀ 在虚拟dom之前

在聊虚拟DOM之前,我还是想先聊聊在没有虚拟DOM概念的时候,我们是如何更新页面的,所以在这里我将先引出前端框架(库)的发展史,通过这个变迁过程也便于大家理解虚拟dom的出现到底解决了什么问题。

贰 ❀ 壹 石器时代jqery

其实在15年以及更早之前,前端面试涉及到性能优化问题,往往都会提到尽可能少的操作DOM这一点。为什么呢?因为在原生JS的年代,前端项目文件都明确分为html、jscss三种,我们在js中获取DOM,并为其绑定事件,通过事件监听感知用户在UI层的操作,并随之更新DOM,从而达到页面交互的目的:

而在后面,jqery的出现极大简化了开发者操作DOM的成本,抹平了当时不同浏览器操作DOMAPI差异,为当时苦于ie以及不同浏览器自研API的开发者解决了不少兼容性问题,当然JQ也并未改变开发者在JS层直接操作DOM这一现状。

那么我们为什么说要尽可能少的操作DOM呢,这里就涉及到重绘与回流两个概念,比如单纯修改颜色就会引发重绘,删除或新增一个DOM节点就会引发回流和重绘,用户虽然无法感知这个过程,但对于浏览器而言也存在消耗性能。所以针对于回流,在此之后又提出了DocumentFragment文档对象以优化多次操作DOM的方案。简单理解就是,假如我要依次替换五个li节点,那么我们可以创建一个DocumentFragment对象保存这五个节点,然后一次性替换。

关于节流与重绘,若有兴趣可读读博主页面优化,谈谈重绘(repaint)和回流(reflow)一文。

关于DocumentFragment可读读博主页面优化,DocumentFragment对象详解一文。

这些都是时代的眼泪,现在应该很少会有人提及,这里就不再赘述了。

贰 ❀ 贰 青铜时代angularjs

JQ之后,angularjs(这里指angularjs1而非angular)横空出世,一招双向绑定在当时更是惊为天人,除此之外,angularjs的模板语法也格外惊艳,我们将所有与数据挂钩的节点通过{{}}包裹(vue在早期设计上大量借鉴了angularjs),比如:

<span>{{vm.name}}</span>

之后 view 视图层就自动与 Model 数据层进行挂钩(MVC那一套),只要 Model 层数据发生变化,view 层便自动更新。angularjs 的这种做法,彻底将开发者从操作 DOM 上解放了出来(为jq没落埋下伏笔),自此之后开发者只用专注 Model 层的数据加工以及业务处理,至于页面如何渲染全权交给 angularjs 底层处理即好了。

但需要注意的是,angularjs 在当时并没有虚拟dom的概念,那它是怎么做感知数据层变化以及更新视图层的呢?angularjs有一套脏检测机制$digesthtml中凡是使用了模板语法{{}}或者ng-bind指令的部分,都会被加入到脏检测的warchers列表中,它是一个数组,之后只要用户通过ng-click(与传统click不同,内置绑定了触发脏检测的机制)等方法改变了Model的数据,angularjs就会从顶层rootScope向下递归,依次访问每个子scope中的warchers列表,并对其中监听的部分做新旧对比,如果不同则进行数据替换,以及DOM层的更新。

但是你要想想,一个应用那么大的结构,只要某一个数据变化了就得从顶层向下对比N个子 scopewarchers 下的所有监听对象,全量对比的性能有多差可想而知,angularjs 自身也意识到了这点,所以之后直接放弃了 angularjs 的维护转而新开了 angular 项目。

对于 angularjs 脏检测感兴趣可以读读博主深入了解angularjs中的

标签:dom,react,var,虚拟,props,组件
来源: https://www.cnblogs.com/echolun/p/16359890.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有