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

More Decks by Shogo Sensui

Other Decks in Technology


  1. 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);
  2. 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 });
  3. Browser native lazy-loading lazyload attribute to load if display with-in

    viewport. • will be enabled on... ◦ <img> ◦ <iframe> • Lazyload images and iframes by bengreenstein · Pull Request #3752 · whatwg/html. • Blink LazyLoad Design Docs (public) <img src="https://example.com/image.jpg" lazyload="on"> <iframe src="https://google.com" lazyload="on"> </iframe>
  4. Priority Hints for resource loading importance attribute to indicate resource

    priority. • will be enabled on... ◦ <img> ◦ <iframe> ◦ <script> ◦ <link> ◦ fetch() • Priority Hints Draft Community Group Report 18 October 2018 <img src="https://example.com/image.jpg" importance="high"> <iframe src="https://example.com" importance="low"> </iframe> <script> fetch('https://google.com', { importance: 'high' }); </script>
  5. Resource Hints Resource Hints provides speculative loading which consists of...

    • DNS Prefetch: host • Preconnect: host • Prefetch: resources • Prerender: specified page <link rel="dns-prefetch" href="//example.com/"> <link rel="preconnect" href="//example.com/"> <link rel="prefetch" as="image" href="https://example.com/high-priority.jpg"> <link rel="prerender" href="https://example.com/">
  6. 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 <link rel="preload" href="https://example.com/high-priority.jpg"> <link rel="preload" href="https://example.com/high-priority.js">
  7. 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') ] });
  8. Nuxt v2.4 supports prefetching links in viewport > Nuxt.js will

    automagically prefetch the code-splitted pages linked with <nuxt-link> when visible in the viewport by default. This hugely improves the end user performances, inspired by quicklink.
  9. 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 <link rel=preload> ▪ Why AMP HTML does not take full advantage of the preload scanner
  10. 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
  11. 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...
  12. 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
  13. 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()
  14. Off The Main Thread (inner browser) • Parse and compile

    scripts in V8 • HTMLParser Redesign • Will Worklets work on Worker thread?
  15. 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
  16. 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 );
  17. 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; |};
  18. 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();
  19. 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