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 Slide

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

    View Slide

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

    View Slide

  4. Lazy Loading

    View 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 Slide

  6. WebKit shipped!!!

    View 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 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 Slide

  9. ⚡ Prefetch

    View 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 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 Slide

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

    View 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 Slide

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

    View 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 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 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 Slide

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

    View 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 Slide

  20. Off The Main Thread

    View Slide

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

    View 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 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 Slide

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

    View 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 Slide

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

    View 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 Slide

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

    View Slide

  29. More easier postMessage() !!!

    View 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 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 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 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 Slide