Next Gen Web: Scaling Progressive Web Apps

Next Gen Web: Scaling Progressive Web Apps

A case study of how we re-built Flipkart.com's desktop website as a progressive web app while dealing with the unique challenges of scaling to a new ecosystem without compromising on performance.

D4f441c819ce53b039b514a3a6ca4803?s=128

Abhinav Rastogi

September 15, 2016
Tweet

Transcript

  1. The Next-Gen Web Abhinav Rastogi @_abhinavrastogi A case study of

    how we re-built Flipkart.com
  2. None
  3. Flipkart Lite Service Worker, App Shells Progressive Web App

  4. Probably the first
 mobile -> desktop migration!

  5. Significant Differences Mobile vs Desktop

  6. Requirements User Behaviour Network Conditions Device Capabilities Browser Fragmentation

  7. Typical SPA • Serve empty HTML from server • Client

    downloads JS bundle • Shows loaders, makes API calls • Renders full page • Subsequent navigations are client-side
  8. Typical SPA • Serve empty HTML from server • Client

    downloads JS bundle • Shows loaders, makes API calls • Renders full page • Subsequent navigations are client-side Pros: • Easy to implement • Fast navigations • Cheap server processing • Low server QPS
  9. First Paint + Full Render

  10. Cons: • Empty page for a long time • SEO

    jeopardised • JS bundle is huge
  11. Upgrade #1 - App Shells Initial HTML renders ‘loading state’


    (Build-time rendering)
  12. Upgrade #1 - App Shells Initial HTML renders ‘loading state’


    (Build-time rendering) Pros: • No more empty page!
  13. Full Render with content First Paint (Loading state)

  14. Cons: • Stuck in “Loading” state • First-paint is not

    meaningful content
  15. Update #2 - Server Render • Render full page on

    server for first request • Client loads JS, makes API calls • Re-renders complete page
  16. Update #2 - Server Render • Render full page on

    server for first request • Client loads JS, makes API calls • Re-renders complete page Pros: • First paint is meaningful • SEO is solved!
  17. Client Render + Interactive First Paint + Full Render

  18. Cons: • Significant increase in server load • HTML download

    size increased • Response time increased • JS file is still huge
  19. Update #3 - Universal app • Render only SEO-critical content

    on server • Client continues to work as normal • React is able to reconcile the DOM
  20. Update #3 - Universal app

  21. Update #3 - Universal app Pros: • Lesser load on

    server • Better SEO, smaller HTML • Header/Footer can load quicker :: Perceived perf! Cons: • First paint still slow • No organic content in first- paint • JS file is still huge
  22. Update #4 - First-fold Render above-the-fold content also on the

    server
  23. Update #4 - First-fold Progressive Images!

  24. Update #4 - First-fold Pros: • Making API calls from

    server is better • Organic content in first paint! • Send api data as part of HTML
  25. #5 - Route based chunking • Break JS bundle into

    parts based on routes • Only load JS required for the current page • Subsequent JS can be loaded when needed
  26. #5 - Route based chunking

  27. Break JS bundle? • Define “split-points” • Replace “import” with

    “require.ensure” • Webpack & React-Router take care of the rest!
  28. None
  29. (as of react-router@2.7.0)

  30. Full Render with content

  31. Typical HTML page

  32. Update #6 - PRPL • Push critical resources for the

    initial route. • Render initial route. • Pre-cache remaining routes. • Lazy-load and create remaining routes on demand.
  33. Basic Preloading

  34. #7 - HTML streaming • Some parts of html are

    independent of page type/ url. Send those first to start resource download • Smart use of preload, prefetch and defer!
  35. Basic Streaming using Express.js

  36. Static resource download starts in milliseconds First paint with meaningful

    content Full page render
  37. Pros: • CSS and JS resources can start downloading within

    milliseconds of request • Page is ready to render as soon as HTML is downloaded Cons: • Server has to keep connection open with client until download completes • Client can download limited number of resources at a time
  38. Chunking + Streaming + Preload (PRPL) Real first-paint First-paint event?

  39. Track custom perf events • Existing browser events like DOMContentLoaded

    and Load are not sufficient • Track real first-paint using RAF and User Timing API • More custom metrics?
  40. Key Take-aways • Problems and solutions are different for Mobile

    and Desktop • Treat performance as a feature • You can’t optimise what you can’t measure • You can split JS bundles into smaller chunks • Smart preloading of chunks goes a long way • RUM is important. Synthetic testing can only do so much.
  41. @_abhinavrastogi Thank you!