关于 Virtual DOM 和直接 DOM 操作哪个性能更高?
VDOM 本质上是一个 Javascript 对象,用来描述 DOM 结构,如:
可以用如下对象表示:
在实际的生产环境需要将这个 JS 对象转化成真实的 DOM 元素。
1、浏览器渲染引擎工作流程大致分为如下步骤:
2、JS 频繁操 DOM 的开销:
假如在实际生产环境中,有这么一个列表:
我们现在需要更新列表的,从后端拿到了数据,但是新的数据只有第50行的数据有变化。
1、最简单最节约心智的办法是,我们不关心新数据与老数据之间的差异,直接 innerHTML 更新整个 ul 标签里的内容。但是这样就造成了不必要的 DOM 操作开销,毕竟只需要更新一个节点,但是为了省事,99次操作是浪费资源的无用功。
2、或者我们逐个对比数据,发现是第50行有变化,直接将第50行的 span 用 innerText 更新内容即可。
3、虽然手动更新第50行内容达到了最小操作,但是每次从后端拿到新数据,我们并不能都知道是哪些行数据有变化,这个时候就需要写一个通用的方法来比较新旧数据的变化,并只去更新数据有变化的节点。
但是这样还不够,这个通用方法也只是满足了这一个列表的数据对比和节点更新,如果我们的项目中还有几十、几百个其它的列表呢?
这个时候 VDOM 就派上用场了。我们把整个页面抽象成 Js 对象(VDOM),每次的更新数据,我们都先更新 VDOM,再通过比较 新旧 VDOM 的变化,找到具体要更新的节点,再去操作具体的 DOM。
这个时候可能有人要问了,那在更新 VDOM 的时候不也做了很多无用功的操作吗?
对,但是 VDOM 的操作都是纯 Js 的计算,大家要明确的一点是 Js 计算(特别是在 V8 引擎的加持下)要比真实 DOM 操作开销小得多,最重要的是再也不用操心到底哪些数据有更新了,直接无脑用 VDOM 就是,开发效率提高了!
用这个列表举例:
1、当列表新数据更新了第50、60行时:
前面也说了得益于现代浏览器的高效,Js 计算是非常快的,故 + << 。
综合比较三种更新方式, < + << 。
可以看出手动去进行最小节点操作是性能最好的,但是其心智负担也不小。
2、当 ul 中所有数据都变了,那就能直接无脑 innerHTML 进行更新,因为此时更新所有节点就是最小节点操作。
所以一个项目能确定基本上每一页的内容都不相同,几乎要全部更新,那可以不用 VDOM,直接用 innerHTML 即可。
反之一个项目,有很多列表,有众多增删改查操作,那用 VDOM 是十分有意义的。
所以抛开场景谈性能就如同抛开剂量谈毒性,都是耍流氓。用 VDOM 更新真实 DOM 其实是在节约开销(运行效率)和节约心智(省事、提高开发效率)之间找到一个比较好的平衡点。不然为什么人家 React 和 Vue 要用 VDOM 呢?成千上万人验证过的东西,能流行一定有它的道理
2023-07-25 广告