为什么虚拟DOM更优胜一筹
注意: 虚拟DOM只是实现MVVM的一种方案,或者说是视图更新的一种策略。没有虚拟DOM比MVVM更好一说。
我们回顾传统MVC框架,如backbone,它是将某个模板编译成模板函数,需要更新时,是自己手动将数据整体传入模板函数,
得到一个字符串,使用innerHTML刷新某个容器!注意,这里其实可以优化,但由于是手动,是体力活,都是使用很粗放型的innerhTML了事
(使用jQuery的html方法性能会更差,不过好处是它处理了IE下的innerHTML BUG及全平台的无法执行内部的script标签的BUG)
由于整体替换,一下子销毁这么多元素(有时还绑着事件,可能导致GC出问题),又要插入这么多元素,再重新绑定事件(这个可以使用事件代理缓解)
因此性能非常差
方案二是使用脏检测的angular,要求对所有作用域对象进行diff,使用通知刷新函数进行视图更新.
页面上的指令越多,需要比较的数据越多(有循环, 需要乘以数组长度或对象键值对个数),可能用于循环时间过长导致页面假死
方案三使用avalon这样的密封舱方案(船底是分成一个个独立的区域,局部受损也不会导致沉船).
avalon使用Object.defineProperty及VBS实现属性监控, 这样用户修数据时,就能立即进入
事件总线系统(观察者模式),然后取得与这属性相关联的订阅者数组(换言之的密封舱,不像ng那样,
一个$scope对象就一个$$watcher数组).而一般情况下,VM中的某个属性在视图中也只会用到几个位置,
那么几个位置,就会生成几个绑定对象,都放在相应的订阅者数组中,每个订阅者数组都不会太长.
因此同步视图,不会因此遍历的数组过长而假死.因此ng在处理2000个指令的页面时就易出问题
(一个grid,往往有两三重循环,很容就飙到5000个指令),而avalon的密封舱方案是能撑到12000个指令
但avalon需要保存大量的绑定对象,并且将普通属性转换访问器属性,也需要占用内存,这是一个以空间换时间的方案.
不过avalon在处理ms-repeat, ms-with, ms-each这些循环绑定的场合, 实现得不太好。这其中要生成大量的代理VM,
整个页面都在生成销毁VM中拖慢了(即便使用各种池子进行循环再用).
方案四,像knockout那样, 使用时让用户痛苦一些,使用可同步视图的东西用函数(wrapper)包裹起来,
刷新视图,就只需要重新调用这个wrapper.现在所有新的MVVM都是从ko那里学到依赖收集.
这个wraper会通知其依赖的wrapper,通过极其痛苦晦涩的方式进入事件总线, 执行视图刷新函数.
knockout是使用闭包用到极致的库,显然这样做性能也很差.
最后react, 首先使用编译手段(jsx的虚拟DOM转换), 将这部分消耗能提前释放出去,
不过将字符串(jsx模板)转换为一个个JS对象,也占不了多少内存. 然后是数据发生变动时,
由于数据变动都是需要用setState方法,因此兼容性很好,
少了Object.defineProperty或wrapper的消耗,然后对应数据通过render转换成字符串,字符串再转换虚拟DOM树
先后虚拟DOM进行比较, 更新视图.
react是面向组件设计, 一个组件就是一个密封舱, 很少会对所有虚拟DOM进行比较, 由于强制使用单向流动,
减少每次变动需要的diff. 没有绑定对象与wrapper的内存占用高的问题.
react的流行,只是ng太难用了,当ng或其他MVVM改用虚拟DOM进行视图更新,这优势就不需要!
react的问题很明显,库非常大,它基本上离开了jsx换转器就活不成。 这么大的库, 换言之大家能对它改动的地方就越多,每升一个版本就数千改动。
作为架构师的我们,需要对其源码进行非常熟悉的了解,要不出了问题无法自己处理,每次等外国人回复就迟了。
react的复杂度,很易触发大家对它的重构,即便占有方有向前兼容的愿望,但能抵得几次诱惑呢,因此经过几个版本会面目全非。如果你坚持不变,那么其他人就会另起山头,
开源的东西很易出现一个更优势的仿品!react的实现很糟糕的,强在设计!
虚拟DOM的难点是如何将一个字符串变成一个模板函数,然后再转换为虚拟DOM。 目前没有简单的HTML parser实现,stackoverflow上说不能使用几行正则就能拆分HTML!
因此这个高门槛,导致react的代替方案难产!github上有许多自称使用了虚拟DOM的框架,不是假的就是超垃圾的实现!更何况react支持自定义标签,因此不单是解析HTML的问题了,
需要对自定义标签进行更多的处理!
目前avalon的虚拟DOM方案也在缓慢推进中,不是我不会写parser,只是太多人问我许多avalon基础问题,严重拖慢我的速度。。。。
为什么虚拟DOM更优胜一筹的更多相关文章
- 【虚拟DOM】√
深度剖析:如何实现一个 Virtual DOM 算法 为什么虚拟DOM更优胜一筹 新建树,渲染树,新建新树,对比树(算法),最少dom操作的渲染树
- React virtual DOM explained in simple English/简单语言解释React的虚拟DOM
初学React,其中一个很重要的概念是虚拟DOM,看了一篇文章,顺带翻译一下. If you are using React or learning React, you must have hear ...
- React虚拟DOM浅析
在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(Virtual DOM)的机制. 什 ...
- React的虚拟DOM
ReactJs的一大特点就是引进了虚拟dom(Virtual DOM)的概念.为什么我们需要Virtual DOM,Virtual DOM给我们带来了什么优势. 首先我们要了解一下浏览器的工作流. 当 ...
- React 虚拟 DOM 的差异检测机制
React 使用虚拟 DOM 将计算好之后的更新发送到真实的 DOM 树上,减少了频繁操作真实 DOM 的时间消耗,但将成本转移到了 JavaScript 中,因为要计算新旧 DOM 树的差异嘛.所以 ...
- JavaScript是如何工作的:编写自己的Web开发框架 + React及其虚拟DOM原理
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 19 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! Jav ...
- Vue之虚拟DOM
一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...
- 从虚拟dom了解vue渲染函数
vue渲染函数就是render函数,他会返回一个VNode,VNode是一个js对象,是dom的映射 vue在介绍渲染函数那个章节看的不是很懂,所以想要彻底的理解渲染函数,首先需要了解vue的虚拟do ...
- Vue原理--虚拟DOM
为什么需要虚拟DOM? 如果对前端工作进行抽象的话,主要就是维护状态和更新视图,而更新视图和维护状态都需要DOM操作.其实近年来,前端的框架主要发展方向就是解放DOM操作的复杂性. 运行js的速度是很 ...
随机推荐
- MySQL数据库order by 奇慢无比
今天遇到个奇葩的问题, sql 数据量很大 有where 和order by,不加order by 速度很快,加了就很慢 一.首先我们对这条sql执行查询计划: explain select t.or ...
- SpringMVC 注解详解
SpringMVC常用注解说明 @Bean, @Configuration表示基于Java配置的类@Bean除了配置在@Configuration,也可以在@Component定义,此时没有特殊意义, ...
- CentOS之Shell基础
Linux默认的shell版本是bash. 我们所敲的命令都是有记录的:被保存在.bash_history文件中.只有当用户正常突出shell时,命令才会保存至.bash_history中. !!:连 ...
- time_base
From:http://blog.csdn.net/supermanwg/article/details/14521869 FFMPEG的很多结构中有AVRational time_base;这样的一 ...
- css实战第三天小结
1.谈一谈对层级的理解: 如果对两个并列的子元素都设置了相对于同一个父元素(如果没有设置父元素那么默认相对于浏览器而言)进行了定位(相对定位),则这两个都具有相同的层级(默认为0),他们的trbl也默 ...
- Docker的常用命令
docker命令有很多,总的分为以下几大类: 容器生命周期管理 — docker [run|start|stop|restart|kill|rm|pause|unpause] 容器操作运维 — doc ...
- bzoj2555 substring(LCT 后缀自动机)
/* 动态求right集合的大小 LCT维护parent树即可 注意 由于树是有向的不会换根并且每次操作单一, 于是不需要维护子树和(写起来很麻烦) 直接打标记修改即可 */ #include< ...
- Hdu 4622 Reincarnation(后缀自动机)
/* 字符串长度较小, 可以离线或者直接与处理所有区间的答案 动态加入点的时候, 因为对于其他点的parent构造要么没有影响, 要么就是在两个节点之间塞入一个点, 对于minmax的贡献没有改变 所 ...
- js 原生图片上传
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用python操作excel表格
首先 pip install xlrd 安装相关模块 其次:使用方法: 1 导入模块 import xlrd 2 打开excel文件读取数据 worksheet=xlrd.open_workbook ...