Webpack & React Performance in 16+ Steps

Post on 16-Apr-2017

1.940 views 1 download

Transcript of Webpack & React Performance in 16+ Steps

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

Reach out! 🙌

moduscreate.com @moduscreate

Grgur Grisogono @ggrgur