This is a little backwards, especially when apps are used under real-world network (3G) and device constraints that can leave the user waiting a long time for interactivity. Even if server-side rendering is used, a user can be left staring at UI that looks like it should work and be tappable, but isn't because it is waiting for our "bundle.js" to finish loading.
We can turn this module bundling mindset upside down and instead take advantage of route-based chunking. That is, code-splitting the routes in our into different "chunks" that serve the minimal amount of code required to make each route fully interactive. This encourages us to deliver resources something closer to the granularity in which they are authored (that is, pretty functionally independent chunks that are as small as possible).
So, aim to serve the minimal code for a route and as the user transitions to other routes in your app, lazy-load
those routes in. Module bundlers like Webpack (via dynamic
import() (Webpack docs for dynamic imports) or
require.ensure()) make this type of code-splitting straight-forward and splitting based on routes stays low-friction when using
a routing solution like React Router that supports asynchronous code-splitting in routes.
Flipkart talk about how they tackled route-based chunking in their talk Scaling Progressive Web Apps
Route-based chunking can get even sweeter when paired with a pattern like PRPL which takes advantage of Service Worker pre-caching and HTTP/2 Server Push to ensure routes are almost instantly interactive on repeat visits and are served as optimally as possible.