Performance is now one of the core value for modern web app. Most of the user shift the web browser experiences from desktop to mobile web. Other than smaller screen, lower CPU power, network condition becomes one of the important factor to make your content assessable to all users.
We want all of our user can enjoy the same experiences globally regardless of the network conditions (and respect user’s preferences in terms of data consumption).
Some strategies we adopted:
- Route/Link base preload: Similar to Addy Osmani’s quicklink library, we use a combination with react router, React lazy and intersection observer to preload the next page bundle when the link component entering viewport and on idle. (Will also suggest to check Minko Gechev’s guess-js which use a data-driven approach to load bundles)
- Service worker precache: For critical assets, we use workbox to generate precache manifest and load those assets upfront in order to fast serve bundle when needed.
- Browser resource priority hint: By using html link
prefetchresource priority hint, we are able to make the first page experience load instantly.
Some deep dive of our web app could be found here: A Tinder Progressive Web App Performance Case Study (by Addy).
Network-aware loading strategies (Adaptive loading)
Our performance journey doesn’t ends there. When testing on real mobile device outside of office, we notice that a lot of time the experiences are less than desire. The web app shows lots of loading state when entering a spotty network area even we already done a lot to improve the first page load. Data consumption also is one of the critical area of focus when it comes to international market where unlimited data might not be accessible or affordable to all users.
Thanks to the new browser APIs, we can now adaptively change our loading strategies based on different device/network conditions.
(MDN) The Network Information API provides information about the system’s connection in terms of general connection type (e.g., ‘wifi’, ‘cellular’, etc.). This can be used to select high definition content or low definition content based on the user’s connection. The entire API consists of the addition of the
NetworkInformation interface and a single property to the
Although not fully supported by browser vendors, the api is heavily used in our web app. (Especially the browser supports align with our international users where Android dominates the market). We regard adaptive loading as progressive enhancement and serve default behavior for unsupported browsers.
Two main informations we collects from the API
(MDN) Returns the effective type of the connection meaning one of ‘slow-2g’, ‘2g’, ‘3g’, or ‘4g’. This value is determined using a combination of recently observed round-trip time and downlink values.
true if the user has set a reduced data usage option on the user agent.
Some examples we adopt for network-aware loading (based on the above prefetch scenario)
- Route/Link base preload: As browser has limited amount of parallel download, it is critical to yield the download quota to high priority resources .We notice that when the network condition is poor, aggressive preload will cause the main experiences flaky. Some important resources got deferred and device CPU occupied. We decide to check only preload next route when user is in good network conditions.
2. Progressive image loading: As mentioned above, we fetch multiple dimensions of same image to progressively display in browser. However, on fast network condition, images complete loading almost in the same time, and the logic cause CPU overhead fetching and swapping image after each image complete loading. We also honer user’s data consumption preference to prevent aggressively prefetching resource if they have data-saver turned on.
Other UI enhancements we accomplished:
- Videos: We use video to display gif images (much smaller size) and disable video auto play for slow network. (We selectively pass
posterattribute to video element which browser will only download the video resource after user interaction.)
To prevent user seeing blank placeholder when navigate to second page of carousel, we used to load the next page photo together. This causes a janky swipe experience on our international market.
We change the behavior to only load the first image under slow network, and start prefetching next page image if user has intention to view more photo for a specific profile (when they view to next page or other interaction indicates the intention).
By implementing the adaptive loading, we notice an improvement our user engagement (more user interaction such as click or swipe) for emerging market where Android is the major device OS and user experiences slow network frequently.