文章目录
- SolidJS:抛弃虚拟 DOM 的前端框架
- 它怎么工作的
- 关键特性
- 和 React 的区别
- 适合什么场景
SolidJS:抛弃虚拟 DOM 的前端框架
过去十年,虚拟 DOM 几乎成了前端框架的标配。React 带火了这个概念,Vue、Preact 等纷纷跟进,开发者也逐渐把虚拟 DOM 视为性能优化的标准答案。SolidJS 走了另一条路:它没有虚拟 DOM,而是在编译阶段就把 JSX 转换成真实 DOM 操作,运行时只做最小粒度的更新。
SolidJS 在 GitHub 上有超过 3.5 万个 Star。这个数字说明,相当多的开发者对"不用虚拟 DOM"这件事感兴趣。
它怎么工作的
SolidJS 的核心机制是细粒度响应式。写代码时你用createSignal声明状态,框架会自动追踪哪些地方用到了这个状态。当状态变化时,只有依赖它的那段代码会重新执行,整个组件函数不会重新运行。
看一个计数器的例子:
import{createSignal}from"solid-js";functionCounter(){const[count,setCount]=createSignal(0);constdoubleCount=()=>count()*2;return(<button onClick={()=>setCount(c=>c+1)}>Increment:{doubleCount()}</button>);}这段代码里,count是一个信号,doubleCount是派生状态。点击按钮后,只有doubleCount()这个表达式会重新计算,按钮的其余部分保持不动。组件函数本身只执行一次。
SolidJS 的编译器会把 JSX 转成高效的 DOM 操作。静态 HTML 被提前提取为模板,动态部分通过insert等方法进行局部更新。生成的代码接近手写原生 JavaScript 的水平。
关键特性
细粒度更新:没有虚拟 DOM diff,没有组件级重渲染。状态变化直接映射到 DOM 操作,跳过了中间的比较步骤。
声明式数据流:用响应式原语建模状态,自动处理依赖追踪。你不需要手动指定哪些组件需要更新。
单次渲染模型:组件函数只执行一次,后续更新由响应式系统驱动。这和 React 的"每次状态变化都重新执行整个组件"有本质区别。
体积小、速度快:SolidJS 的核心包体积很小,完全支持 tree-shaking。在 JS Framework Benchmark 中,它的性能接近原生 JavaScript。
现代功能齐全:JSX、Fragments、Context、Portals、Suspense、流式 SSR、渐进式水合、错误边界、并发渲染,主流框架该有的它都有。
调试友好:在浏览器开发者工具中,你看到的<div>就是真实的 div,不是虚拟节点。这让 DOM 调试变得直观。
和 React 的区别
SolidJS 用 JSX 写法,表面上和 React 很像,但底层逻辑完全不同。
React 中,组件函数在每次状态更新时都会重新执行。useState 返回的值是快照,React 通过重新调用组件函数来生成新的虚拟 DOM,然后做 diff。这意味着即使你只改了一个计数器,整个组件树的相关部分都会重新执行。
SolidJS 中,组件函数只执行一次。createSignal 返回的是响应式引用,状态变化时只有真正读取了这个信号的代码才会重新运行。没有重新执行、没有虚拟 DOM、没有 diff。
举个具体场景:一个列表组件里有 1000 个条目,你修改了其中一个条目的标题。React 会重新执行列表组件函数,生成新的虚拟 DOM 树,然后找出变化的那个节点。SolidJS 只会更新那一个标题对应的 DOM 文本节点。
适合什么场景
SolidJS 适合对性能有要求的项目。如果你的应用有大量的动态内容、频繁的状态更新、或者复杂的列表渲染,SolidJS 的细粒度更新能带来明显的性能提升。
它也适合喜欢 React JSX 语法但对重渲染机制不满的开发者。SolidJS 的心智模型更简单:状态变了,用到它的地方就更新,没用到的就不动。
SolidJS 生态在持续发展。社区提供了响应式原语库 solid-primitives、组件库 Kobalte、以及各种构建时工具。TypeScript 支持也很完善,配置 JSX 的jsxImportSource指向solid-js即可。
快速上手可以用脚手架:
npx degit solidjs/templates/js my-app cd my-app npm install npm run devSolidJS 的设计哲学是"用更少的抽象做更多的事"。组件就是函数,渲染完全由状态的使用方式决定,没有隐藏规则。这种务实的态度,加上接近原生的性能表现,让它在前端框架的竞争中占据了一个独特的位置。
更多的事"。组件就是函数,渲染完全由状态的使用方式决定,没有隐藏规则。这种务实的态度,加上接近原生的性能表现,让它在前端框架的竞争中占据了一个独特的位置。