navi
navi copied to clipboard
Preload imported assets
We're using navi in our React-app together with server side rendering. We're working on page speeds and one of our requirements to improve speed is to preload assets such as CSS files and JS files.
To do that, we need to know the set of dynamic modules where rendered in a request. For example, a request to '/' renders two dynamically imported JavaScript bundles and one dynamically imported CSS bundle. Do you have a suggestion for how we can get that information from navi?
We used react-loadable prior to navi, but changed to navi as it solved most of our requirements better with less code so we'd love to keep navi. However, this particular requirement is unclear how to solve using navi. Here's a link to the corresponding react-loadable documentation.
When using Navi for static rendering, navi-scripts will hook into jsdom's loading code and record JavaScript and CSS files. It then provides these via a dependencies object to the renderPageWithString() function. You can see an example here:
https://github.com/frontarm/navi/blob/master/packages/react-navi/create-react-app.js#L56
As for server-rendering, unfortunately Navi itself doesn't actually know what's been rendered, because unlike react-loadable, it's all done at runtime. There's no build step where import() and require() calls can be analyzed and recorded.
It'd probably be possible write a babel plugin that looks for import statements in route files and adds a withData() matcher (or similar) that records them. This isn't something I really want to support in Navi itself though, as it only really becomes a problem when you're using lots of small CSS files. Using CSS-in-JS solves the problem as it lets you generate the critical CSS, and it's possible to structure your imports and use /* webpackMode: "eager" */ comments to avoid the problem on the JavaScript side.
To add to this, it would be possible to get 90% support for this in SSR apps -- you'd just have to do a static rendering pass when building the assets, and record the dependencies then.
I'd like to add an example with this at some point, so I'll leave this issue open for now.