Blog
Making Plate.js Static Render Fast - From 30 Seconds to 300ms
Dmytro Bondarchuk|May 13, 2026|11 min read|No commentsThe blog on bondarchuk.me runs on timeli.sh - specifically on its blog app, which stores posts as Plate.js JSON and renders them server-side on public pages using PlateStatic, the read-only renderer that ships with @udecode/plate. For short posts this works fine. For longer posts - like the payment integration write-up with multiple code blocks, tables, and several thousand words - the initial page load was taking around 28-32 seconds. During that time, one CPU core was pegged and the Node.js process was blocked from serving anything else.
This post is the story of two attempts to fix it. The first brought the time down to around 7.5-8.5 seconds with a visual shimmer to mask the wait. The second brought it down to around 280-320ms and removed the shimmer entirely.
PlateStatic renders a Plate document by walking the node tree and dispatching each node to its registered static element component - a React component per node type (paragraph, heading, code block, link, bold leaf, etc.). For a long post with hundreds of nodes, that means a very large React component tree: every paragraph, every heading, every code line, every text span with a mark becomes a React element.
The expensive part is not initialization - it is the React render itself. PlateStatic produces a deeply nested tree and React has to reconcile the whole thing in one synchronous pass. On the server, Next.js renders this tree to an HTML string. For a document with 80-100 top-level blocks, each containing multiple inline nodes, the total node count can reach into the thousands. React walks every one of them, calls every function component, resolves every className, and serializes the result to HTML before the response can be sent.