Asset Loading Performance
When developing a Single Page Application (SPA), all the application logic will be run only on the browser. As Application grows over time, so the size of assets (js, css, images).
As mentioned in this blog post even today, lots of famous apps loads more asset to perform main action. It is always crucial to optimise the amount of asset required to render page of an application.
Let's see different options available to improve the page loading speed
Reducing the number of assets itself
Deprioritising assets which are not required at the moment
Loading assets only when required
Effective caching
Reducing the number of assets itself
What do I mean by that, when the page requires more number of asserts to display the content, the number of request to the server to fetch asserts increases. As the number of requests increases the network latency piles up. This all adds up the delay to see the content of page.
Here is where webpack chunk grouping plugin comes handy.
We can group chunks based on following factors
File size
File path
Purpose
we can group all vendor modules into one chunk based on file size.
Or We can create a group per module. Eg: We can create group for SignIn Module and another one for Profile Module.
Here is the webpack chunk splitting configuration to split based on the modules and vendor files.
Deprioritising assets which are not required at the moment
In this step we will categorise the resources based on the priority. You need to basically get Yes response to following question.
"Does this resource really contributes to the information that user currently seeing?"
If not, we can deprioritize it using one of below ways.
- In HTML we have got
loading
attribute to inform when to load images and iframe.
<img loading="lazy" src="image.jpg" alt="..." />
<iframe loading="lazy" src="video-player.html" title="..."></iframe>
This will load resource only when the resource comes into view. refer here for detailed explaination.
Loading assets only when required
We can leverage the dynamic module loading of javascript to defer loading resources until it is needed. Here small example loading profile details only when user hover over the profile picture. This will make the profile component to not to participate in initial chunk loading.
import { lazy } from 'react';
const ProfileComponent = lazy(() => import('./ProfileComponent.js'));
function HomeComponent() {
return (
...
{ isProfileHovered && <ProfileComponent /> }
...
)
}
We can also leverage the resource hint feature that insists the browser to load the files in parallel to the actual src files. here is the detailed article to refer on that aspect. This will reduce the time to load the resource.
Effective Caching
The first step before implementing caching is that we have to decide what to cache.
We need to split the resources in a way that we can differentiate less frequently changing resource with resource that will change more frequently so that we can effectively utilise the both long term and short term caching.
In the above example of chunk splitting code, we demonstrated we moved all the less frequently changing resource like vendor modules and design system into separate chunk so we can cache them longer duration. On the other hand all the application level code which we will change on a daily basis we moved it out for short term cache.
Choosing what to move into long term cache and what to move inside short term cache is purely use case driver.