注意: 虚拟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是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的。虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。
浏览器解析HTML文档生成DOM树的过程,以下是一段HTML代码,以此为例来分析解析HTML文档的原理.解析HTML文档构建DOM树的理解过程可分为两个主要模块构成,即标签解析、DOM树构建
javascript获取DOM对象的多种方法:通过id获取 、通过class获取、通过标签名获取、通过name属性获取、通过querySelector获取、通过querySelectorAll获取等
遍历DOM节点常用一般用节点的 childNodes, firstChild, lastChild, nodeType, nodeName, nodeValue属性。在获取节点nodeValue时要注意,元素节点的子文本节点的nodeValue才是元素节点中文本的内容。
要构建自己的虚拟DOM,需要知道两件事。你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂——但实际上,虚拟DOM的主要部分只需不到50行代码。
事件冒泡: 即事件开始时由最具体的元素(文档中嵌套层数最深的那个点)接收,事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件.与此同时,我们还需要了解dom事件绑定处理的几种方式:
先列出我的理解,然后再从具体的例子中说明:DOM操作本身应该是同步的(当然,我说的是单纯的DOM操作,不考虑ajax请求后渲染等);DOM操作之后导致的渲染等是异步的(在DOM操作简单的情况下,是难以察觉的)
早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类。
设置定义属性值 :data-value=.., 2.直接获取 3.通过this.$refs.***获取 1.目标DOM定义ref值: 2.通过 【this.$refs.***.属性名】 获取相关属性的值: this.$refs.*** 获取到对应的元素 ...
框架用多了,你还记得那些操作 DOM 的纯 JS 语法吗?看看这篇文章,来回顾一下~ 操作 className,addClass给元素增加 class,使用 classList 属性
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!