Vue 想要抛弃虚拟 DOM 了?!
The following article is from 前端学不动 Author VeeV
最近 Vue 在美国举办了 Vue Conf 2022,不过可惜的是在国内并未掀起任何的波澜,于是我来试试能不能一石激起千层浪,因为尤雨溪在 Vue Conf 上说他们正在探索一种新的编译策略。
2021
年以来,无虚拟DOM
框架/库/编译器获得了极大的瞩目,最为典型的两个项目:Svelte
Solid.js
我们来看看他俩究竟有多勇:
可以看到Svelte
去年一年在GitHub
上增长的Star
接近Vue
,甚至力压老牌经典框架Angular
!
再来看看这个:
满意度甚至超越React
和Vue
,(吐槽:Angular
这满意度趋势…)
感兴趣程度同样霸榜,只不过这回刚好反过来:Svelte
力压Solid
,Vue
力压React
(越来越多的人对Vue
感兴趣了哈)。Angular
颓势已显,气数已尽了?别担心!下一个选项(Usage)让Angular
来告诉你,什么叫你大爷永远是你大爷:
奇怪,感觉自己身边明明没那么多人用Angular
,怎么肥四?这是因为调查对象主要以欧美地区为主(尤其美国):
母语为英语的人占多数:
年轻人为主:
这就很完美的解释了为什么Solid
和Svelte
的受欢迎程度会那么高,年轻啊!折腾啊!你要是五六十岁了(在中国应该没有这个岁数的程序员了吧)你也不愿意折腾那些乱七八糟的。
数据来源:https://2021.stateofjs.com/en-US/libraries/front-end-frameworks/
Svelte
和Solid
已经成为流行框架\库\编译器了,有相当一部分叫好不叫座的,我们来看看npm
的数据:哎呀!暴露了暴露了,再来看看Google
搜索量:
Vue
和Angular
的差距已经越来越小了,当然还因为有股神秘的东方力量屏蔽掉了大部分去Google
搜索Vue
的,不然我相信Vue
的数据一定可以超越Angular
的。数据源自https://trends.google.com/trends/explore?cat=31&date=today%205-y&q=React%20javascript,Vue%20javascript,Angular%20javascript,Solid.js%20javascript,Svelte%20javascript
没想到对Svelte
最感兴趣的居然是韩国人!虽然三大框架YYDS
,但作为后起之秀并且在没有明显优势的情况下(综合情况,光写个Hello World
确实谁也比不过Svelte
)依然能够从三大框架嘴里分一杯小小的羹,并且还能够获得如此巨大的关注度,那就证明无虚拟DOM的趋势已经悄然兴起了。
为什么这玩意会成为一种趋势呢?有啥好处?好处就是性能!
什么?虚拟 DOM 不就是为了提升性能的吗?!是也不是,推荐读一下这篇:
[0]《网上都说操作真实 DOM 慢,但测试结果却比 React 更快,为什么?》
他们会火不是没有原因的,我们来看看他俩的性能:
可以用傲视群雄
这四个字来形容了,Vue
之前一直以高性能为傲,但被人超了怎么可能会甘心?毕竟Vue
和React
不一样,当数据更新时Vue
是知道该更新哪个组件的,React
不知道所以它只能用diff
算法,没有虚拟DOM
根本不行。那Vue
干嘛也要来一个虚拟DOM
呢?尤雨溪也是这么想的!
其实他早就有过放弃虚拟DOM
的想法了:在尤雨溪发表的《Vue3的设计过程》(翻译版)一文中,尤大说:一种选择是放弃虚拟 DOM
并直接生成命令式 DOM
操作,但这将消除直接编写虚拟 DOM
渲染功能的能力,我们发现这对高级用户和库作者非常有价值。
那时候Vue3
还没发布呢,Vue3
的createRenderer
就是利用虚拟DOM
来实现跨平台的,但成天老是跨平台跨平台的,我们平时开发业务又有多少跨平台项目呢?
现在追求的就是一个轻量级,没有了虚拟DOM
就没有了Diff
算法,不仅可以不用运行一些无谓的计算,而且打包出来的体积那可真是轻上加轻啊!它不香吗?
但也不能完全放弃虚拟DOM
啊,一方面虚拟DOM
还是有它大展宏图的场景的。另一方面你直接把虚拟DOM
删了,那些库怎么办?它们有多少是依赖虚拟DOM
的API
的呢?有多少组件库用的是jsx
呢:
去掉了虚拟DOM
的话,那些组件库是不是就用不了了呢?那咱们可以搞个模式出来嘛!
无虚拟DOM模式
我们都知道
Vue
是一个基于模板的框架,即使你能用jsx
能用虚拟DOM
,但大多数用户还是会用template
模板。
(挨个截图太麻烦了我就不截了,还浪费篇幅,我就直接写翻译了,感兴趣的话可以点进去视频链接[2]看)
由于
Vue
的大部分用户都用单文件组件来写代码,所以我们其实是有机会把组件编译成原生JS、CSS的。所以编译的这个步骤是有机会能让Vue
变成一个超级编译器的!这将会很有趣,所以我们想要探索一下新的编译策略,这也是受到了Solid.js
的启发。新的编译策略可以把template
模板编译成命令式的DOM
操作+响应式的setup
绑定以代替虚拟DOM
和render
函数。所以想象一下,当我们写了一个这样的组件:
(此处省略一些废话:这是script setup
语法、看这里有个button
按钮、我们给按钮绑定一个响应式的值之类的话)
我们生成的将会是这样的代码,生成出来的代码量非常少,目前的想法是我们过一遍虚拟
DOM
树然后生成真实DOM
的操作。我们会在编译期分析template
模板里的HTML
的结构并将其字符串化:
为了能让打包出来的内容最小化,去掉了结束标签以及各种绑定的属性。然后再生成一个
cloneNode
:
通过分析得出哪些属性是响应式的,把它们都放在
effect
里,再绑定事件,全部都是非常好理解的DOM
操作:
(这不比Svelte
生成出来的那一大坨好多了?)
两种模式
虚拟DOM模式
和无虚拟DOM模式
这两种模式,而是无虚拟DOM模式
下还可以继续再往下细分出来两种模式:组件模式
比方说你现在手里已经有了长期维护的Vue3
项目,你要是直接换成无虚拟DOM模式
那肯定是要出问题的,所以可以采用组件模式来精确控制哪些组件不需要虚拟DOM
。
比方说你的项目中采用了尤大推荐的naive-ui
这个组件库,我们打开一个比较常用的组件Button
来看一下:
tsx
结尾,那虚拟DOM
算是没跑了。不过tsx
也照样可以给改成生成真实DOM
的函数啊,solid.js
不就是这么干的吗?其实理论上来说确实是可以做到的,我们点进去再看一眼:
h
函数,这个函数是专门用来生成虚拟DOM
的,假如你把项目全部换成了无虚拟DOM模式
同时这些库还没来得及跟进的话,那肯定是不行的。所以你可以控制,你哪个组件里没用这个组件库,你再给这个组件单独的一个编译策略(无虚拟DOM模式
)。
既然有组件级的那就肯定有应用级的,比方说你想开发一个UI
高度定制化的H5
活动页。
一般来说这样的页面不会用组件库,都是自己写样式。另一方面这种活动页当然是越小越好,越快越好啦!那么此时你就可以采用全局无虚拟DOM模式
。
怎么感觉这是在抢Svelte
饭碗呢?我看技术论坛已经有人分享了自己用Svelte
来开发一些小页面的文章了,这回再有什么性能跑分之类的评测Vue
应该不会再输给Svelte
了(看情况,组件越少Svelte
越占优,反之则Vue
占优)
机遇与挑战
最近前端可谓是越来越卷了,你要是去面试稍微高级点的岗位的话,估计很可能会问你Vue
怎么编译的两种模式了(即使你并不感兴趣)。
但我发现很多人对自己做一款组件库非常感兴趣,从文章列表里看一下究竟有多少组件库相关的文章就能够一探究竟了。而且很多教大家搭建组件库的文章也是点赞量非常高,还有很多文章推荐自己做出来的组件库。
只可惜大部分个人做的组件库都是孤芳自赏,没几个人用。一方面的个人开发者可能随时删库跑路,不稳定。谁知道你写的那玩意有多少bug
呢?另一方面大家也更愿意用Star
非常多的组件库,证明其稳定。
所以大家如果想从主流组件库那里分一杯羹的话还是非常困难的。那现在这个无虚拟DOM
模式是不是就是一个千载难逢的大好时机?不过我个人依然感觉希望不大,因为那些主流组件库肯定会立马跟进,搞一款无虚拟DOM
适配版。
不过不管怎么说,我对这个实验性特性还是非常期待的。因为这个编译策略编译成web components
很可能会是一个非常不错的选择,总之,期待无虚拟DOM
的到来!
文章链接:
- EOF -
加主页君微信,不仅前端技能+1
主页君日常还会在个人微信分享前端开发学习资源和技术文章精选,不定期分享一些有意思的活动、岗位内推以及如何用技术做业余项目
加个微信,打开一扇窗
觉得本文对你有帮助?请分享给更多人
推荐关注「前端大全」,提升前端技能
点赞和在看就是最大的支持❤️