Slide 1

Slide 1 text

JavaScript Code Splitting JSSophia #2 — April 25, 2019 Olivier Audard — @_dhar Pic: Ahsan S.

Slide 2

Slide 2 text

Why do we need to split code exactly? 2 Pic: Janis Rozenfelds

Slide 3

Slide 3 text

WH Y DO WE NEE D COD E S PL IT T IN G? 3 The Web has changed... • Web apps are more complex than they used to be • Many different devices: Mobile/Low-end devices • Many different network conditions (2G/3G)

Slide 4

Slide 4 text

© 201 9 CO NF I D E N TI A L Some stats from Chrome Dev Summit 2017 WH Y DO WE NEE D COD E SP L IT T IN G? 53% of users abandon sites that takes more than 3 seconds to load 4

Slide 5

Slide 5 text

© 201 9 CO NF I D E N TI A L Some stats from Chrome Dev Summit 2017 WH Y DO WE NEE D COD E SP L IT T IN G? 19sec Average mobile web page load on 3G 5

Slide 6

Slide 6 text

© 201 9 CO NF I D E N TI A L Some stats from Chrome Dev Summit 2017 WH Y DO WE NEE D COD E SP L IT T IN G? 60% of mobile connections world-wide are 2G 6

Slide 7

Slide 7 text

© 201 9 CO NF I D E N TI A L We set a budget in time of <= 5 seconds first-load Time-to- Interactive and <= 2s for subsequent loads Alex Russell — Can You Afford It?: Real-world Web Performance Budgets WH Y DO WE NEE D COD E SP L IT T IN G? 7

Slide 8

Slide 8 text

© 201 9 CO NF I D E N TI A L The default global baseline is a ~$200 Android device on a 400Kbps link with a 400ms round-trip-time (“RTT”) Alex Russell — Can You Afford It?: Real-world Web Performance Budgets WH Y DO WE NEE D COD E SP L IT T IN G? 8

Slide 9

Slide 9 text

© 201 9 CO NF I D E N TI A L This translates into a budget of ~130-170KB of critical-path resources, depending on composition Alex Russell — Can You Afford It?: Real-world Web Performance Budgets WH Y DO WE NEE D COD E SP L IT T IN G? 9

Slide 10

Slide 10 text

Code Splitting flavours 1 0 Pic: Pietro De Grandi

Slide 11

Slide 11 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVO U R S • Mainly for apps using server side routing • End-users shouldn't need to download every script when they only use a single page/route 1 1

Slide 12

Slide 12 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 2 myapp.io/ myapp.io/profile myapp.io/preferences big-bundle.js index.js profile.js preferences.js big-bundle.js big-bundle.js

Slide 13

Slide 13 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 3 module.exports = { // ... entry: { index: './src/home/index.js', profile: './src/profile/index.js', preferences: './src/preferences/index.js' } }; See: Webpack - Entry Points documentation

Slide 14

Slide 14 text

© 201 9 CO NF I D E N TI A L Vendor splitting COD E S P L IT T IN G FL AVO U R S • Your app has a different lifecycle that its dependencies • End-users shouldn't need to re-download everything every time your app is updated • Vendor splitting prevents cache invalidation for dependencies 1 4

Slide 15

Slide 15 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 5 big-bundle.js vendors.js app.js

Slide 16

Slide 16 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 6 myapp.io/ myapp.io/profile myapp.io/preferences big-bundle.js preferences.js big-bundle.js big-bundle.js vendors.js profile.js vendors.js index.js vendors.js

Slide 17

Slide 17 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 7 module.exports = { //... optimization: { splitChunks: { // ... name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, chunks: 'all' }, } }, runtimeChunks: { name: 'runtime' // Webpack's runtime/manifest get its own chunk }, } }; See: Webpack - Optimization documentation

Slide 18

Slide 18 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 8 module.exports = { //... optimization: { splitChunks: { // ... name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, chunks: 'all' }, } }, runtimeChunks: { name: 'runtime' // Webpack's runtime/manifest get its own chunk }, } }; See: Webpack - Optimization documentation

Slide 19

Slide 19 text

© 201 9 CO NF I D E N TI A L Entry point splitting COD E S P L IT T IN G FL AVOU R S 1 9 module.exports = { //... optimization: { splitChunks: { // ... name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, chunks: 'all' }, } }, runtimeChunks: { name: 'runtime' // Webpack's runtime/manifest get its own chunk }, } }; See: Webpack - Optimization documentation

Slide 20

Slide 20 text

© 201 9 CO NF I D E N TI A L Dynamic splitting COD E S P L IT T IN G FL AVO U R S 20 import(/* webpackChunkName: "mymodule" */ './my-module.js') .then(({ default: myModule }) => doSomethingCoolWith(myModule)) .catch(error => 'Oops! Something went wrong...') See: Webpack - Code Splitting documentation

Slide 21

Slide 21 text

Code splitting in pratice 2 1 Pic: Alyson McPhee

Slide 22

Slide 22 text

© 201 9 CO NF I D E N TI A L Every optional or conditional feature must be lazy loaded Mutually exclusive features must be in distinct chunks Identify your app critical path(s). Optimize there first. Optimize the Critical Path(s) COD E S P L IT T IN G I N P RAT I C E 2 2

Slide 23

Slide 23 text

© 201 9 CO NF I D E N TI A L Code will be more difficult to reason about. Team alignment is required App framework/architecture might get in the way. It's not an easy way... COD E S P L IT T IN G I N P RAT I C E 2 3

Slide 24

Slide 24 text

© 201 9 CO NF I D E N TI A L 3 2 1 Ship "work in progress" hidden features Fine-tuned browser support A/B testing COD E S P L IT T IN G I N P RAT I C E 2 4 A few atypical use-cases

Slide 25

Slide 25 text

© 201 9 CO NF I D E N TI A L Always monitor your chunks No Really! Always monitor your chunks! Create your split points early Additional takeaways COD E S P L IT T IN G I N P RAT I C E 2 5

Slide 26

Slide 26 text

Thank you! Pic: Artem Maltsev

Slide 27

Slide 27 text

JAVA S CR IP T CO DE S P L I T TI N G 2 7 References • Reduce JavaScript Payloads with Code Splitting • Lessons Learned: Code Splitting with Webpack and React • https://webpack.js.org/ • https://github.com/webpack-contrib/webpack- bundle-analyzer • http://chrisbateman.github.io/webpack-visualizer/