惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

W
WeLiveSecurity
Jina AI
Jina AI
博客园 - 司徒正美
雷峰网
雷峰网
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园_首页
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
I
InfoQ
博客园 - Franky
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
Cyberwarzone
Cyberwarzone
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
P
Privacy & Cybersecurity Law Blog
T
Threatpost
Cloudbric
Cloudbric
D
Docker
M
MIT News - Artificial intelligence
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Vercel News
Vercel News
Martin Fowler
Martin Fowler
J
Java Code Geeks
AWS News Blog
AWS News Blog
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
L
Lohrmann on Cybersecurity
Hacker News: Ask HN
Hacker News: Ask HN
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
V
V2EX
博客园 - 【当耐特】
I
Intezer
爱范儿
爱范儿
F
Fortinet All Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Privacy International News Feed
IT之家
IT之家
L
LINUX DO - 最新话题
B
Blog RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

Secret Weblog

Becoming More Xee: A Modern XPath and XSLT Engine in Rust Looking for new challenges! Repeat Yourself, A Bit The Curious Case of Quentell The Humble For Loop in Rust The Humble For Loop in JavaScript Don Question Best Practices I Was a 1980s Teenage Programmer Part 5: Achieving Assembly I Was a 1980s Teenage Programmer Part 4: The Call of Assembly The Tooling Shift I Was a 1980s Teenage Programmer Part 3: MSX-2 JavaScript: when you need two ways to do it! Empowering Programming Languages Bloat and Retrofuturism Refreshing my Blog Again Random Rust Impressions Apilar: An Alife System I Was a 1980s Teenage Programmer Part 2: Olivetti M24 I Was a 1980s Teenage Programmer: the Alphatronic Is premature optimization the root of all evil? Framework Patterns: JavaScript edition Roll Your Own Frameworks Framework Patterns Secret Weblog Highlights Refactoring to Multiple Exit Points mstform: a form library for mobx-state-tree Seven Years: A Very Personal History of the Web Morepath 0.16 released! Is Morepath Fast Yet? Introducing Bob Strongpinion Punctuated Equilibrium in Software Morepath 0.15 released! Impressions of React Europe 2016 Morepath 0.14 released! Morepath 0.13 now with Dectate Dectate: advanced configuration for Python code JavaScript Dependencies Revisited: An Example Project The Incredible Drifting Cyber A Brief History of Reselect The Emerging GraphQL Python stack Thoughts about React Europe Build a better batching UI with Morepath and Jinja2 GraphQL and REST Server Templating in Morepath 0.10 10 reasons to check out the Morepath web framework in 2015 A Review of the Web and how Morepath fits in Morepath 0.9 released! Better REST with Morepath 0.8 Morepath 0.7: new inter-app linking They say something I don Life at the Boundaries: Conversion and Validation BowerStatic 0.4 released! Morepath 0.6 released! Morepath 0.5(.1) and friends released! New HTTP 1.1 RFCs versus WSGI Against On Naming In Open Source My visit to EuroPython 2014 Morepath 0.4.1 released (with Python 3 fixes) Morepath 0.4 and breaking changes Announcing BowerStatic Morepath 0.3 released! Morepath 0.2 Morepath Python 3 support The Call of Python 2.8 Morepath 0.1 released! WebOb and Werkzeug compared Morepath: from Werkzeug to WebOb Racing the Morepath: SQLAlchemy Integration The Centre Cannot Hold Breaking Morepath Changes Morepath Update How to do REST with Morepath Morepath Security the Gravity of Python 2 #python2.8 discussion channel on freenode Alex Gaynor on Python 3 Morepath Documentation Starting to Take Shape Back to the Center Morepath App Reuse Implementing Grok Grok: the Idea Why Linux Works for Me On the Morepath Reg, Now With More Generic! The New Zope as a Web Framework Jim Fulton, Zope Architect Renewing Zope Object Publishing The Weirdness of Zope The Rise of Zope My Exit from Zope Reg: Component Architecture Reimagined JSConf EU 2013 impressions Obviel 1.0! JS Dependency Tools Redux Obviel 1.0rc1 released! Succinct data structures
SolidJS fits my brain
Martijn Faassen · 2022-07-14 · via Secret Weblog

In this article I'm going to talk about the SolidJS frontend framework, and why I think it's cool and fits my brain.

React

I got interested in React because of a talk by Pete Hunt at JSConf Europe back in 2013. React was a baby then, a controversial baby, and this talk convinced me and many others to give it a serious look. What did I learn?

React had a very nice approach to fine-grained declarative components, and the use of a virtual DOM, even though de-empathised now, was a revelation. I gave up my own efforts on a frontend framework and switched to React instead.

State management

State management on the client is something I was interested in already. With React I went through the pre-flux era, flux and Redux. I thought Redux was cool, but I did find state management with Redux to be rather verbose. Newer layers above it have since softened these drawbacks.

Redux heavily leans on the immutability paradigm: you never change state, but you create a new version of it instead with each change. This brings some benefits, and one is related to performance: you can skip updating a particular UI component in your program entirely if you know the data you sent to it hasn't changed. You don't have to regenerate its virtual DOM or have to do any updates in the live DOM in that case. Immutable data has the interesting property that it lets you determine it hasn't changed with a very cheap comparison operation.

In 2016 I learned about MobX. This takes a very different approach: it's Key Value Observable (KVO). Basically MobX just lets you create objects and classes, annotate them very lightly to mark which data is observable, and then it tracks state changes in a fine-grained manner. If you update a property on an observed object, MobX updates only those React components that use it. Any other components are left alone. You don't need to think about it: it just works. Updates are more fine-grained than with Redux with less effort. It seemed like magic to me. In fact I recall spending a day at a React Europe hackathon trying to understand its magic when I first encountered it.

In 2017 I started using MobX for a real project, and I've been happy with it ever since. On occasion I've looked at other state management systems for React (including the built-in hooks), but nothing could compare with the ease of use and power of MobX.

The Genesis of SolidJS

This capsule history is a vague impression more than an accurate historical reconstruction, but it appears Ryan Carniato, the creator of SolidJS, also was impressed by MobX, and KVO frameworks in general. As I mentioned, React uses a virtual DOM - your React component produce a state tree, and this is then used to update the real browser DOM, only changing what is actually different. Ryan had the brilliant insight you could use a KVO framework directly to update DOM. This way you get fine-grained updates of the UI entirely skipping the virtual DOM. This lead to the development of SolidJS.

SolidJS Performance

The SolidJS approach turned out to be fast: according to various benchmarks SolidJS performs near the speed of hand-optimized DOM manipulation.

Does performance matter a lot? It's complicated.

React is fast enough for most purposes, and frameworks tend to engage in performance matches as it's an easy benchmark to compare. Users of frameworks like to use performance to evaluate frameworks far more than they should. Then again, performance can also be reflective of good design, and it's important a framework doesn't lead you into performance pitfalls. And low-powered devices are common especially in the mobile phone world, and higher performance approaches use less energy.

Raw performance of a framework isn't everything: developer usability matters. The fastest framework is no framework at all. But we use frameworks for a reason, and the reason is not performance, it's developer usability.

So let's look at developer usability next.

Solid and React as frameworks

What's important in a framework is that it gives you the tools to build your application well, keeping a lot of tradeoffs in mind: how easy is it to reason about, speed of development, maintainability, evolvability, and, yes, performance.

What does React do for you as a framework? It lets you avoid thinking about DOM updates. You can just pretend it's like a server-side framework, and that all your declarative function components get re-run each time you change any data and that this describes the new state of the UI, even though that doesn't really happen underneath and it can skip a lot of those steps as an optimization. It's easy to reason about and it helps the code that uses it stay maintainable and performant, and that's what makes it valuable to use it as a framework.

Solid looks and feels a lot like React, even though it's very different underneath. It offers fine-grained components you define like functions that take props and return JSX, just like modern React. It has functions that look a lot like React hooks; useState becomes createSignal, useMemo becomes createMemo, and useEffect becomes createEffect. Solid was immediately familiar to me as a React user.

How Solid is different from React

But Solid does a few things differently. You don't need to declare any dependencies for hooks, unlike in React. It does dependency tracking, so that when a value changes, any hooks that use that value run automatically. This is a great feature, as suddenly you don't need to think about it anymore. The subtleties of hooks in React are tricky. On top of this, Solid offers an easy way to integrate with server APIs with createResource.

React with MobX goes a step above plain React in ease of use and optimization -you can treat state as mutable, and MobX tracking is so clever only those React components rererender that use the state you changed. Solid has that built in. Solid has createStore which lets you define observable objects with fine-grained reactivity, much like MobX does.

Solid then takes this a step further; the update is not a rerender of the component (rerunning the function) but of a much finer granularity: when you change a value that's used in an expression in JSX somewhere, only that expression gets rerun and results in a DOM update.

With Solid, just like React, you can also, sort of, pretend it's like a server-side framework, and that all your JSX re-runs whenever you change any data. But in fact the function components don't get rerun. They only run once, when the component is created in the tree. That has some differences with React code:

  • You can't unpack props like is common with React, as props is a reactive object. This means in JSX you need to write <div>{props.foo}</div>.
  • You can't put a console.log in a component body and expect it to re-run in each update. Instead you need to place it in a function that is used in a JSX expression somewhere, or use createEffect.

What you get from this, besides performance, is easy to reason about behavior. Create functions, the equivalent of hooks, are just functions. They run once per component, though the functions you pass them are reactive. So can use create functions anywhere you like, such as in conditional expressions and loops. You don't even have to put them in the function component.

The granularity of components can be a subtle aspect of React performance optimization -- more components can support more fine-grained updates. But in Solid, this matters a lot less - you can make your components as big or small as you like and it won't make much of a difference.

My experience with Solid

After playing with Solid for a couple of months I've used it for real projects for the first time over the last month. I found it easy to think in Solid. Only very rarely has Solid surprised me unpleasantly. Refactoring and extending code was easy and it let me do what I wanted. The TypeScript support is also good. It's a subjective experience, but it fits my brain!

I haven't even talked about bundle size yet, but it was definitely neat when my entire Solid project's bundle is half the size of the react-dom bundle by itself. And Solid manages to pack a powerful state management framework in along the way!

Solid has a few basic principles you need to be aware of, but its API has quite a few knobs and possibilities. Luckily I didn't need to understand all of them to be able to use Solid effectively. And once every while when I ran into a new problem I recalled reading something about it in the API manual that I only half understood at the time, and suddenly it clicked and helped me solve the problem.

Last week I built a little library solid-dexie that integrates Solid with Dexie, an API on top of IndexedDB that's built into the browser. Dexie offers live queries, a form of reactivity to the contents of the database - when you add or modify a record the query result, and the UI that depends on it, automatically updates. Dexie also has React integration in the form of a dexie-react-hooks package. In my library, I figured out how to integrate it with Solid with a few lines of code -- it took a bit of headscratching but it's pretty neat!

Are there any drawbacks to Solid compared to React? There's one big one: the ecosystem of SolidJS is much smaller. React has an enormous range of libraries on offer that do all sorts of things. For Solid it's more limited. What is out there for SolidJS in its ecosystem is pretty good, as it has the benefit of refining the best ideas from the React ecosystem, but the ecosystem needs more time to grow. For some projects this drawback will outweigh the benefits. I love the benefits though, so I am going to look for more opportunities to use Solid in the future.

Iain Simmons

This is a great write up, and it's nice to hear this from a more personal and practical standpoint instead of the usual pros and cons and frameworks competing on arbitrary criteria.

I've also been learning a lot about Solid and hope to be able to use it in my day-to-day work soon.