Improving Headless load times – Server Side Rendering Update
PWA / Headless with Magento.
PWA and Headless started with a lot of hype and promises. Many websites have benefited from successful implementations that proves many promises were fulfilled.
However, one of the biggest drawbacks of a headless / PWA implementation of a Magento website is the page load times - especially as reported by tools and metrics not tuned for the benefits.
A key benefit headless offers is improved navigation experience, but that is not measured, even by some Real User Monitoring (RUM) tools.
Headless makes sense - almost imperative - in many cases such as a large changing catalog (we have a customer with 700k products with 1k new product uploads and additional 1k product updates daily).
While navigating, a graphql is responsible for updating the page with content and it returns only the data asked for, which can be cached across all users. For uncached catalog graphqls, the Elastic Search is most crucial part of the system for performance, but a lot of php formatting such a the menu, that went along with it is now eliminated.
This has to be a better system. So, where does it go wrong?
Issues with headless that causes speed problems
- Large js (the application) that needs to be loaded before any content can be painted
- Too many graphql fragments. A framework has to decide what graphql is too small that the number of graphql calls will increase. PWAStudio is a prime negative example.
- Session locks in Magento graphqls
- Use of POST graphqls which are not easily cacheble in varnish. Traditionally graphqls are served in POST to avoid hitting url size limits. URL are limited by the browser with 2048 considered a limit at the lower end. But, most Magento frontends generate URLs much smaller than the 2k limit and can easily use GET for queries and
These reasons and SEO requires a good implementation of SSR - Server Side Rendering
What is Server Side Rendering (SSR)
- A headless implementation is written with a browser in mind - one that can load javascript and render the content. This is Client Side Rendering.
- A Server Side Rendering will render the page on the server side - much like a regular Magento theme might do - and return HTML
SSR has 2 flavors
- SSR that serves HTML without the javascript. This HTML will have no interactivity. Usable only for SEO purposes.
- SSR that "hydrates" the HTML on the browser - by adding the events to the html and also perhaps bootstraps the application itself so it is interactive
React 18 and SSR
Headless technologies written with React have an opportunity to leapfrog the site performance by upgrading to React 18 and using the SSR features
- Suspense component. This allows specifying a part of the UI to be in loading state. Through this react knows the page is yet being loaded.
- renderToPipeableStream API. Allows HTML to be sent as a nodejs stream.
- hydrateRoot API. Allows the react application to be attached to the rendered HTML.
These 2 features basically allow the server side to keep rendering the application as the HTML is being returned, allowing for asynchronous rendering of components. The 3rd feature is useful when the destination is a browser - the rendered HTML is now made useful.
Current state of some popular Magento PWA technologies
- PWAStudio : Currently is on react 16 and does not include any SSR component.
- ScandiPWA : Version 6.2 and above are on react 18. Out of the box ScandiPWA does not support SSR, but it should not be very difficult to add the ssr route.
- VSF1 : Is based on vue and supports an inbuilt SSR
- VSF2 : Has an inbuilt SSR