-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FEATURE: Code splitting by route #10
Comments
What does RelateRocket have to do with code splitting? Some googling shows that it looks to be your startup? I think implementing this could open up an important feature: speed
|
LOL, yeah, RelateRocket is my startup. I meant "React Router" but the two are close enough I guess that I substituted one for the other. I updated the original comment. And yup, yup, yup! Larger sites especially will really benefit from code splitting. Right now relaterocket.co only has ~5-6 pages so the initial JS load isn't large but eventually the plan is it'll have 100s if not 1000s so code splitting will hugely beneficial. |
Because Gatsby loads all pages/modules upfront, to implement code splitting, internally each split would effectively be treated as its own site. E.g. Each would share the top-level html/_template components. |
+1 for code split I want to raise a few issues though.
P.S. Thanks for amazing tool! I was amazed when first tried it out - it just works :) |
@sergeylukin hey glad it "just worked"! That's the goal! So pagination/code splitting is something I'm still researching but the idea is you'd definitely be able to get chunk sizes down to whatever size you'd like. For example, my thinking is now that pagination should be a default way to load chunks. So if you have Navigation to a new chunk doesn't require a page-reload. You would click on the link and wait a bit while the new js chunk downloads and then the page transition would happen. Most of the time you'd barely notice the delay unless you're on a slow connection. We're leveraging ReactRouter's https://github.com/rackt/react-router/blob/master/docs/guides/advanced/DynamicRouting.md functionality here. Oh and on my blog bundle—it's smaller now since #48 629kb before gzip and 202kb after :) |
It's late and I'm tired, but I think I figured out a way to get everything working with code splitting. Here are my thoughts:
I have some small experiments that demonstrate that this should work. Since gatsby makes use of If you see no problems with this I'd like to take a whack at implementing it. |
Hey Ken! Thanks for looking into this! Getting this done would be huge! Two thoughts/questions. The Second question is would it be possible to merge page chunks together? E.g. say the |
Though one interesting advantage of single-page chunks is they'd be very stable as many pages don't change post-launch. With #100 you could have a service worker which caches pages (perhaps even do it in the background after the initial page load) meaning most of a Gatsby site would work offline and load near-instantly. This would be especially cool for a docs site as the docs would be instantly referenceable whenever you need them. Though sadly mobile Safari doesn't support service workers yet. |
And another complexity—metadata. Right now templating in Gatsby assumes you can access all metadata from any page. E.g. here where the example docs site gathers all doc pages and pulls out the title. There's some exploration of this in #47 but this needs to be solved before code splitting can happen. |
You might want to look in to
Consider my custom exports.data = {
title: 'foo',
children: [],
//...
};
exports.load = function () {
require.ensure([], function (require) {
// ...
}, 'name');
}; Metadata would add some slight overhead to the initial bundle, but the vast majority of the content would still be lazy loaded. You could make metadata an option so people could opt-in. You might also consider making this implementation closer to |
Looks like |
Woah, very cool! The Webpack ecosystem keeps delivering :) So this sounds completely perfect. Tell me if this sounds right.
sections: {
"2015": "/blog/2015*"
"2014": "/blog/2014*"
"oldPosts": "/blog/!(2014|2015)*"
} So then when creating chunks, matching paths would get added to a named multi-path chunk. This same pattern would also be added into the require.ensure stuff with react-router so it knows which named chunks to load when a particular path is navigated to. |
On metadata—getting metadata for a single file is easy—the tricky thing is when you want metadata such as all the titles + paths of your blog entries, etc. |
as this is implemented, some things I myself would like to see:
edit: bundle -> chunk |
@phlogisticfugu 100% agree. Gatsby should be as speedy as possible in all respects. Minimal page loads through lazy loading, compress/minify all assets (e.g. #18), and cache everywhere (browser through service workers/normal caching & unique asset names for CDNs). |
Extending my custom var context = require.context('posts', true, /\.md$/);
var keys = context.keys(); // ['posts/foo.md', 'posts/bar.md', ...] |
From that point each post is just a module with the meta data and a lazy-load function. |
so, re-reading https://webpack.github.io/docs/code-splitting.html it would seem to make sense then if the meta data for all pages is in it's own module, and that module is included in all entry-point chunks. Then it's available on all pages, plus webpack manages it properly as a dependency. The main content of each page would then be separated from the metadata, and lazy-loaded in it's own module |
Yeah, that's what I'm thinking too. It's far easier and the size would only become prohibitive for very large sites (would have to run tests to see). Titles and dates, etc. are pretty small. So basically take the |
And if you really needed to split up the metadata you could always just make multiple contexts. But I'd say get the simple case working first. I started an attempt but I don't really Coffeescript. I'll probably keep trying but if anyone else wants to take a whack at this feel free. |
Feel free to convert the coffeescript to js first. Most code has already
|
Gatsby 0.8 includes an upgrade to React Router 2.0 making code splitting now possible. |
oOoOoOo... I might start taking another look at this. I've been silly busy lately. |
@knpwrs that'd be great! And how's that old saying go... "if you want something done, ask a busy person" ;-) |
Article on auto-code-splitting w/ Webpack 2.0 from @ChristopherBiscardi https://medium.com/modus-create-front-end-development/automatic-code-splitting-for-react-router-w-es6-imports-a0abdaa491e9#.hgqgqdbo4 |
To combine the code splitting sections/groups + the above article, perhaps when you define page groups, every page within that group gets rolled up within a module e.g. |
Did you know that one can limit the total amount of chunks generated by webpack? I just learned about it now myself and decided to share with you as I couldn't find it being mentioned here. Btw, a side effect I've discovered is that if it is set to 1, the build is faster, so my
and it puts all chunks in main bundle which is OK for development as long as build is faster :) While production may have something like:
Production configuration preference really varies of course and for gatsby chunks limit may not be ideally the best option but it's an option to consider and probably the easiest one to go for atm. Cheers |
@sergeylukin that is nifty — thanks for bringing it up. Definitely worth looking into it. Might be an interesting option / inspiration. |
@KyleAMathews would like to contribute, but I'm not too familiar with the Gatsby codebase and Webpack as well. Perhaps you could suggest a concrete place to start looking into? |
@demoneaux you'd like to contribute to this issue or in general? |
Code splitting is coming in 1.0! Wrote up plans at #431 Closing this issue in favor of that one. |
Once we upgrade to ReactRouter 1.0, leverage Webpack's code splitting to dynamically load sections of large sites e.g.
docs/*
orblog/*
http://webpack.github.io/docs/code-splitting.html
remix-run/react-router#755
The text was updated successfully, but these errors were encountered: