Reference guide · html-css-js · Published 2026-08-16 · 3 min read
The PRPL pattern for faster initial page loads
PRPL pattern (push, render, pre-cache, lazy-load) to speed up first meaningful paint in JavaScript-heavy sites.
- ·Understand the steps
- ·Push critical assets
- ·Pre-cache and lazy-load
PRPL describes a strategy for loading a fast first meaningful paint in JavaScript-heavy web apps. The letters stand for Push critical resources, Render the initial route, Pre-cache the remaining routes, and Lazy-load the rest on demand.
Understand the steps
- Push critical resources. Ship or reference the smallest critical CSS and the code the first screen needs as early as possible, so the browser can render without waiting for the whole bundle.
- Render the initial route. Optimise the render of the route the user first lands on, using critical rendering path ordering, so a usable first paint happens quickly.
- Pre-cache remaining routes. Use a service worker to pre-cache assets for routes and shells users are likely to take next, so subsequent navigations hit the cache (see service worker caching).
- Lazy-load the rest. Load less-important routes, components and below-fold content only when needed, such as through route-level code splitting and on-demand component loading.
Push critical assets
- Inline the critical CSS. The styles above the fold can be inlined and the full stylesheet deferred, so the first paint does not wait on a render-blocking
<link>. This is the same idea as critical CSS. - Ship only what the route needs. Split your JavaScript by route so each route loads the module it requires instead of the full application bundle.
- Keep the entry small. Reduce your initial payload with tree-shaking and by moving third-party libraries to on-demand or preconnect-optimised delivery.
Pre-cache and lazy-load
- Register a service worker early. Register the worker with
navigator.serviceWorkerafter initial load and start pre-caching the app shell and high-likelihood routes in the background. - Pre-cache, do not just cache. Loading likely-next assets during idle time (for example using requestIdleCallback) turns a cold navigation into a cache hit.
- Lazy-load below the fold. The content-visibility CSS property and lazy media loading let you defer work for parts of the page the user has not reached.
- Use it for view-based apps. PRPL is especially suited to app shells and single-page applications where subsequent "pages" are route components. For traditional multi-page sites, the concepts still apply route by route, but the biggest wins come from the push-and-render half.
Prevention
- Measure before and after. Verify that a change actually shifted the first meaningful paint rather than building trust in a pattern blindly. Use the page speed diagnosis workflow to compare.
- Avoid over-caching. Pre-caching too many assets wastes bandwidth and storage, so pre-cache a handful of likely routes, not the whole site, and cap the cached set.
- Keep the shell light. The app shell should stay minimal, because it is the part that must load first for every route.