Building Fast Angular Applications From End-to-End

Building Fast Angular Applications From End-to-End

82bafb0432ce4ccc9dcc26f94d5fe5bc?s=128

Minko Gechev

June 07, 2019
Tweet

Transcript

  1. @yourtwitter Building Fast Angular Applications From End-to-End Minko Gechev twitter.com/mgechev


    github.com/mgechev
 blog.mgechev.com ⚡
  2. @yourtwitter Description or Image @twitterhandle Agenda • Network performance •

    Tips & tricks • Application in production
  3. @yourtwitter Network performance Description or Image @twitterhandle

  4. @yourtwitter Shipping less JavaScript

  5. @yourtwitter @mgechev • Minification/dead code elimination • Differential loading •

    Code-splitting Shipping fewer bytes
  6. @yourtwitter @mgechev • Minification/dead code elimination • Differential loading •

    Code-splitting Shipping fewer bytes
  7. @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
  8. @mgechev -65KB polyfills ~2-10% smaller bundles

  9. @mgechev Step 1: Load HTML Step 2: Look at script

    tags Step 2: Download right version Differential loading
  10. @yourtwitter Differential loading <!DOCTYPE html> <html lang="en"> <head> <title>Differential loading

    </title> </head> <body> <script type="module" src="app-es2015.js"> </script> <script nomodule src="app-es5.js"> </script> </body> </html>
  11. @yourtwitter Differential loading <!DOCTYPE html> <html lang="en"> <head> <title>Differential loading

    </title> </head> <body> <script type="module" src="app-es2015.js"> </script> <script nomodule src="app-es5.js"> </script> </body> </html>
  12. @yourtwitter @mgechev Differential loading ✅ Simple deployment infrastructure ✅ Proposal

    for a browser standard WHATWG
  13. @yourtwitter @mgechev • Minification/dead code elimination • Differential loading •

    Code-splitting Shipping fewer bytes
  14. twitter.com/mgechev lazy-loading

  15. @yourtwitter @mgechev • Component-level • Route-level Code-splitting could be

  16. @yourtwitter @mgechev • Component-level • Route-level Code-splitting could be

  17. @mgechev

  18. @mgechev

  19. @yourtwitter @mgechev • Component-level • Route-level Code-splitting could be

  20. @mgechev

  21. @yourtwitter Route-based code-splitting const routes: Routes = [ { path:

    'settings', loadChildren: import('./settings/settings.module') .then(m => m.SettingsModule); },
 ... ];
  22. @mgechev

  23. @mgechev

  24. 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
  25. twitter.com/mgechev

  26. @yourtwitter @mgechev • Prefetch visible links • Predictive prefetching •

    Prefetch on mouse over Prefetching strategies
  27. @yourtwitter @mgechev • Prefetch visible links • Predictive prefetching •

    Prefetch on mouse over Prefetching strategies
  28. @mgechev

  29. @yourtwitter Prefetch visible links $ npm install ngx-quicklink

  30. @yourtwitter Prefetch visible links import { QuicklinkStrategy, QuicklinkModule } from

    'ngx-quicklink'; @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: QuicklinkStrategy }), QuicklinkModule], exports: [RouterModule] }) export class AppRoutingModule {}
  31. @yourtwitter @mgechev • Prefetch visible links • Predictive prefetching •

    Prefetch on mouse over Prefetching strategies
  32. @mgechev

  33. @mgechev

  34. twitter.com/mgechev

  35. twitter.com/mgechev app-routing.module.ts pseudo code 
 const routes: Routes = [

    { path: 'a/:id', loadChildren: './a.js' }, { path: 'b', loadChildren: './b.js' } ]; report /a/1 /a/2 /b
  36. twitter.com/mgechev app-routing.module.ts pseudo code 
 const routes: Routes = [

    { path: 'a/:id', loadChildren: './a.js' }, { path: 'b', loadChildren: './b.js' } ]; report /a/1 /a/2 /b
  37. twitter.com/mgechev app-routing.module.ts pseudo code 
 const routes: Routes = [

    { path: 'a/:id', loadChildren: './a.js' }, { path: 'b', loadChildren: './b.js' } ]; report /a/1 /a/2 /b /a/:id
  38. twitter.com/mgechev app-routing.module.ts pseudo code const module = 'settings.module.js'; const path

    = './settings'; const routes: Routes = [ { path: 'profile/:id', loadChildren: './profile/profile.module.js' }, { path: 'settings', loadChildren: path + '/' + module, } ];
  39. twitter.com/mgechev app-routing.module.ts pseudo code const module = 'settings.module.js'; const path

    = './settings'; const routes: Routes = [ { path: 'profile/:id', loadChildren: './profile/profile.module.js' }, { path: 'settings', loadChildren: path + '/' + module, } ];
  40. twitter.com/mgechev app-routing.module.ts pseudo code const module = 'settings.module.js'; const path

    = './settings'; const routes: Routes = [ { path: 'profile/:id', loadChildren: './profile/profile.module.js' }, { path: 'settings', loadChildren: path + '/' + module, } ];
  41. @mgechev main.js a.js b.js c.js 
 p = ( ...pairs)

    => { // Prefetch chunk // if connection // is sufficient }; p( ['b.js', 0.3], ['c.js', 0.7] ) p( ['a.js', 0.1], ['c.js', 0.9] ) 
 p( ['a.js', 1] )
  42. @mgechev

  43. @mgechev A performance budget is a limit for pages which

    the team is not allowed to exceed. Addy Osmani
  44. @yourtwitter Performance Budgets enforces constraints to let you have guarantees

    v8.0.0 https://angular.io/guide/build
  45. @mgechev

  46. @yourtwitter One more thing to make your apps faster ⚡

  47. @yourtwitter Angular projects without compression >27%

  48. @yourtwitter >80% Angular projects without CDN

  49. @mgechev

  50. @mgechev @angular/fire @azure/ng-deploy @zeit/ng-deploy

  51. @yourtwitter @mgechev Summary • Reducing the bundle size • Speeding

    up user navigations • Predictive prefetching • Automated deployment via CLI
  52. @mgechev Thank you! twitter.com/mgechev
 github.com/mgechev
 blog.mgechev.com