Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Predictive Prefetching for Angular

Minko Gechev
August 23, 2018
170

Predictive Prefetching for Angular

Websites are slow! Double-click shows that the average load time on a 3G network is 19 seconds! On top of that, on mobile devices, JavaScript compared to a JPG image with the same size may require x25 more processing time.

How to speed up our apps? Lazy-loading is here to help! By only loading the minimum amount of JavaScript during the initial page load we can improve the UX dramatically. However, this brings another set of questions - how to decide what to load lazily, how to provide instant page load by mindfully prefetching the bundles, without draining the users' mobile data plan?

Machine learning is already playing an essential role in our day-to-day life, and it has the potential to assist in our development process for smaller, smarter, and faster JavaScript applications!

In this talk, we'll see how we can create a machine learning model from a Google Analytics report. Later, by empowering static analysis techniques, we'll map this model to the lazy-loaded JavaScript chunks and apply predictive prefetching and data-driven bundling. In the last part of the presentation, we'll look at Guess.js which provides a sample implementation of these ideas.

Minko Gechev

August 23, 2018
Tweet

Transcript

  1. twitter.com/mgechev
    Predictive Prefetching
    twitter.com/mgechev
    github.com/mgechev
    blog.mgechev.com

    View Slide

  2. twitter.com/mgechev

    View Slide

  3. twitter.com/mgechev
    twitter.com/mgechev
    github.com/mgechev

    View Slide

  4. twitter.com/mgechev

    View Slide

  5. twitter.com/mgechev
    comparable to native

    View Slide

  6. twitter.com/mgechev
    Everything comes with a price tag

    View Slide

  7. twitter.com/mgechev

    View Slide

  8. twitter.com/mgechev

    View Slide

  9. twitter.com/mgechev

    View Slide

  10. twitter.com/mgechev

    View Slide

  11. twitter.com/mgechev

    View Slide

  12. twitter.com/mgechev

    View Slide

  13. twitter.com/mgechev
    https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e

    View Slide

  14. twitter.com/mgechev
    lazy-loading

    View Slide

  15. twitter.com/mgechev
    - Route-based
    - Component-based
    Lazy-loading strategies

    View Slide

  16. twitter.com/mgechev
    How do we pick the split points?

    View Slide

  17. twitter.com/mgechev
    often subjectively

    View Slide

  18. twitter.com/mgechev
    sometimes based on data

    View Slide

  19. twitter.com/mgechev
    - Manual
    - Error-prone
    but always…

    View Slide

  20. 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

    View Slide

  21. twitter.com/mgechev
    How do we pick the priorities of
    the bundles to pre-fetch?

    View Slide

  22. twitter.com/mgechev

    View Slide

  23. twitter.com/mgechev
    Lazy-load everything!

    View Slide

  24. twitter.com/mgechev
    Lazy-load everything!
    …and let tooling take care of the rest

    View Slide

  25. twitter.com/mgechev

    View Slide

  26. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  27. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  28. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  29. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  30. twitter.com/mgechev

    View Slide

  31. twitter.com/mgechev

    View Slide

  32. twitter.com/mgechev
    Route-based splitting

    View Slide

  33. twitter.com/mgechev
    $ npm run build
    # For Angular CLI
    $ serve -s dist

    View Slide

  34. twitter.com/mgechev
    Let’s emulate *really* bad conditions

    View Slide

  35. twitter.com/mgechev

    View Slide

  36. twitter.com/mgechev

    View Slide

  37. twitter.com/mgechev
    Let’s take a look at the GA graph

    View Slide

  38. twitter.com/mgechev

    View Slide

  39. twitter.com/mgechev

    View Slide

  40. twitter.com/mgechev
    - Main & Settings in same chunk
    ‣ Update of the source code
    - Pre-fetch FAQ when the user is at
    Home
    Possible optimizations

    View Slide

  41. twitter.com/mgechev

    View Slide

  42. twitter.com/mgechev
    early preview

    View Slide

  43. twitter.com/mgechev
    Supports Angular CLI 1.7
    Disclaimer

    View Slide

  44. twitter.com/mgechev
    $ npm run eject
    # For Angular CLI
    $ vim webpack.config.js

    View Slide

  45. twitter.com/mgechev
    const { GuessPlugin } =
    require('guess-webpack');
    "// ""...
    plugins: [
    "// ""...
    new GuessPlugin({ GA: 'XXXXXX' })
    ]
    "// ""...

    View Slide

  46. twitter.com/mgechev

    View Slide

  47. twitter.com/mgechev

    View Slide

  48. twitter.com/mgechev
    How it works…

    View Slide

  49. twitter.com/mgechev
    - guess-ga
    - guess-parser
    - guess-webpack
    Packages

    View Slide

  50. twitter.com/mgechev
    guess-ga
    Fetching structured data from Google Analytics

    View Slide

  51. twitter.com/mgechev
    const { fetch } = require(‘guess-ga');
    fetch({
    key: require('./c.json'),
    viewId: '000000000',
    period: { startDate, endDate },
    routes
    })
    .then(g "=> writeFileSync('data.json', JSON.stringify(g)));
    guess-ga

    View Slide

  52. twitter.com/mgechev
    guess-parser
    Gets metadata by statically analyzing our app

    View Slide

  53. twitter.com/mgechev
    guess-webpack
    Set of webpack plugins which automate the build

    View Slide

  54. twitter.com/mgechev
    GuessPlugin
    ClusterChunksPlugin RuntimePrefetchPlugin

    View Slide

  55. twitter.com/mgechev
    GuessPlugin
    ClusterChunksPlugin RuntimePrefetchPlugin

    View Slide

  56. twitter.com/mgechev
    RuntimePrefetchPlugin

    View Slide

  57. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  58. twitter.com/mgechev
    Markov Chain
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    /a
    /a/a /a/b
    /b
    /b/a
    /

    View Slide

  59. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Probability threshold: 0.5

    View Slide

  60. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Probability threshold: 0.5

    View Slide

  61. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Probability threshold: 0.5

    View Slide

  62. twitter.com/mgechev
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    - Download b.bundle.js
    Probability threshold: 0.5

    View Slide

  63. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    - Download b.bundle.js
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Probability threshold: 0.5

    View Slide

  64. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    Activity:
    - Download b.bundle.js
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Probability threshold: 0.5

    View Slide

  65. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Activity:
    - Download b.bundle.js
    - No action
    Probability threshold: 0.5

    View Slide

  66. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Activity:
    - Download b.bundle.js
    - No action
    Probability threshold: 0.5

    View Slide

  67. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Activity:
    - Download b.bundle.js
    - No action
    Probability threshold: 0.5

    View Slide

  68. twitter.com/mgechev
    /a
    /a/a /a/b
    /b
    /b/a
    /
    / /a /a/:id /b /b/a
    / 0 0.3 0 0.7 0
    /a 0 0 0.9 0.1 0
    /a/:id 0 1 0 0 0
    /b 0 0 0 0 1
    /b/a 0 1 0 0 0
    Activity:
    - Download b.bundle.js
    - No action
    - Download a.bundle.js
    Probability threshold: 0.5

    View Slide

  69. twitter.com/mgechev
    - Personalized bundling
    - Smarter clustering
    - Personalize pre-fetching
    - Reduced chunk over fetching
    - More robust parsers
    Future plans

    View Slide

  70. twitter.com/mgechev
    - https://mgv.io/dd-bundling
    - https://mgv.io/cost-of-js
    - https://mgv.io/predictive-fetching
    - https://mgv.io/guess
    References

    View Slide

  71. twitter.com/mgechev
    A new wave of data-driven web tooling is up to come

    View Slide

  72. Thank you!
    twitter.com/mgechev
    github.com/mgechev
    blog.mgechev.com

    View Slide