React: Concurrent Rendering
GITHUB
Concurrent rendering is a way of scheduling rendering work.
The developer tells React which updates are more important and which are less important.
Since React runs on JavaScript, there is only one main thread.
Imagine a kid building a Lego city.
While building it, his sister falls down. He pauses building the Lego city (lower priority), helps his sister (higher priority), and then resumes building the city.
React example
Consider two state updates
The text the user types must appear immediately
The computed results can appear with a slight delay
So we tell React:
Treat updates that affect the input value as high priority
Treat updates that render derived or expensive results as low priority
If React is busy rendering less important work and a high-priority update arrives, React can pause or abandon the low-priority rendering, update the input immediately, and then resume the less important work later.
Example:const [text,setText] = useState("");
const [query,setQuery] = useState("");
const [isPending, startTransition] = useTransition();
const items = useMemo(() => {
return Array.from({ length: 20000 }, (_, i) => `Item ${i} - ${Math.random()}`);
}, []);
const filtered = useMemo(() => {
let result = items;
for (let i = 0; i < 400; i++) {
result = result.filter((x) => x.includes(query));
}
return result;
}, [items, query])
return (
<>
<div>
{isPending ? "Filtering..." : `Results: ${filtered.length}`}
</div>
<input type="text" value={text}
onChange={(e) => {
const val= e.target.value;
setText(val); //urgent
startTransition(() => {
setQuery(val); //non-urgent
})
}}
/>
<ul>
{filtered.slice(0, 200).map((x) => (
<li key={x}>{x}</li>
))}
</ul>
</>
)
setQuery(data);
});
You are explicitly telling React:
Concurrent rendering is a way of scheduling rendering work.
The developer tells React which updates are more important and which are less important.
Since React runs on JavaScript, there is only one main thread.
Imagine a kid building a Lego city.
While building it, his sister falls down. He pauses building the Lego city (lower priority), helps his sister (higher priority), and then resumes building the city.
React example
Consider two state updates
- State update for the text typed in the input box
- State update for the computed results based on the input
The text the user types must appear immediately
The computed results can appear with a slight delay
So we tell React:
Treat updates that affect the input value as high priority
Treat updates that render derived or expensive results as low priority
If React is busy rendering less important work and a high-priority update arrives, React can pause or abandon the low-priority rendering, update the input immediately, and then resume the less important work later.
What useTransition is NOT doing:
It does not make code async
It does not run code on another thread
It does not speed up computations
It does not affect network calls
It only affects rendering priority.
Example:
const [query,setQuery] = useState("");
const [isPending, startTransition] = useTransition();
const items = useMemo(() => {
return Array.from({ length: 20000 }, (_, i) => `Item ${i} - ${Math.random()}`);
}, []);
const filtered = useMemo(() => {
let result = items;
for (let i = 0; i < 400; i++) {
result = result.filter((x) => x.includes(query));
}
return result;
}, [items, query])
return (
<>
<div>
{isPending ? "Filtering..." : `Results: ${filtered.length}`}
</div>
<input type="text" value={text}
onChange={(e) => {
const val= e.target.value;
setText(val); //urgent
startTransition(() => {
setQuery(val); //non-urgent
})
}}
/>
<ul>
{filtered.slice(0, 200).map((x) => (
<li key={x}>{x}</li>
))}
</ul>
</>
)
Summary:
startTransition(() => {setQuery(data);
});
You are explicitly telling React:
- This update can be deferred
- This update can be interrupted
- This update can be dropped if something newer comes in
- React then schedules that update at a lower priority.
Comments
Post a Comment