$30 off During Our Annual Pro Sale. View Details »

Fast Angular Apps from End to End

Minko Gechev
September 29, 2020

Fast Angular Apps from End to End

Minko Gechev

September 29, 2020
Tweet

More Decks by Minko Gechev

Other Decks in Programming

Transcript

  1. @yourtwitter Fast Angular Apps from End to End Minko Gechev

    twitter.com/mgechev github.com/mgechev blog.mgechev.com
  2. @yourtwitter Description or Image @twitterhandle Agenda • Web vitals and

    LCP • Tips & tricks • Application in production
  3. @mgechev

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

    Understand what you serve • Code-splitting • Server-side rendering Improving LCP
  5. twitter.com/mgechev

  6. @mgechev

  7. @mgechev

  8. @yourtwitter @mgechev Differential loading • Produce ES2015 for modern browsers

    • Do not send polyfills to modern browsers • Smaller payload • Do not downlevel modern features • Faster execution • Smaller payload
  9. @mgechev -65KB polyfills ~2-10% smaller bundles

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

    tags Step 2: Download right version Differential loading
  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 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>
  13. @yourtwitter If you’re still not on version 8 $ ng

    update @angular/cli @angular/core
  14. @mgechev My production bundles are so small! Nobody

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

    Understand what you serve • Code-splitting • Server-side rendering Improving LCP
  16. @mgechev Framework has constant size framework app code

  17. @mgechev Framework has constant size framework app code dependency dependency

  18. @mgechev Framework has constant size framework app code dependency dependency

    dependency dependency dependency dependency dependency
  19. @mgechev Framework has constant size framework app code dependency dependency

    dependency dependency dependency dependency dependency
  20. @yourtwitter Using source-map-explorer to understand your bundles $ vim angular.json

    $ ng build --prod $ source-map-explorer dist/app/main.hash.js
  21. @mgechev

  22. @mgechev Large 3P dependency Other dependencies

  23. @mgechev Framework

  24. @yourtwitter @mgechev Shipping fewer bytes • Minification/dead code elimination •

    Differential loading • Understand what you serve • Code-splitting • Server-side rendering
  25. twitter.com/mgechev lazy-loading

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

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

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

  29. @mgechev

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

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

  32. @mgechev

  33. 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 Preloading
  34. twitter.com/mgechev

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

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

    Prefetch on mouse over Prefetching strategies
  37. @mgechev

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

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

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

    Prefetch on mouse over Prefetching strategies
  41. @mgechev

  42. @mgechev

  43. @mgechev Broken window

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

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

    v8.0.0 https://angular.io/guide/build
  46. @mgechev SSR for faster LCP

  47. @mgechev SSR enabled app Node.js Browser API server

  48. @mgechev SSR enabled app https://example.com Node.js Browser API server

  49. @mgechev SSR enabled app https://example.com Node.js Browser API server

  50. @mgechev

  51. @yourtwitter $ ng add @nguniversal/express-engine

  52. @yourtwitter Deploying an SSR app with a single command

  53. twitter.com/ mgechev New in @angular/fire

  54. New in @angular/fire

  55. twitter.com/ mgechev New in @angular/fire

  56. @mgechev @angular/fire @azure/ng-deploy @zeit/ng-deploy angular-cli-ghpages @netlify-builder/deploy

  57. @yourtwitter One more feature to make your apps faster ⚡

  58. @yourtwitter @mgechev • Inline critical CSS • Lazy-load styles •

    Inline fonts Removal of blocking resources
  59. @yourtwitter <!DOCTYPE html> <html lang="en"> <head> <link href="icon.css" rel="stylesheet"> <link

    href="styles.css" rel="stylesheet"> </head> <body> <div class="bar"> <div class="spinner"> </div> <app-root> </app-root> </div> </body> </html>
  60. @yourtwitter <!DOCTYPE html> <html lang="en"> <head> <link href="icon.css" rel="stylesheet"> <link

    href="styles.css" rel="stylesheet"> </head> <body> <div class="bar"> <div class="spinner"> </div> <app-root> </app-root> </div> </body> </html>
  61. @yourtwitter <!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="styles.css" media="print"

    onload="this.media='all'"> <style> div.bar { /* ... */ } .bar .spinner { /* ... */ } </style> </head> <body> ... </body> </html>
  62. @yourtwitter Coming soon ⚡

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

    up user navigations • Predictive prefetching • SSR for faster LCP • Automated deployment via CLI
  64. @mgechev Thank you! twitter.com/mgechev github.com/mgechev blog.mgechev.com Survey: mgv.io/talk