Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JS Fest 2019. Minko Gechev. Building Fast Angular Applications by Default

84 views

Published on

Angular grew significantly in the past few years from both a tooling and developer experience standpoint. This talk will explore many of the features and newer improvements in the pipeline that allow anyone to build and deploy performant apps with very little overhead. Through real demos and examples, we’ll cover Ivy, bundle budgeting, differential serving, automatic code-splitting, and progressive rehydration of SSR elements. In the second part of the talk, we’ll focus on how to efficiently prefetch and preload different modules and components.

Published in: Education
  • Be the first to comment

  • Be the first to like this

JS Fest 2019. Minko Gechev. Building Fast Angular Applications by Default

  1. 1. @mgechev Building Fast Angular Applications by Default Minko Gechev twitter.com/mgechev
 github.com/mgechev
 blog.mgechev.com
  2. 2. @yourtwitter Description or Image @twitterhandle Agenda ● Network performance ● Runtime performance ● Good practices ● Application in production ● Initial rendering
  3. 3. @yourtwitter Network performance Description or Image @twitterhandle
  4. 4. @yourtwitter@mgechev Good practices ● Ship fewer bytes of JavaScript ● Lazy loading ● Preloading & prefetching ● Server-side rendering ● Write efficient code
  5. 5. @yourtwitter Shipping less JavaScript
  6. 6. @yourtwitter@mgechev ● Minification/dead code elimination ● Differential loading or serving ● Code-splitting Shipping fewer bytes
  7. 7. @yourtwitter@mgechev ● Minification/dead code elimination ● Differential loading or serving ● Code-splitting Shipping fewer bytes
  8. 8. @yourtwitter@mgechev Differential loading ● Produce ES5 bundles for newer browsers ● Do not send polyfills to modern browsers ● Smaller payload ● Do not downlevel modern features ● Faster execution ● Smaller payload
  9. 9. @mgechev -40KB polyfills -7% each bundle
  10. 10. @mgechev Step 1: Load HTML Step 2: Look at script tags Step 2: Download right version Differential loading
  11. 11. @mgechev Step 1: Load HTML Step 2: Request JS Differential serving Step 3: Return JS based on userAgent
  12. 12. @yourtwitter@mgechev Differential loading ✅ Simple deployment infrastructure ✅ Proposal for a browser standard WHATWG
  13. 13. @yourtwitter Differential loading <!DOCTYPE html> <html lang="en"> <head> <title>Differential loading </title> </head> <body> <script type="module" src="app.mjs"> </script> <script nomodule src="app.js"> </script> </body> </html>
  14. 14. @yourtwitter Differential loading <!DOCTYPE html> <html lang="en"> <head> <title>Differential loading </title> </head> <body> <script type="module" src="app.mjs"> </script> <script nomodule src="app.js"> </script> </body> </html>
  15. 15. @mgechev
  16. 16. @yourtwitter Angular CLI Introduced this feature in v8.0.0
  17. 17. @yourtwitter@mgechev ● Set the target in tsconfig.json to es2015 ● Set the minimum supported browsers in browserlist Differential loading with Angular CLI version 8
  18. 18. @yourtwitter@mgechev ● Minification/dead code elimination ● Differential loading or serving ● Code-splitting Shipping fewer bytes
  19. 19. twitter.com/mgechev lazy-loading
  20. 20. @yourtwitter@mgechev ● Component-level ● Route-level Code-splitting could be
  21. 21. @yourtwitter@mgechev ● Component-level ● Route-level Code-splitting could be
  22. 22. @mgechev
  23. 23. @mgechev
  24. 24. @mgechev https://www.youtube.com/watch?v=MMPl9wHzmS4
  25. 25. @yourtwitter@mgechev ● Component-level ● Route-level Code-splitting could be
  26. 26. @mgechev
  27. 27. @yourtwitter Route-based code-splitting const routes: Routes = [ { path: 'settings', loadChildren: './settings/settings.module#SettingsModule' }, { path: 'article', loadChildren: './article/article.module#ArticleModule' } ];
  28. 28. @yourtwitter Route-based code-splitting in Ivy const routes: Routes = [ { path: 'settings', loadChildren: import('./settings/settings.module') .then(m => m.SettingsModule); },
 ... ];
  29. 29. @yourtwitter Route-based code-splitting in Ivy const routes: Routes = [ { path: 'settings', loadChildren: import('./settings/settings.module') .then(m => m.SettingsModule); },
 ... ]; Experimental
  30. 30. @yourtwitter@mgechev 1. Definition of a lazy module 2. Declaration of a lazy route 3. Definition of a component 4. Declaration of a eager route Steps for creating a lazy-loaded module
  31. 31. @mgechev
  32. 32. @yourtwitter Route-based code-splitting with the future Angular CLI $ ng g module about --route=about --module=index
  33. 33. @yourtwitter@mgechev Questions
  34. 34. @mgechev
  35. 35. @mgechev
  36. 36. twitter.com/mgechev Step 1: Open https://example.com/ Step 2: Determine JavaScript which is likely to be required Step 3: Download the chunks Step 4: Store chunks in browser cache Pre-fetching
  37. 37. twitter.com/mgechev
  38. 38. @yourtwitter@mgechev ● Prefetch visible links ● Predictive prefetching ● Prefetch on mouse over Prefetching strategies
  39. 39. @yourtwitter@mgechev ● Prefetch visible links ● Predictive prefetching ● Prefetch on mouse over Prefetching strategies
  40. 40. @mgechev
  41. 41. @yourtwitter Prefetch visible links $ npm install ngx-quicklink
  42. 42. @yourtwitter Prefetch visible links import { QuicklinkStrategy } from 'ngx-quicklink'; @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: QuicklinkStrategy })], exports: [RouterModule] }) export class AppRoutingModule {}
  43. 43. @yourtwitter Prefetch visible links import { QuicklinkModule } from 'ngx-quicklink'; @NgModule({ imports: [ ... QuicklinkModule ], exports: [ ... QuicklinkModule, ] }) export class SharedModule {}
  44. 44. @yourtwitter@mgechev ● Prefetch visible links ● Predictive prefetching ● Prefetch on mouse over Prefetching strategies
  45. 45. @mgechev
  46. 46. @mgechev
  47. 47. @mgechev early alpha
  48. 48. @mgechev A performance budget is a limit for pages which the team is not allowed to exceed. Addy Osmani
  49. 49. @yourtwitter Performance Budgets enforces constraints to let you have guarantees v8.0.0 https://angular.io/guide/build
  50. 50. @yourtwitter Angular projects without compression >27%
  51. 51. @yourtwitter >80%Angular projects without CDN
  52. 52. @yourtwitter ng deploy $ ng add [PROVIDER] $ ng run app:deploy
  53. 53. @mgechev
  54. 54. @mgechev Partnering with
  55. 55. @yourtwitter@mgechev Questions
  56. 56. @yourtwitter Server-side rendering
  57. 57. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  58. 58. @yourtwitter@mgechev ● Faster initial contentful paint ● Better SEO ● Better time to interactive? Benefits of SSR
  59. 59. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  60. 60. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  61. 61. @mgechev https://addyosmani.com/blog/rehydration/
  62. 62. twitter.com/mgechev Destructive Rehydration DOM Component tree
  63. 63. twitter.com/mgechev Progressive Rehydration DOM ( )
  64. 64. twitter.com/mgechev Progressive Rehydration DOM ( )
  65. 65. twitter.com/mgechev ( ) Progressive Rehydration DOM
  66. 66. twitter.com/mgechev ( ) Progressive Rehydration DOM
  67. 67. twitter.com/mgechev ( ) Progressive Rehydration DOM ChildCmp1
  68. 68. twitter.com/mgechev ( ) Progressive Rehydration DOM ChildCmp1
  69. 69. twitter.com/mgechev ( ) Progressive Rehydration DOM ChildCmp1
  70. 70. twitter.com/mgechev ( ) Progressive Rehydration DOM ChildCmp1 ChildCmp2
  71. 71. twitter.com/mgechev ( ) Progressive Rehydration DOM ChildCmp1 ChildCmp2
  72. 72. twitter.com/mgechev ( ) Progressive Rehydration DOM RootCmp ChildCmp1 ChildCmp2
  73. 73. @yourtwitter Progressive bootstrapping
  74. 74. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  75. 75. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  76. 76. @mgechev Step 1: Request page Step 2: Render page Step 3: Paint & load JS Server-side rendering Step 4: Bootstrap app
  77. 77. twitter.com/mgechev Progressive loading DOM
  78. 78. twitter.com/mgechev Progressive loading DOM ⌨Key down
  79. 79. twitter.com/mgechev Progressive loading DOM ChildCmp
  80. 80. @yourtwitter Faster Rendering
  81. 81. @yourtwitter@mgechev ● Discovery of dependencies ● Efficient code generation ● Efficient runtime Runtime optimizations
  82. 82. @mgechev Model View dependencies Compiler
 
 
 
Front-end Back-end Input Output
  83. 83. @mgechev <p class="card-text"> {{ comment.body + 'foo' }} </p> if (rf & 1) { // Create } if (rf & 2) { ɵtextBinding(3, ɵinterpolation1(" ", ctx.comment.body, " " ...)); }
  84. 84. @yourtwitter@mgechev ● Tree-shakeable code ● Monomorphic executions Efficient code generation
  85. 85. @mgechev Tree-shakeable code import { ɵelementStart, … } from ... if (rf & 1) { ɵelementStart(0, "div", _c0); ɵelementStart(2, "p", _c2); ɵtext(3); ɵelementEnd(); ɵelementEnd(); } if (rf & 2) { ɵtextBinding(3, ... ɵinterpolation1( ...) } The compiler imports only what given component needs
  86. 86. @yourtwitter@mgechev In collaboration with v8 team to make sure we generate code optimizable by the JavaScript engine Monomorphic code
  87. 87. @yourtwitter@mgechev Summary ● Reducing the bundle size ● Speeding up user navigations ● Automated deployment via CLI ● Progressive rehydration ● Compile-time optimizations
  88. 88. @yourtwitter@mgechev Questions
  89. 89. @mgechev Thank you! twitter.com/mgechev
 github.com/mgechev
 blog.mgechev.com

×