Preact JSX and Rendering — Components in 3kB
Learn how Preact handles JSX compilation, component rendering, and DOM updates with a minimal virtual DOM diffing algorithm that keeps the library at 3kB.
In this lesson, you'll understand how Preact processes JSX, how the render function works, and how Preact's virtual DOM differs from React's.
What You'll Learn
How Preact compiles JSX, how the render() function mounts and updates the DOM, and how Preact's simplified diff algorithm works under the hood.
Why It Matters
Understanding Preact's rendering model helps you write efficient components. Preact skips many of React's internal abstractions to reduce bundle size, which means some rendering behaviors differ subtly.
Real-World Use
Preact renders UI components inside DodaZIP's file extraction progress bars. The minimal diff algorithm ensures smooth updates even when the UI refreshes every 100ms during extraction.
flowchart LR
A[JSX Code] --> B[Preact Compiler]
B --> C[Virtual DOM Tree]
C --> D[Differential Algorithm]
D --> E[Real DOM Updates]
style B fill:#673ab8,color:#fff
JSX in Preact
Preact uses the same JSX syntax as React. Babel or TypeScript compiles JSX into h() function calls (Preact's equivalent of React.createElement).
// JSX code
const element = <h1>Hello, world!</h1>;
// Compiled output
const element = h('h1', null, 'Hello, world!');
The h() function creates virtual DOM nodes, which are plain JavaScript objects describing the DOM structure.
The render() Function
Preact's render() mounts a component into the DOM:
import { render } from 'preact';
render(<App />, document.getElementById('app'));
Unlike React's createRoot().render(), Preact's render() takes the component and container directly. The first call mounts the component, and subsequent calls update it.
Component Rendering
function Greeting({ name }) {
return <p>Welcome, {name}!</p>;
}
render(<Greeting name="Alice" />, document.getElementById('app'));
Output: The paragraph <p>Welcome, Alice!</p> appears in the DOM. The component receives name as a prop and returns JSX that Preact renders.
Virtual DOM Diffing
Preact uses a simplified diff algorithm with these rules:
- Components of the same type are updated in place
- Components of different types are unmounted and remounted
- Keys control element identity in lists
- Class and style attributes are diffed smartly
function Timer({ seconds }) {
return <div>Elapsed: {seconds}s</div>;
}
// First render
render(<Timer seconds={0} />, document.getElementById('app'));
// Output: <div>Elapsed: 0s</div>
// Update with same component type
render(<Timer seconds={5} />, document.getElementById('app'));
// Output: <div>Elapsed: 5s</div>
// The same DOM node is reused and only the text updated
Common Mistakes
- Using
classNameinstead ofclass: Preact supports both, butclassis preferred and consistent with HTML. React requiresclassName. - Expecting
React.StrictMode: Preact doesn't implementStrictMode. Use Preact's DevTools for debugging instead. - Assuming Fragments work identically: Preact supports
<></>fragments, but they compile differently. ImportFragmentfrompreactfor explicit fragments. - Using
dangerouslySetInnerHTMLincorrectly: The API is the same as React:dangerouslySetInnerHTML={{ __html: content }}. Forgetting the__htmlwrapper crashes. - Not understanding hydration: Preact's
hydrate()differs from React's. Useimport { hydrate } from 'preact'for SSR hydration, notrender().
Practice Questions
What function does Preact use instead of
React.createElement? Answer:h()frompreact. It creates virtual DOM nodes (VNodes).How does Preact's render differ from React 18's render? Answer: Preact uses
render(<App />, container)directly withoutcreateRoot(). The function handles both initial mount and updates.Can you use
classNamein Preact? Answer: Yes, but Preact prefersclasssince it matches HTML. Both work for compatibility.What determines whether Preact reuses a DOM node? Answer: The component type at the same position in the tree. Same type = update in place. Different type = unmount + remount.
Challenge
Create a component that renders a list of items. Add a button to remove the first item and observe how Preact handles the list update. Compare the behavior with and without key attributes.
Mini Project
Build a live clock component that updates every second using setInterval and render() updates. Measure how many DOM mutations occur compared to the number of renders.
FAQ
What's Next
Continue to Preact Components to learn how to build reusable component trees with Preact's component model.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro