PWA for Magento
Every good application should work, look, and feel good. This means that it should be:
- Reliable — working well on slow connections
- Fast — data exchange happens very quickly
- Engaging — UX is attractive and pleasant to work with
Concurrently, PWA brings improvements to each of these points. What’s more, what if I told you that any Magento 2 store could be converted to a very simple, but still incredible Progressive Web Application with offline availability in 1–2 weeks?
PWA workflow may break the usual Magento development flow. React suggests a steep learning curve for a regular Magento developer, at the same time, it is one of the top options for PWA development. SEO issues with PWA, extension integrations with the frontend on React, and GraphQL coverage are just a few things you need to be aware of. In this webinar, scandiweb’s CEO Antons Sapriko shares knowledge and explains how to tackle the most common tripping points:
Now, let’s continue with the article.
From a technical perspective, there is not much effort needed to simply add client-side caching for entire pages and fetching them in the background. The interface will remain the same: old and boring, so engagement may not be fully reached. In the world of PWA, there are no black and white implementations: PWA / non-PWA is not a binary distinction. Theoretically, only implementing push notifications and offline browsing could make any web page a PWA.
That’s not good enough! We want to create the best PWA we can, stopping only at platform/networking/stack limitations, while striving to realize all 3 requirements as well as possible: loads fast ( <1.5s), data exchange is fast (<1s) and the app looks and feels amazing!
To achieve great UX, we must rework the user interface, and here ReactJS comes in handy, bringing us chunking and further possible enhancements.
It is important to highlight: everything mentioned above is about frontend — UI, UX. That is the reason, why all competitors create backend-agnostic implementations (Schema 2). We want it different.
Note: it is important to understand, that PWA itself is highly dynamic. Therefore, it must be built in some way and delivered as a “package” to the client afterward. So, actually PWA is a part, working client-side, however, deep integration with server-side is necessary to keep it highly dynamic.
ReactJS + MobX
Great libs, that allow us to build applications that feel awesome(engaging) and implement chunking (fast data exchange). This can make the app reliable & working fast. It provides much more, but this is irrelevant to our current topic.
Our goal is to integrate PWA with Magento and make it a Magento theme, not a standalone / 3rd party service.
We must understand, that React will replace such Magento functionalities as:
- Front controller
How it looks now
When you type in the address, it connects to a proper server and gets index.html (app shell) that gives initial content (template: header, footer) and activates ReactJS. All is great, except the way we get index.html. So for now, we are using a custom renderer during deployment to generate an absolutely static html.
While, in fact, there is a customer section (“Hello, username”, minicart and might be some more dynamic fields). But we will load just a “default” view without any options. And it all feels like reinventing the bicycle.
How we would like to build it
We could hit Magento: stripped out layout produces the very same content as index.html, but — we can make it dynamic. So, if there is a valid session, but we are requesting app shell — we can display “Hello, username” right away.
There might be concerns about speed, however — stripped of complex logic and multiple DB request to get records from the database — the app shell will be generated faster, than the usual homepage. Additionally — we forgot about our lovely speed booster: Varnish. Magento will be hit only once after Varnish was purged (ex. deployment).
Dynamic content can be resolved blazingly fast with Varnish ESI blocks. And even the first-run delay can be easily eliminated with a single page request to regenerate Magento and Varnish caches. It is extremely easy — the PWA application has only one entry point that serves as initial “installation” — all other URLs are routed on the client. This way only one resource needs to be cached and warmed.
What is the gain:
- No need for pre-generation using overwhelming custom logic pre-generation
- We avoid forcing static content when we actually need dynamic blocks
- We leave initial page layout control at Magento site (layout.xml it is)
- We trust Magento to serve the React application and keep it as an integrated part of Magento.
As a result, we get a Magento theme on steroids: Magento is serving a client-side app, that moves UX to new heights.
Schema 4 represents the flow of a usual web page, while Schema 5 represents PWA’s flow.
So, at the very beginning, the first (simple) request is needed, which is sort of “installing” our application on the client side. During the “installation”, the service worker is registered, which acts as a data fetch proxy, managing requests, caching rules (offline mode), background fetch (prefetch/background update). It automatically catches all data requests (comparable to Ajax requests) and fulfills them based on rules.
Next to the modern UI, which is great with React, the service worker is the second extremely important part, that actually allows to create the “feeling of a native app”.
Since we are building a Magento theme — we must keep the existing design, however, app shell generation should not involve side node processes, utilizing the Magento engine instead. With Varnish and ESI blocks we can get great speed results with dynamic content of the app shell.
Otherwise, the current implementation is absolutely a stand-alone solution for serving PWA to the client and forces us to introduce multiple custom tools that cannot become a part of Magento because of technical reasons (tech stack mismatch).
In order to build an awesome PWA experience — we must carefully analyze and decide on data set (elements) fetching strategy. I will borrow the naming from the Google offered service worker lib:
- Network first/cache fallback — try network, whether unavailable — serve from cache.
- Cache first/network — server from cache, if unavailable — request over network.
- Cache only
- Network only
- Cache/network race — try both, use the one which is faster
Correct and well-done design will provide us control over any piece of the app and has a direct impact on application speed.
This article was written by Ilja Lapkovskis, Scandiweb’s CTO. If you have any questions, comments, or would like to see what ScandiPWA can do for your store, write us a message at [email protected]! Find all the essential information on PWA: features, explanation of the tech, real-life case studies, and much, much more. Take a look!