← 返回目录

虚拟DOM

第 135 / 154 卷日期:

单一事实来源,任何要在组件之间共享的数据,都需要保存在一个地方,与使用它的组件分开。这个单一的位置被称为“商店”。组件必须从该位置读取应用程序数据,而不是保留自己的副本以防止冲突或分歧。

数据只可读,组件可以自由地从存储中读取数据。但他们不能更改存储中的数据,至少不能直接更改。相反,他们必须通知存储他们更改数据的意图,并且存储将负责通过已定义“更新”的函数进行这些更改。

更新是同步的,我们根据上面的两个原则,就能很便利的追踪数据的状态变化和调试,但是如果是异步的话,我们就不能很好的判断执行的顺序。

三、具体使用

具体的应用就是我们常见的 VUEX 和 React 中。

虚拟DOM

一、什么是虚拟 DOM呢?

再过去或者我们原生JavaScript的时候,我们可以发现,当我们需要改变视图的数据的时候,我们往往需要先获取到这个 DOM 元素,然后对其进行更新。也就是:

数据改变-->操作DOM--> 视图更新

但是我们在 VUE或者 React 中是直接改变 Data 就能实现视图的更新了。

数据改变-->视图更新

那么要是我们每一次数据改变都需要操作 DOM,那就非常麻烦,而且慢。因为 JavaScript执行时很快的,但是操作 DOM就不是了。所以就有了虚拟 DOM了

数据改变-->操作虚拟 DOM(计算变更)-->操作真实的 DOM--> 视图更新

那么什么虚拟 DOM 呢?

可以说虚拟 DOM 本质上是 JS 和 DOM 之间的映射,表现为是一个能描述 DOM结构及其属性信息的 JS对象。那么下面我们看一个例子为什么这么说吧:

//我们定义的 DOM <div id="app">

<p class="text">hello</p> <h1 class="text">hello world!!!</h1>

</div>

//转换为虚拟 DOM {

tag: 'div', props: {

id: 'app' },

chidren: [ {

}, chidren: [

'hello' ]

}, {

tag: 'h1', props: {

className: 'text' },

chidren: [ 'hello world!!!'

] }

] }

实际上就是通过 JavaScript 对象来作为基础的树,用对象的属性来描述节点,然后通过映射成真实的 DOM 结构。

二、那么这么做有什么好处呢

1、优化性能

我们常说要减少重排的发生,那是为什么呢,因为那会涉及到 DOM 树的重新渲染。而操作 DOM 树是比较慢的,且 DOM 元素的数量谁很庞大的,当操作 DOM 很容易带来页面的性能问题。很容易给用户带来不好的体验,而

这点是很重要的,可以说我们前端页面是与用户的第一个窗口。

比如,正常情况下,当我们要更新10个节点的时候,浏览器就会计算 10次,一次一次的进行更新。而在使用虚拟 DOM,他相对就好像多了一个缓存区,当 DOM 操作(渲染更新)比较频繁时,它会先将前后两次的虚拟 DOM 树

进行对比,定位出具体需要更新的部分,生成一个“补丁集”(也就是一个 js对象),最后只把“补丁”一次性打在需要更新的那部分真实的 DOM 树上,避免了很多没必要的计算,提高了性能。

2、抽象化渲染过程

很多人认为虚拟 DOM 最大的优势是 diff 算法,减少 JavaScript 操作真实 DOM 的带来的性能消耗。虽然这一个虚拟 DOM 带来的一个优势,但并不是全部。虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力,

而不仅仅局限于浏览器的 DOM,可以是安卓和 IOS 的原生组件,可以是近期很火热的小程序,也可以是各种 GUI。

解耦了视图层和渲染平台,带来了更多的可能性

有点像我们语言中,都会编译成 AST,而在这个阶段,可以实现多种转化,就像 Babel,和 ESList 等。

3、缺点也是有的:在初次渲染的时候,会多出一层虚拟DOM的计算,而且使用虚拟DOM也不一定是高效的,往往当我们每一次改动不大的时候,才是相对高效的,但是如果我们改动大的话,相比还多出了更多的计算,是不利

的。

总结

全站分卷索引 · 154 卷
  1. 1代码随想录知识星球精华(最强八股文)第五版(前端篇))
  2. 2html语义化
  3. 3src 和 href 的区别
  4. 4link 与 @import 的区别
  5. 5iframe
  6. 6CSS
  7. 7伪元素和伪类
  8. 8block,inline,inline-block
  9. 9重排、重绘和合成
  10. 10盒子模型
  11. 11margin 合并
  12. 12margin和padding 的值为百分比时
  13. 13浮动
  14. 14定位
  15. 15CSS选择器
  16. 16CSS选择器优先级
  17. 17选择器权重Specificity
  18. 18CSS属性继承
  19. 19不可/可继承属性
  20. 20display: none与 visibility: hidden的区别
  21. 21background-size
  22. 22client、offset&scroll
  23. 23CSS3新特性
  24. 24flex布局
  25. 25常见布局
  26. 26三栏布局
  27. 27垂直居中
  28. 28水平垂直居中
  29. 29CSS画三角形
  30. 30使chrome支持12px以下文字
  31. 31响应式布局
  32. 32媒体查询
  33. 33过渡与动画
  34. 34JavaScript 动画 和 CSS动画
  35. 35SCSS
  36. 36CSS性能优化
  37. 37有哪些数据类型
  38. 38判断数据类型
  39. 39类型转换
  40. 40parseInt&parseFloat
  41. 41浮点数求和步骤
  42. 42十进制小数转二进制
  43. 430.1+0.2 为什么不等于 0.3
  44. 44undefined 和 undeclared 的区别
  45. 45JavaScript NaN 属性
  46. 46isFinite()&isNaN()
  47. 47数组
  48. 48对原数组有影响
  49. 49对原数组无影响
  50. 50数组去重
  51. 51数组拍平
  52. 52ES6新增的数组方法
  53. 53判断是否存在某个值
  54. 54arguments为啥不是数组
  55. 55对象
  56. 56遍历对象的方法
  57. 57判断对象是否具有属性
  58. 58for in 和 for of 的区别
  59. 59继承方式
  60. 60instanceof
  61. 61深浅拷贝
  62. 62freeze属性
  63. 63函数
  64. 64函数柯里化
  65. 65函数的 length
  66. 66箭头函数和普通函数区别
  67. 67构造函数
  68. 68执行上下文
  69. 69作用域
  70. 70作用域和作用域链
  71. 71闭包和内存泄漏
  72. 72this
  73. 73关于 this 的指向问题
  74. 74改变this指向的方法(bind / call / apply)
  75. 75字符串
  76. 76DOM和事件
  77. 77哪些事件支持冒泡
  78. 78阻止冒泡
  79. 79HTMLCollection、NodeList
  80. 80dom.onclick 和 dom.addEventListener的区别
  81. 81e.target和e.currentTarget
  82. 82页面生命周期
  83. 83异步
  84. 84内存管理GC
  85. 85其它
  86. 86JavaScript 中日期时间格式转换
  87. 87input和object实现双向绑定
  88. 88JSON.stringify()
  89. 89escape、encodeURI&encodeURIComponent
  90. 90移动端滚动穿透和溢出
  91. 91ES6
  92. 92Map字典
  93. 93... 与rest
  94. 94proxy
  95. 95模块化
  96. 96Ajax、Fetch和Axios
  97. 97Webpack
  98. 98浏览器:事件循环
  99. 99浏览器内核
  100. 100浏览器同源策略
  101. 101输入URL回车后发生了什么
  102. 102HTTP
  103. 103HTTP 2.0
  104. 104浏览器存储
  105. 105鉴权
  106. 106Webstorage
  107. 107浏览器执行机制
  108. 108AST 抽象语法树
  109. 109性能优化
  110. 110CSS
  111. 111网络相关
  112. 112使用HTTP2.0
  113. 113图片
  114. 114CDN图片
  115. 115其他文件优化
  116. 116降低APP首页开屏渲染时间
  117. 117页面白屏
  118. 118HTTPS中间人攻击
  119. 119Web Worker
  120. 120Service Worker
  121. 121微前端
  122. 122Vue
  123. 123v-show 和 v-if 的区别
  124. 124双向数据绑定的原理
  125. 125Vue中的插槽使用
  126. 126Vue中的key
  127. 127Vue过滤器
  128. 128Vue中Scoped原理
  129. 129Vue中$nextTick的使用
  130. 130Vue中实现组件通信的方式
  131. 131Vue-router
  132. 132Vue路由传参
  133. 133前端路由
  134. 134Vuex
  135. 135虚拟DOM
  136. 136DIFF 算法
  137. 137Vue3和Vue2有哪些区别
  138. 138说一说你对React的理解
  139. 139React事件机制
  140. 140说一说你对react refs的理解
  141. 141react中key的作用
  142. 142组件开发
  143. 143有状态组件和无状态组件
  144. 144函数式组件和类组件的区别
  145. 145PureComponent&Component
  146. 146常见 Hooks
  147. 147状态管理
  148. 148redux toolkit
  149. 149React18新特性
  150. 150client中的createRoot取代以前的ReactDOM.render
  151. 151Suspense
  152. 152新的Hooks
  153. 153VDom一定更快吗
  154. 154Fiber