Honey, I shrunk your Ember app

2a9ae0d13241afce653f9354ca23f012?s=47 Simon Ihmig
October 12, 2018

Honey, I shrunk your Ember app

Ember does not have the best reputation for being suited for mobile apps, mostly for being "too large". But why does size matter, and how can we keep it small? Future techniques like tree-shaking and code-splitting will support this task. But there are quite a few things you can do today to reduce your bundle size.

Based on the experience of optimizing my own app, this talk will guide you through the iterative process of measuring, analyzing and optimizing your app's size. For each of these phases I will introduce you to some essential tools and helpful practical tips.

2a9ae0d13241afce653f9354ca23f012?s=128

Simon Ihmig

October 12, 2018
Tweet

Transcript

  1. None
  2. SIMON IHMIG @simonihmig

  3. None
  4. None
  5. None
  6. None
  7. None
  8. KALIBER5 We ❤ Ember We ❤ Open Source We for

    talent www.kaliber5.de www.github.com/kaliber5
  9. None
  10. None
  11. None
  12. None
  13. None
  14. www.thelocalwater.com Invitation Code: emberfest

  15. None
  16. WHY DOES IT MATTER?

  17. WHY DOES IT MATTER? https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4

  18. WHY DOES IT MATTER? • Download • Parse • Compile

    • Execute 30% of overall time CPU-bound Network-bound
  19. THE FUTURE

  20. None
  21. TREE SHAKING // main.js import { foo } from 'foo-bar';

    // foo-bar.js export function foo() { … } export function bar() { … }
  22. CODE SPLITTING /order 30 % /cart 15 % /products 35

    % / 20 % /order 30 % /cart 15 % /products 35 % / 20 %
  23. THE FUTURE

  24. THE PRESENT

  25. THE OPTIMIZATION CYCLE

  26. Measure Analyze Optimize

  27. Measure Analyze Optimize

  28. WHAT TO MEASURE • measure your production build • measure

    after minification (uglify) and compression (gzip)
  29. HOW TO MEASURE • ember build -prod
 ember asset-sizes

  30. HOW TO MEASURE • What’s missing: continuous automatic monitoring

  31. Introducing EMBER-CLI-BUNDLESIZE

  32. EMBER-CLI-BUNDLESIZE • Test against a given size budget • Integrates

    into your CI • Prevents accidental bloat
  33. EMBER-CLI-BUNDLESIZE // config/bundlesize.js

  34. Measure Analyze Optimize

  35. None
  36. BROCCOLI-CONCAT-ANALYSER • Visualizes asset sizes and their composition of modules

    • Provides insights on how modules/packages/addons affect the total size • Works with any broccoli-concat based broccoli setup • Not integrated into Ember CLI, troublesome to set up
  37. Introducing EMBER-CLI-BUNDLE-ANALYZER

  38. EMBER-CLI-BUNDLE-ANALYZER • Wraps broccoli-concat-analyser into an addon • Open http://localhost:4200/_analyze

  39. None
  40. None
  41. None
  42. Play with the demo at: https://github.com/kaliber5/ember-cli-bundle-analyzer

  43. Measure Analyze Optimize

  44. THE BEGINNING OF OUR JOURNEY 500KB thelocalwater.com

  45. CUT DOWN ON ADDONS

  46. CUT DOWN ON ADDONS • Addons are a double-edged sword

    • Addon size is mostly intransparent • (Nested) dependencies can have a huge effect, e.g. ember-lodash
  47. CUT DOWN ON ADDONS • Exclude addon(s) from production build

  48. CUT DOWN ON ADDONS 500KB Removed ember-moment Replaced by a

    few custom date helpers
  49. CUT DOWN ON ADDONS Reduction 20.7KB (4.1%) 479KB Removed ember-moment

    Replaced by a few custom date helpers
  50. CUT DOWN ON ADDONS Reduction 26.7KB (5.3%) 452KB Removed liquid-fire

    Was mostly unused, replaced with some CSS transitions
  51. MANUAL DEAD CODE ELIMINATION

  52. MANUAL DEAD CODE ELIMINATION • Some addons provide include/exclude functionality.

    • ember-bootstrap • ember-composable-helpers • ember-math-helpers • ember-metrics • Addon developers here? It’s not that hard, using broccoli-funnel
  53. MANUAL DEAD CODE ELIMINATION But what about my own code,

    or other addons?
  54. MANUAL DEAD CODE ELIMINATION • Use ember-cli-funnel to… • remove

    unused components • remove routes depending on build/deployment target • remove services only used for development/testing (e.g. Mocks)
  55. MANUAL DEAD CODE ELIMINATION Removed unused code Removed unused ember-bootstrap

    components, 
 and in-app components using ember-cli-funnel 452KB
  56. MANUAL DEAD CODE ELIMINATION Reduction 12.4KB (2.5%) 440KB Removed unused

    code Removed unused ember-bootstrap components, 
 and in-app components using ember-cli-funnel
  57. None
  58. BYE BYE JQUERY • As of Ember CLI / Ember

    3.4 RFC294 is implemented
  59. BYE BYE JQUERY • refactor your application code (ember-ajax ->

    ember-fetch) • refactor your test suite • Use RFC268 based tests • Use @ember/test-helpers instead of global test helpers / this.$() • Codemods can help: 
 ember-qunit-codemod, ember-mocha-codemods, ember-test-helpers-codemod • must not rely on addons still requiring jQuery
  60. BYE BYE JQUERY Removed jQuery Removed jQuery from own code,

    „fixed“ 3rd-party addons, replaced ember-ajax with ember-fetch 440KB
  61. BYE BYE JQUERY Reduction 31.8KB (6.4%) 408KB Removed jQuery Removed

    jQuery from own code, „fixed“ 3rd-party addons, replaced ember-ajax with ember-fetch
  62. KNOW YOUR TARGETS

  63. KNOW YOUR TARGETS • Supporting older browsers (hint: IE) comes

    at a cost • Transpilation (Babel) and possibly Polyfills (Babel polyfill/core-js) are required for legacy browsers • Today’s evergreen browser support ES2015+ natively
  64. KNOW YOUR TARGETS Dropped IE11 support Shipping native ES6 code

    408KB
  65. KNOW YOUR TARGETS Reduction 11KB (2.2%) 397KB Dropped IE11 support

    Shipping native ES6 code
  66. KNOW YOUR TARGETS Reduction 32.4KB (6.5%) 365KB Removed Babel polyfill

    Which modern browsers do not need
  67. None
  68. Zopfli Brotli

  69. Zopfli • 5% better compression • Gzip compatible • Supported

    by all browsers • 80x compression time • Supported by 
 ember-cli-deploy-{gzip,compress} • node-zopfli unmaintained
  70. Brotli • 17% better compression • Supported by all the

    latest modern browsers • But not: IE11, iOS <11
  71. ZOPFLI / BROTLI 1. Serve Brotli only • If all

    your target browsers support it, just use Brotli 2. Serve Brotli and Zopfli/Gzip • Generate *.br and *.gz files • Serve the appropriate ones based on Accept-Encoding HTTP header • Not supported by most CDNs 3. Serve Zopli only
  72. ZOPFLI / BROTLI Use Zopfli compression for deployment Updated ember-cli-deploy-gzip

    to use zopfli 365KB
  73. ZOPFLI / BROTLI Reduction 16.4KB (4.5%) 349KB Use Zopfli compression

    for deployment Updated ember-cli-deploy-gzip to use zopfli
  74. ZOPFLI / BROTLI Reduction 62KB (17%) 303KB Use Brotli compression

    for deployment Alternative scenario assuming brotli instead of zopfli
  75. THE END OF OUR JOURNEY 197KB 303KB

  76. THANK YOU!