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

Introduction to Performance APIs

Shogo Sensui
February 19, 2019

Introduction to Performance APIs

2019年2月19日に開催された Chrome Tech Talk Night #12 https://developers-jp.googleblog.com/2019/02/chrometechtalknight12.html の「Introduction to Performance APIs」のセッション資料です。

Shogo Sensui

February 19, 2019
Tweet

More Decks by Shogo Sensui

Other Decks in Technology

Transcript

  1. Introduction to
    Performance APIs
    Chrome Tech Talk Night #12
    Shogo Sensui (@1000ch)

    View full-size slide

  2. Shogo Sensui
    (@1000ch)
    Software Engineer
    Merpay, Inc / Mercari, Inc

    View full-size slide

  3. Table of contents
    ● Lazy Loading
    ● Prefetch
    ● Off The Main Thread

    View full-size slide

  4. Lazy Loading

    View full-size slide

  5. Intersection Observer
    > The Intersection Observer API
    provides a way to asynchronously
    observe changes in the intersection
    of a target element with an
    ancestor element or with a
    top-level document's viewport.
    const observer = new
    IntersectionObserver((entries) => {
    for (const entry of entries) {
    if (entry.isIntersecting) {
    console.log(entry);
    }
    }
    });
    const el = document.querySelector('#el);
    observer.observe(el);

    View full-size slide

  6. WebKit shipped!!!

    View full-size slide

  7. Intersection Observer v2
    Intersection Observer v2 will detect
    the actual visiblity (like “opacity”).
    ● New options
    ○ trackVisiblity constructor
    option to track visiblity
    ○ isVisible property in
    IntersectionObserverEntry
    ● IntersectionObserver v2 demo
    const el = document.querySelector('#el);
    const observer = new
    IntersectionObserver((entries) => {
    for (const entry of entries) {
    if (entry.isVisible) {
    console.log(entry);
    }
    }
    });
    observer.observe(el, {
    trackVisiblity: true
    });

    View full-size slide

  8. Browser native lazy-loading
    lazyload attribute to load if
    display with-in viewport.
    ● will be enabled on...


    ● Lazyload images and iframes
    by bengreenstein · Pull Request
    #3752 · whatwg/html.
    ● Blink LazyLoad Design Docs
    (public)
    src="https://example.com/image.jpg"
    lazyload="on">
    src="https://google.com"
    lazyload="on">

    View full-size slide

  9. ⚡ Prefetch

    View full-size slide

  10. Priority Hints for resource loading
    importance attribute to indicate
    resource priority.
    ● will be enabled on...


    ○ <br/>○ <link><br/>○ fetch()<br/>● Priority Hints Draft Community<br/>Group Report 18 October 2018<br/><img<br/>src="https://example.com/image.jpg"<br/>importance="high"><br/><iframe<br/>src="https://example.com"<br/>importance="low"><br/></iframe><br/><script><br/>fetch('https://google.com', {<br/>importance: 'high'<br/>});<br/>

    View full-size slide

  11. Resource Hints
    Resource Hints provides
    speculative loading which consists
    of...
    ● DNS Prefetch: host
    ● Preconnect: host
    ● Prefetch: resources
    ● Prerender: specified page


    rel="prefetch" as="image"
    href="https://example.com/high-priority.jpg">
    rel="prerender"
    href="https://example.com/">

    View full-size slide

  12. https://www.igvita.com/2015/08/17/eliminating-roundtrips-with-preconnect/

    View full-size slide

  13. Preload
    Preload provides aggressive loading
    ● For nested resources for initial
    loading
    ○ e.g) Images referred in CSS
    ○ e.g) JavaScript loaded on JavaScript
    ● Similar to Resource Hints
    rel="preload"
    href="https://example.com/high-priority.jpg">
    rel="preload"
    href="https://example.com/high-priority.js">

    View full-size slide

  14. Chrome Prerender History
    chrome://net-internals/#prerender

    View full-size slide

  15. GoogleChromeLabs/quicklink
    > Faster subsequent page-loads by
    prefetching in-viewport links during
    idle time
    Speculative prefetch links with-in
    viewport using following APIs.
    ● Intersection Observer
    ● Prefetch (Resource Hints)
    ● requestIdleCallback()
    ● Network Information API.
    quicklink({
    ignores: [
    /\/api\/?/,
    uri => uri.includes('.zip'),
    (uri, el) => el.hasAttribute('noprefetch')
    ]
    });

    View full-size slide

  16. Nuxt v2.4 supports prefetching links in viewport
    > Nuxt.js will automagically
    prefetch the code-splitted pages
    linked with when visible
    in the viewport by default. This
    hugely improves the end user
    performances, inspired by
    quicklink.

    View full-size slide

  17. AMP is the best example for Prefetch/Prerender
    AMP prefetch/prerender some resources to achieve instant loading
    ● Prefetch resources
    ○ from Google AMP Cache hosted on Google
    ● Prerender documents
    ○ AMP’s prerender differs from
    ■ Why AMP HTML does not take full advantage of the preload scanner

    View full-size slide

  18. AMP’s URL is a long-standing problem..

    View full-size slide

  19. Web Packaging will solve the AMP’s URL problem
    Web Packaging consists of...
    ● Signed HTTP Exchanges: Signs request/response including URL with
    private keys and creates .sxg file
    ● Bundled HTTP Exchanges: Bundles subresources in response
    ● Loading Signed Exchanges: Loads signed .sxg file and displays the
    original URL instead of distributed URL

    View full-size slide

  20. Off The Main Thread

    View full-size slide

  21. More rich,
    More heavy.
    Web Page’s payload is increasing continuously

    View full-size slide

  22. Main Thread is busy
    ● Loading (almost described by Critical Rendering Path)
    ○ Fetch HTML
    ○ Parse HTML and construct DOM
    ○ Fetch sub-resources including CSS
    ○ Parse CSS and construct CSSOM
    ○ Eval heavy JavaScript (especially in recent web app)
    ○ etc...
    ● Runtime
    ○ Interact to user operations
    ○ Fetch data and render async
    ○ etc...

    View full-size slide

  23. Performance metrics are changing
    1. Focused to Server Response (old SSR)
    ○ load event
    ○ DOMContentLoaded event
    2. Focused to First View (CSR a.k.a SPA)
    ○ Speed Index
    ○ First Paint, First Contentful Paint, First Meaningful Paint
    ○ Async smooth page transition
    3. Focusing to interactivity <= now
    ○ First CPU Idle (Time to interactive)
    ○ Responsibility on Runtime

    View full-size slide

  24. https://dev.to/addyosmani/web-page-usability-matters-3aok

    View full-size slide

  25. DOM manipulation is heavy
    ● Virtual DOM was born
    ○ to solve rendering performance
    ○ The Inner Working Of Virtual DOM
    ○ View library has implemented it such as React, Vue.js, Angular, Preact
    ● Virtual DOM achieve effective rendering, but...
    ○ Diff algorithm is also heavy
    ○ Can we use DOM in Worker?
    ● Split DOM manipulation
    ○ React Suspense provides async render with Promise
    ○ Vue.js mutation will use requestIdleCallback()

    View full-size slide

  26. Off The Main Thread (inner browser)
    ● Parse and compile scripts in V8
    ● HTMLParser Redesign
    ● Will Worklets work on Worker thread?

    View full-size slide

  27. Off The Main Thread (web page land)
    ● ampproject/worker-dom: DOM API implementation in Worker
    ○ using MutationRecord and postMessage
    ○ Browser-native Worker DOM is…?
    ● OffscreenCanvas: Canvas in Worker
    ○ Draw canvas on Worker Context
    ● Concurrent JavaScript idea by WebKit

    View full-size slide

  28. https://threejs.org/examples/webgl_worker_offscreencanvas.html

    View full-size slide

  29. More easier postMessage() !!!

    View full-size slide

  30. postMessage() interface override
    We could only pass string messages
    to postMessage(), but new interface
    is added.
    postMessage(
    // primitives, object, File, Blob, etc...
    message,
    // targetOrigin, transfer
    options
    );
    postMessage(
    // string
    message,
    // targetOrigin
    targetOrigin,
    // transfer
    transfer
    );

    View full-size slide

  31. JavaScript "blöcks" proposal
    We could only pass string messages
    to postMessage(), but new interface
    is added.
    const result = await worker{|
    const res = await fetch("people.json");
    const json = await res.json();
    return json[2].firstName;
    |};

    View full-size slide

  32. GoogleChromeLabs/comlink
    > Comlink removes the mental
    barrier of thinking about
    postMessage and hides the fact
    that you are working with workers.
    // main.js
    const MyClass = Comlink.proxy(new
    Worker("worker.js"));
    // `instance` is an instance of `MyClass` that
    lives in the worker!
    const instance = await new MyClass();
    // logs “myValue = 42”
    await instance.logSomething();

    View full-size slide

  33. Further prospects
    ● More adoptive loading
    ○ By using Resource Hints, Intersection Observer, lazyload attribute, etc
    ● More effective prefetch
    ○ Like quicklink, Nikkei
    ● Will View libraries use Worker?
    ○ To calculate Virtual DOM diffs in Worker Thread
    ○ To apply Virtual DOM patch from Worker Thread
    ● Pray for browser optimizations

    View full-size slide