SolidJS 2.0 Beta:一级异步支持、重构的 Suspense 与确定性批处理
来源: InfoQ 话题 - 大前端
SolidJS是一款基于细粒度响应式编程的JavaScript框架,最近发布SolidJS 2.0 Beta版本,对其异步处理、响应式模型和开发体验进行了全面重构。团队在Experimental阶段进行了长时间迭代,直接跳过了原计划的Alpha阶段,创建者Ryan Carniato在讨论中指出:“Alpha中的大多数里程碑似乎不足以单独构成一个阶段。”
Solid 2.0的核心变化是异步成为一级特性。计算可以返回Promise,响应式图会自动处理挂起与恢复。这意味着开发者可以将Promise直接传入createMemo并交给框架管理,减少了以往所需的大量手动编排工作。同时,Loading已被重构为仅处理初始就绪状态:子树首次加载时显示fallback,后续更新期间保持UI稳定。Pending状态现在通过isPending(() => expr)表达,而不是拆毁并重建界面。
变更(mutations)操作也获得了专用原语。新的action()函数与createOptimisticStore结合,使开发者可将乐观更新、服务端写入和数据重新验证表达为一个统一的流程。派生状态通过函数形式(如createSignal(fn)和createStore(fn))成为了一级原语。更新现在采用微任务批处理,读取仅在调用flush()后才更新,使调度模型完全实现了确定化。
本次发布包含若干破坏性变更。Index被替代,For子项现在接收accessor。createEffect被拆分为独立的compute和apply阶段,onMount被onSettled替代,store的setter默认采用draft-first语义。use:指令系统被移除,改为使用ref指令工厂。
在Reddit上,有用户对异步成为一级特性表示积极评价:
对async成为一级公民这件事,我感到非常如释重负、非常开心。我虽然还没实际试过,但示例里的模式看起来用起来会非常顺手。
另一位评论者也表达了类似观点:
2.0中对异步原语的整理看起来非常周到。就我个人而言,Solid一直有所有JS框架中最好的响应式模型——真正的细粒度更新,而且没有虚拟DOM。
完成TanStack Start和SolidStart到2.0迁移的开发者Brenelz在其文章中写道,“异步模型感觉更好,响应式改动也很有思考”,并指出旧版Suspense行为“在把UI突然拿走时会有些突兀”。
在Github讨论中,有评论对createEffect的改动提出了担忧:
单函数createEffect在实践中表现很好。自动依赖跟踪覆盖了大多数使用场景,像Vue.js和Svelte这样的框架也提供了基于自动依赖跟踪的原语。
切换到新的分阶段API感觉有些笨重,也让诸如根据A来跟踪B或C这类模式更难表达,嵌套响应式逻辑也不如自动跟踪时清晰……
另外还有关于“flush后值更新(value updates after flush)”的担忧:
……我还担心flush后再更新值会引入不一致读取。写入signal不会立即影响后续读取,这迫使开发者把响应式值与普通变量区别对待,打破了Solid 1.x直观的心智模型。
对此,SolidJS作者Ryan在讨论中回应:
我知道这些地方会让人难以接受。但我做这些选择不是出于偏好……我花了一年多时间研究它们,最后无法回避这个现实,就像无法逃避物理规律一样。真相是,如果你想获得一致的async,这两点都必不可少。
…
这两种行为最终会导向更简洁、更连贯的设计,因为我们建立了正确边界并设定了正确预期。在这个过程中,库吸收了大量复杂性。真正美妙之处在于,如果这些模式被正确使用,你会发现几乎不再需要频繁使用createEffect。
与React相比,SolidJS仍通过其完全绕开虚拟DOM的细粒度响应式模型保持差异化。
想尝试Beta的开发者可参考团队提供的迁移指南(覆盖从1.x的迁移),SolidStart用户可参阅针对该元框架的单独指南。该Beta已通过npm的next标签发布,可运行npm install solid-js@next @solidjs/web@next安装。
SolidJS是由Ryan Carniato创建并维护的开源JavaScript框架。它基于细粒度响应式实现高性能UI渲染且无需虚拟DOM,适合寻求类似React开发体验但希望显著降低运行时开销的开发者。
查看英文原文:SolidJS 2.0 Beta: First-Class Async, Reworked Suspense and Deterministic Batching