found
found copied to clipboard
Investigate how to better support tracking use of chunks in code-splitting
When doing server-side rendering, in order to be able to synchronously render the client-side code (and avoid a waterfall of requests for code bundles), we need so be able to do something like the following:
- Transform client-side code to be able to import dynamic modules synchronously if it's already available (eg the target bundle has already been loaded and executed).
- Transform server-side code to track which dynamic imports have been used during a server render.
- Have some kind of mechanism for mapping tracked dynamic imports to static assets (eg JS, CSS) and include references to those assets in the returned HTML so that step 1 can work correctly.
There appear to be some existing mechanisms to make this work with component-based code-splitting, and therefore with component-based routing such as React Router 4, and Reach Router. But I haven't seen anything for supporting any other kind of dynamic import.
I suspect a lot of this could be achieved in Found by using a custom babel plugin that operates on route configurations. It probably couldn't be a core feature, because the behaviour of the plugin would likely need to vary per project. But it may be worth trying to build out some examples that implement the full universal rendering + code-splitting story to demonstrate how it could be done in a real project.
cc @jquense, who might know the relevant magical webpack incantations.
I'll also note that it's not an arbitrary waterfall – it's just one extra round-trip, since the initial render on the client will pull down all the split-out bundles in parallel.
It'd just be nice to eliminate that extra single round trip, if we can find a nice way to do so.
We only avoid the full waterfall if there isn't additional code-splitting within the tree of the route component themselves. With some of the new @match
stuff that's coming in Relay, it's more likely that we ourselves will choose to take advantage of it. Ideally any solution we come up with will be able to benefit all dynamic imports.
Ah, I see – so in the event that there are nested @match
calls, while waterfalling isn't avoidable per se when doing client-side rendering, you still want to avoid waterfalling on a server render? Makes sense; that's somewhat tangential to what would get addressed in the router, then.
Yeah, i'm less fussed about waterfalls further down, more concerned with the router part for now.
Pulling in some discussion from Slack so I don't forget:
taion [08:16]
i don’t have an answer for how to avoid the extra round trip /: i think most people (incl airbnb per their example) just take the hit perhaps a better answer is integrating https://github.com/faceyspacey/webpack-flush-chunks/blob/master/README.md but i haven’t done that and haven’t looked into what’s required
andrewingram [08:35]
I tried this, but it requires that you're using something else that instruments the server code so that it knows what chunks were used and that something else seems to be a component wrapper
andrewingram [09:01]
https://github.com/faceyspacey/babel-plugin-universal-import they suggest using this, but if you look at it, it's actually tied to Components
@taion @AndrewIngram any update on code-splitting ??
Code splitting already works. Just use getComponent
and dynamic imports, and you'll have code splitting for your components. This is an additional optimization that can give a minor performance boost when doing SSR, but doesn't matter at all when not doing SSR.