Optimize Build Output w/ Code-splitting#2173
Draft
Conversation
This plugin is deprecated because the underlying issue is fixed in vite v5
Using the dynamic `import()` function that imports a JS Module only when called, we can split our code into several discrete chuncks of code, as opposed to having it all in one giant file. This allows us to ensure that users only have to download the code needed for the pages they view, instead of downloading the code for the entire site even if they only visit the homepage. This problem is technically caused by our bundler, which transforms the thousands of files of source code into unified bundles of code in one file. Bundling is desirable because it prevents the browser from having to "waterfall" request the source code: i.e. request App.js from the server, and then request Home.js that is imported by App.js, and then request CLWCredits.js that is imported by Home.js, etc. The only downside is that the bundled file can become so large that it takes a user-noticeable amount of time to download, and includes code that will never run because the user only visits a small portion of the site. Code-splitting lets us optimize in both directions, by bundling our code into files exactly sized to display one top-level route of the site each. So the user gets only the code they need for the page they are currently viewing, but they get all that code in one request that serves one reasonably-sized file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds code-splitting that splits our bundled JS output for production builds into several files - roughly one per route.
Using the dynamic
import()function that imports a JS Module only when called, we can split our code into several discrete chunks of code, as opposed to having it all in one giant file. This allows us to ensure that users only have to download the code needed for the pages they view, instead of downloading the code for the entire site even if, for example, they only visit the homepage.This problem is technically caused by the bundling step in creating a production build, which transforms the thousands of files of source code into unified bundles of code in one file. Bundling is desirable because it prevents the browser from having to "waterfall" request the source code: i.e. request App.js from the server and parse that file, and then request and parse Home.js that is imported by App.js, and then request and parse CLWCredits.js that is imported by Home.js, etc.
The downside of bundling is that the bundled file can become so large that it takes a user-noticeable amount of time to download and includes code that may never run. Code-splitting lets us optimize in both directions, by bundling our code into files exactly sized to display one top-level route of the site each. So, the user gets only the code they need for the page they are currently viewing, but they get all that code in one request that serves one reasonably sized file.
For context, here are the JS files output for a production build before this PR, without code-splitting:
And here are the JS files for the same version of the site but with code-splitting:
We go from two VERY large JS files to a number of more reasonably-sized JS files. The vendor.js file is still noticeably large unfortunately, but it is less than half it's previous size. There are some scripts in the code-split build that don't seem like they need to be in their own files. But I think that code-splitting at the top-level routes is a good enough starting point for this behavior.