webpack & react performance in 16+ steps
TRANSCRIPT
Steps for Boosting React and Webpack Performance
Grgur Grisogono @ggrgur
1Modus Create @moduscreate
6bit.ly/reactpack-live
Grgur Grisogono
2
Software Architect@moduscreate
Performance = Speed
What is Speed?
Who’s the consumer?
End User Experience
Bundle Size
Developer Experience
(Re)Build Speed
Agenda
Webpack perf
React perf
Babel perf
Node EnvironmentAvoid development code execution
Node Environment
Build Perf (Dev) Bundle Perf (Prod)
✔N/A
SourceMaps SelectionChoose the right SourceMap kind (devTool) for your build type
SourceMaps Selection
Build Perf (Dev) Bundle Perf (Prod)
✔✔
UglifyJS
Minify production source code. Hint: React 15 doesn’t support IE8
UglifyJS
Build Perf (Dev) Bundle Perf (Prod)
✔✘
!UglifyJS • UglifyJS works great with GZIP
• Also removes dead code • Preserves SourceMaps • Can be configure to
remove @license comments
• Avoid in development
identName Hashes (CSS Modules, Chunk names)
Hash name generation is best used in prod. Descriptive names in dev.
https://github.com/webpack/loader-utils#interpolatename
identName Hashes
Build Perf (Dev) Bundle Perf (Prod)
✔✘
Disable Autoprefixer in developmentAutoprefixer adds vendor prefixes for CSS, but also adds build overhead
Disable Autoprefixer in development
Build Perf (Dev) Bundle Perf (DEV)
✔✔
CSS Loader v0.14.5
This older version of CSS loader is much faster at processing CSS (but it doesn’t support all features like CSS composition)
CSS Loader v0.14.5
Build Perf (Dev) Bundle Perf (Prod)
✔ ?
!CSS Loader v0.14.5
• Much faster for CSS processing
• Doesn’t use expensive dependencies (e.g. PostCSS)
• Composition not available
Parallelize build with HappyPackMulti-threading for Webpack Builds. Works with any loader (SCSS and LESS, too)
Parallelize build with HappyPack
Build Perf (Dev) Bundle Perf (Prod)
✔ N/A
Create DLL bundles
DLLs contain infrequently changed code (libraries) to avoid unneeded processing
Create DLL bundles
Build Perf (Dev) Bundle Perf (Prod)
✔ N/A
!Create DLL bundles
• A way of caching • Avoid rebuilding of
libraries • Not needed for production • Requires a custom DLL
build config
Code Splitting (Chunking)Separate application core from meaningful modules and load them on demand
Code Splitting (Chunking)
Route path
Splitting API
Chunk name
Code Splitting (Chunking)
Build Perf (Dev) Bundle Perf (Prod)
✔N/A
👁👁
*perceived performance
!Code Splitting (Chunking)
• Automatic code splitting based on require rules
• Asynchronous • Work great with React
Router • Improve perceived
performance • Improved TTII (Time to
Initial Impression)
Import Dependencies DirectlyInstead of importing the entire bundle, import direct files where possible
Import Dependencies Directly
Build Perf (Dev) Bundle Perf (Prod)
✔✔
!Import Dependencies Directly
• Poor man’s dead code elimination
• Improves code splitting
Export Only What You NeedExports create overhead and increase bundle size
Export Only What You Need
Build Perf (Dev) Bundle Perf (Prod)
✔N/A
React Optimizations in Babel ConfigRemove unneeded React code in Prod
React Optimizations in Babel Config
Build Perf (Dev) Bundle Perf (Prod)
✔✘
#1 React Perf Tip
The key to all React performance is avoiding wasteful CPU cycles. Most frequently this means optimizing the render() function.
Use PureComponent
Extend React.PureComponent to minimize render() execution count (requires React ^15.3.0)
!Use PureComponent
• Render only when properties or state has changed
• Replaces shallow-compare add-on
• Beware of nested state objects
Don’t Assign JSX to VariablesUse Functional (Stateless) Components instead to minimize render count
Bad
Avoid Large JSX BlocksUse Functional (Stateless) Components instead to minimize render count and keep code maintainable
Normalize State
Deeply nested objects (e.g. API) should be flattened to ensure efficient state processing
https://github.com/paularmstrong/normalizr
Use Memoized Selectors (Reselect)Compute (and memoize) derived data to minimize Redux state.
https://github.com/reactjs/reselect
Keep Redux Action Names ShortConstant string names do not have to be long. They cannot be minified.
Bonus Tips
Use Node v6.x
Up to 30% faster with Webpack and Server Side Rendering
Enable HMR
Don’t forget Hot Module Replacement for React components and Redux reducers
Webpack 2 Tree ShakingWebpack 2 enables direct ES6 imports and Tree Shaking dead code elimination
Critical Path CSS
Universal (Isomorphic) Apps may benefit from isomorphic-style-loader that handles critical path CSS automatically
Beware of CSS Scope CreepUse one CSS file for one Component to avoid inclusion of unnecessary CSS when using Style or Isomorphic Style loader
theme.scss combined.scss
component.js
bundle.js
CSS Scope Creep
theme.scss comp.scss
component.js
bundle.js
Minimal CSS Scope
Use SCSS Placeholder SelectorsPlaceholder selectors (%mySelector) will be compiled only when extended. This greatly improves CSS scope when importing SCSS files
React 0.14 vs 15.x
React 0.14 is faster in development, but slower in production. React 15.3.0 introduces PureComponent. Upgrade to 15.x if your app allows