A talk to beginner web developers about Webpack with a focus on performance optimization mindset and techniques. Given at an event organized by https://mintbean.io/
7. Optimizing Webpack - Why does it matter?
You have no control over how users load your site.
Internet speeds and device computing power vary drastically.
8. Optimizing Webpack - How?
The less the browser has to load, the faster the user experience will generally be.
So - focus on optimizations towards a small bundle.js file
9. Optimizing Webpack
Three intertwined optimization levers:
1) Build Time
a) Monitoring/analysis
b) Separating development and production builds
1) Small Bundle Size
a) Monitoring/analysis
b) Bundle size reduction
c) Tree Shaking
d) Minifying / Uglifying
1) Browser Loading Techniques
a) Lazy loading in browser (aka “code splitting”)
Local
Production
10. Optimizing (Browser Load Techniques) - Code Splitting
Image source
The browser only loads sections of code when they are needed instead of loading
everything up front on first load. (Webpack Docs)
- Compare load time using Lighthouse before and after code splitting
11. Optimizing (Bundle Size) - Uglify / Minify
webpack.config.js
JavaScript Input JavaScript Output
Less readable and takes up less space
UglifyJS Webpack Plugin
Online Minifier Demo
13. Optimizing (Bundle Size) - Tree Shaking Pt 2.
- Google Developer guide to Tree Shaking
“The difference between [the second] import example and the previous one is that
rather than importing everything from the "array-utils" module (which could be a lot
of stuff!), this example imports only specific parts of it. In dev builds, this doesn't
really change anything, as the entire module gets imported regardless. In production
builds, however, we can configure webpack to "shake" off exports from ES6 modules
that weren't explicitly imported, making those production builds smaller.”
Before Tree Shaking After Tree Shaking
14. Optimizing (Build) - Development vs Production
Tutorial
Split dev and prod
webpack builds to
fine tune dev
webpack build for
quick hot
reloading.
(Real life example
of the value of this
on the next slide)
Image source
15. Optimizing (Build) - Monitoring/Analysis Pt. 1
speed-measure-webpack-plugin
Dev build - faster build time, faster hot
reload, faster developing! 🎉
Prod build - longer build time but uses a
plugin needed for prod deployment.
16. Early detection of large module sizes in development flow before even building.
Optimizing (Bundle Size) - Monitoring/Analysis Pt. 2
Import Cost VSCode Extension
17. Optimizing (Bundle Size) - Monitoring/Analysis Pt. 3
More on other visual bundle analysis tools
DEMO TIME!
Image Source
18. Optimizing - Final Thoughts
Layered monitoring strategies in your workflow.
Develop an awareness of module sizes before they become entrenched in your app.
19. Discussion / Q&A
Webpack is a massive topic with a huge ecosystem/community of plugins. Go
explore! See more on the Webpack docs page.
Some other topics we could discuss:
- Transpilers (ex: Babel)
- Webpack Dev Server
- Sourcemaps/Stacktrace - aka ‘what line did the error happen?’
- Webpack + Docker staged production builds
- Dependency graphs
- Modules, plugins, or other general Webpack concepts
20. Appendix
CODE EXAMPLE FOR Uglify online: https://skalman.github.io/UglifyJS-online/
function getIntoAnArgument() {
var args = arguments.slice();
args.forEach(function(arg) {
console.log(arg);
});
}
module.exports = {
haste: {
hasteImplModulePath: require.resolve('./noHaste.js'),
},
modulePathIgnorePatterns: [
'<rootDir>/scripts/rollup/shims/',
'<rootDir>/scripts/bench/',
],
transform: {
'.*': require.resolve('./preprocessor.js'),
},
setupFiles: [require.resolve('./setupEnvironment.js')],
setupFilesAfterEnv: [require.resolve('./setupTests.js')],
// Only include files directly in __tests__, not in nested folders.
testRegex: '/__tests__/[^/]*(.js|.coffee|[^d].ts)$',
moduleFileExtensions: ['js', 'json', 'node', 'coffee', 'ts'],
rootDir: process.cwd(),
roots: ['<rootDir>/packages', '<rootDir>/scripts'],
collectCoverageFrom: ['packages/**/*.js'],
timers: 'fake',
snapshotSerializers: [require.resolve('jest-snapshot-serializer-raw')],
testSequencer: require.resolve('./jestSequencer'),
// TODO: Upgrade to Jest 26 which uses jsdom 16 by default.
testEnvironment: require.resolve('jest-environment-jsdom-sixteen'),
};