Should you favor skeleton loading over spinner loading, and what would be the difference between building a PWA or server rendered website?
There was a question on LinkedIn about perceived performance, asked by Jan-Willem Bobbink.
"Looking into best practices for optimizing for perceived performance. Facebooks skeleton loading for example. Who knows about some great cases?"
Let's start with some abbreviations:
- UX: User eXperience
How is a user experiencing an environment (within this subject, how will users experience the loading process); - SSR: Server Side Rendered
A webpage is Server Side Rendered when its content (in HTML) is being rendered on the server, and contents are being output within the initial HTML document; - CSR: Client Side Rendered
A webpage is Client Side Rendered when the HTML is containing references to new resources (JavaScript) which are responsible for loading and showing title, product-image and other content; - PWA: Progressive Web App
A PWA is often build on top of JavaScript frameworks where content is being fetched using JavaScript on top of frameworks. Often, a Progressive Web App is Client Side Rendered and thus CSR; - AMP: Accelerated Mobile Pages.
HTML framework designed by Google, with restrictions on HTML, CSS and JavaScript to guarantee a performance baseline (not necessarily faster than building websites the 'traditional' way).
Perceived performance within CSR
Skeleton loading could be a solution when practicing Client Side Rendering. However, downsides to be aware of when developing sites or e-commerce while building the CSR way, are as following:
- Setting up skeleton loading might take more development time (as you are building some kind of equivalent instead of a derivation of the eventual page);
- Content placement or positioning might be different after fully loaded. Content may be larger than skeleton loading is illustrating. As a result, skeleton loading might produce false expectations as to where content might pop up.
- Skeleton loading often results in layout shifts (CLS metric);
- Visitor can't grasp the page's content (title, image, text) directly as it isn't meaningful, not enforcing visitor's to "answering your needs, encouraging their next action to remain with you". This may have an decreasing impact on the conversion rate;
- Users of old(er) devices / browsers, or slow internet (bad coverage, low internet plan) might be looking at skeleton loading for a (relative) long period of time.
CSR skeleton loading example
Below, you are seeing a screenshot of a before and after situation within a client side rendered webpage. Click on the image to see the large image.
Skeleton loading and JavaScript dependency
Skeleton loading is often initiated using JavaScript. As a result, users might be looking at white screen for a while instead, before skeleton loading kicks in. When applying skeleton loading, make sure the skeleton loading interface is set up using SSR, with inlined CSS. This way, no following (and thus render blocking) resources have to be made.
UX, SEO and inclusivity
However, at the same time, skeleton loading might also decrease UX and 'dwell time' as a ranking factor. JavaScript will always have some impact on performance as it has to be executed and parsed as well.
Obviously, as JavaScript syntax errors will be less forgiving, we would reduce risk towards technical SEO when building SSR. To put it in other words: more technical SEO testing should be done when building CSR.
My advice would always be to use those first HTML bytes to display heading, text and product-image right away with minimal (inlined) CSS, while lazyloading/deferring other resources at the same time. This way, if JavaScript is timing out (or disabled), the site will still work (that is, when building with progressive enhancement in mind and tested properly).
Perceived performance within SSR
When your webpages are being rendered server side (SSR), there is no need to apply skeleton loading. Why would you serve a skeleton loading interface when the main content is already there, within the initial downloaded HTML document? A best practice would be to inline CSS partially. For example, this is also done within AMP solutions, although coming with restrictions.
SSR perceived performance example
Below, you are seeing a screenshot of a before and after situation within a server side rendered webpage, with the advantage that the meaningful content is already there when first bytes are received by the browser.
Wordpress and inline CSS
There are also Wordpress plugins to inline CSS for you, but this may produce downsides:
- browser caching advantages aren't utilized;
- this often result in layout shifts (once again, CLS metric);
- initial download-size will increase, making the initial load time slower. For example, DeOnlineDrogist.nl productpages increased 633% in HTML download-size while inlining CSS.
Your visitors can start reading right away
The biggest advantage of SSR in combination with inlining critical css, is that a user can start reading right away. Content isn't dependant of JavaScript. In the meantime, the website might load Google Fonts or other custom fonts, JavaScript and other resources in the background; An improved perceived performance, where especially user experience and thus conversion is benefiting.
But skeleton loading looks shiny
At the agency I work, we apply perceived performance too, automated within the Content Management System we use. One might not notice, as content will be visible as soon as the first bytes were received by the browser. At the time the user starts interacting with a site, other resources might already be loaded while navigating the website or webshop won't be blocked at all.
Obviously, creating skeleton loading might be more fun for developer experience, but the art is to improve user experience.
Want to know more about implementation? I will be talking about this specific subject during the next Refresh event (Tuesday, November 26th @ Groningen).
Skeleton loading best practice
If you already build your website or shop the CSR way and want to improve the perceived performance, than do read the article on skeleton screens and perceived duration while waiting. The conclusion? You are better of using skeleton loading instead of a loading spinner. Within skeleton loading, slow left to right wave animation seems to be best for perceived duration (amongst 20 testers):
Do take note of the fact that this research was done in a pre-defined environment. There were no real-life influences such as:
- Internet-speed fluctuations;
- JS preferences (noscript/saveData);
- JS compatibility issues due to operating system of browser version;
- Device capabilities (memory, CPU).