Enable webpack code splitting to improve frontend performance.
Here's a breakdown of the sections I've numbered in the graph above:
- 339ms – Ignoring everything before the first byte (because that's backend and network performance related), there is a lengthy idle frame where we are waiting for blocking network requests (our JS and CSS assets in the page header).
- 629ms – Running the DOMContentLoaded event.
After all of this, the page is fully interactive. Between all of these steps, there's about 1.7 seconds of loading time that are fully within the frontend team's power to improve.
A LOT of the code we evaluate in steps 2 and 4 are unrelated to the page we're viewing, and a lot of the size of the files we wait for in step 1 is due to code that won't even execute on this page.
Improving both perceived and actual performance with webpack
- Introduce webpack code splitting and asynchronously load large components like the emoji picker, dropzone library, or calendar picker.
- Intelligently split up the main.js and dispatcher.js files into smaller, page-specific chunks.
- Move our scripts below the html
<body>so it doesn't block the initial render.
- Enable webpack code splitting. Configure babel and eslint to understand
import(). Ensure it works in all gitlab configurations (i.e.
relative_url_rootplays nice). We can test this with the emoji picker first.
- Start eliminating
importside effects as technical debt. Almost every script in our codebase (with a few privileged exceptions) should do nothing other than define and
exportclasses and methods. This will help us evaluate our dependency graph and eliminate global scope pollution.
- Evaluate all imports within
dispatcher.jsand identify groups of scripts that ought to be bundled together. Utilize the new Chrome DevTools code coverage feature to inspect the code that executes on a given page and easily identify common paths.
- Take the code that is not necessary for initial interactivity and split it off into asynchronous chunks.
- Remove all embedded
<body>so we don't block the page from rendering initially.
- Create a means to automatically include async bundle browser hints with
<link rel="preload">which is now supported in both Chrome and Safari.
- Update ~Documentation with guidelines for code splitting and webpack bundle best practices.