Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript Code Splitting

oad
April 25, 2019

JavaScript Code Splitting

Code Splitting has become a mandatory piece of modern web applications tech stack. In this talk, I briefly recap where that need comes from, what are the tools and principles at our disposal to solve this. Then I follow with some guidelines and concrete feedbacks on how to use those tools and principles during our day-to-day work as web developers.

oad

April 25, 2019
Tweet

Other Decks in Technology

Transcript

  1. 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)
  2. © 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
  3. © 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
  4. © 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
  5. © 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
  6. © 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
  7. © 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
  8. © 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
  9. © 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
  10. © 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
  11. © 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
  12. © 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
  13. © 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
  14. © 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
  15. © 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
  16. © 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
  17. © 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
  18. © 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
  19. © 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
  20. © 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
  21. © 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
  22. 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/