Fine‑Grained Reactivity in SolidJS: How Signals and Memos Deliver Targeted DOM Updates
SolidJS eliminates the Virtual DOM by using signals and memos for fine‑grained reactivity. Learn how to create targeted DOM updates, avoid common pitfalls like destructuring props, and verify your component’s behavior in the browser’s Elements tab.
30 Jan 2026, 06:07 UTC

Concrete Problem: Unnecessary Re‑renders in a Simple Counter
When building a counter component, many developers fall back to a state hook that returns a whole object. Updating the count then forces the entire component tree to re‑render, even if only a single <span> actually needs to change. In a large UI, this can lead to visible lag and wasted JavaScript work.
Thesis: SolidJS’s Signals and Memos Give You a Tiny, Targeted Update Instead of a Virtual DOM Diff
SolidJS compiles JSX into direct DOM manipulation code. Coupled with its fine‑grained reactivity primitives—createSignal for state and createMemo for derived values—only the DOM nodes that depend on a changed signal are touched. This eliminates the overhead of a Virtual DOM diff and gives you predictable, minimal updates.
Signals: The Building Blocks of Reactivity
A signal is a pair of getter/setter functions that automatically track which parts of the UI read the value. When the setter is called, SolidJS walks a dependency graph and updates only the subscribed nodes.
import { createSignal } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0);
return (
<div>
<button onClick={() => setCount(count() + 1)}>Increment</button>
<span>Count: {count()}</span>
</div>
);
}
In the example above, only the <span> that displays {count()} will be updated when setCount is called. The <button> remains untouched.
Memos: Cache Expensive Derivations
When you need to compute a value that depends on one or more signals, createMemo caches the result and only recomputes when its dependencies change. This is especially useful for formatting, filtering, or expensive calculations.
import { createSignal, createMemo } from 'solid-js';
function FizzBuzz({ num }) {
const [value] = createSignal(num);
const fizzBuzz = createMemo(() => {
const n = value();
if (n % 15 === 0) return 'FizzBuzz';
if (n % 3 === 0) return 'Fizz';
if (n % 5 === 0) return 'Buzz';
return n;
});
return <div>{fizzBuzz()}</div>;
}
Only the <div> that renders {fizzBuzz()} will re‑render when num changes. The memo itself is invisible to the DOM, but its recomputation cost is capped to its dependencies.
Verification Checklist
- Open the browser’s Elements panel while the component is rendered.
- Trigger a state change (e.g., click the button).
- Observe that only the text node inside the
<span>is updated; the surrounding<div>and<button>nodes remain untouched. - Use
console.loginside acreateMemoand confirm it runs only when its signal changes.
Common Pitfall: Destructuring Props Breaks Reactivity
Because createSignal returns a getter that must be called, destructuring a prop that is itself a signal will invoke the getter once during component initialization, losing the reactive link.
// ❌ Bad – loses reactivity
function BadComponent({ value }) {
const [val] = value; // value is a signal
return <div>{val()}</div>;
}
Instead, keep the signal reference and use it directly:
// ✅ Good – keeps reactivity
function GoodComponent(props) {
return <div>{props.value()}</div>;
}
Trade‑Off: Manual DOM Manipulation Requires Care
Because SolidJS skips a Virtual DOM, developers must avoid direct DOM mutations that conflict with the reactive system. For example, mutating an element’s style outside of a reactive context can cause the framework to overwrite that change on the next update cycle. Stick to Solid’s declarative syntax or wrap imperative changes in createEffect with a clear dependency list.
Actionable Takeaway
To harness fine‑grained reactivity in your next SolidJS project:
- Use
createSignalfor every piece of state that the UI reads. - Wrap expensive derived values in
createMemoto avoid unnecessary recomputation. - Never destructure signal props; pass the signal itself and call it in the template.
- Verify selective updates by inspecting the Elements panel during interaction.
- When manipulating the DOM imperatively, encapsulate changes inside
createEffectand keep dependencies explicit.
With these practices, you’ll enjoy the performance benefits of SolidJS’s fine‑grained reactivity while keeping your code readable and maintainable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.