React 虚拟DOM(https://zhuanlan.zhihu.com/p/28562066)
通过在 JS 和 DOM 之间增加一个新的抽象表示层,从而在需要更新时,对比这一表示层的 diff,最终差量更新 DOM。
当有数据变化时,例如 list 变为了 [ { id: 1, text: 'Item 1' } ],React 会执行如下三个步骤:
- 接收到变更数据,整个 UI 被重新渲染为新的 Virtual DOM 表示
- 对比新旧 Virtual DOM 表示的区别,得到差量更新内容。React 称这一过程为调和(Reconciliation)过程。在这个例子中,差量更新的内容为:删除后面两个 li
- 对 DOM 应用上一步中计算的差量更新
然而这并不是 Virtual DOM 的全部价值,在增加这一抽象层之后,React 其实脱离了 DOM 这样单一的应用场景,它的解决问题的思路可以普世地应用在所有 UI 场景中。前面三个步骤中的前两个属于 React 核心部分,第三个步骤可以由特定的 Renderer 来完成。目前单就官方目前支持的就有 DOM Renderer(浏览器)、Server Renderer(服务器)、Native Renderer(iOS 和 Android)、ART Renderer(Canvas,SVG 或者 VML),以及测试使用的 Test Renderer。比较知名的第三方 Renderer 有 Flipboard 的 react-canvas,更多 Renderer 可以看这个 Awesome list。
为什么使用前端框架(vue、react、angular)而不是jquery了呢?
不用关心dom,只需要关心状态,关心逻辑,代码容易维护。
vue状态变化侦测及渲染原理(https://github.com/berwin/Blog/issues/20)
Vue 模板编译原理(https://github.com/berwin/Blog/issues/18)
一个状态对应某个组件,而不再是具体标签,这样做有一个好处是可以大大降低依赖的数量,毕竟组件的数量与DOM中的具体标签比,数量要少的多。但是这样就需要多一个操作,当状态发生变化只通知到组件,那么组件内部如何知道具体更新哪个DOM标签??
答案是VirtualDOM。
也就是说,当粒度调整为中等之后,需要多一个操作就是在组件内部使用VirtualDOM去重新渲染。
Vue很聪明地通过变化侦测+VirtualDOM这两种技术方案,提升了框架运行的性能问题。
所以说,Vue2.0引入VirtualDOM并不是因为VirtualDOM有多好,而是恰好VirtualDOM结合变化侦测可以将绑定调整成中等粒度来解决依赖追踪的开销问题。
关于vue的内部原理其实有很多个重要的部分,变化侦测,模板编译,virtualDOM,整体运行流程等。
数据检测部分(https://github.com/berwin/Blog/issues/17)
利用 Object.defineProperty
侦测对象的变化,最简单的可以写出这样的代码:
function defineReactive (data, key, val) {
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function () {
return val
},
set: function (newVal) {
if(val === newVal){
return
}
val = newVal
}
})
}