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

HTML Optimization for Web Performance

Shogo Sensui
November 16, 2019

HTML Optimization for Web Performance

2019年11月16日に開催された Frontend Conference Fukuoka 2019 https://eventon.jp/18416/ の「HTML Optimization for Web Performance」のセッション資料です。また、セッション内容を書き起こした解説記事はこちら https://tech.mercari.com/entry/2019/12/02/000000 です。

Shogo Sensui

November 16, 2019
Tweet

More Decks by Shogo Sensui

Other Decks in Technology

Transcript

  1. HTML Optimization for
    Web Perfomance
    Frontend Conference Fukuoka 2019
    Shogo SENSUI (@1000ch)

    View Slide

  2. Chromium Blog: Moving towards a faster web

    View Slide

  3. Shogo SENSUI (@1000ch)
    ● Software Engineer focusing on the
    web technology
    ● Engineering Manager and Tech
    Lead at Merpay, Inc.
    ● This is the second in Fukuoka. My
    first time was 2014.01.25

    View Slide

  4. Why HTML
    Optimization?

    View Slide

  5. HTML is the first step of rendering a page

    View Slide

  6. The origin of
    subresources
    Loading order affects rendering speed directly

    View Slide

  7. Independent of
    web page type
    Regardless of dynamic web application or not

    View Slide

  8. Easy to optimize
    relatively
    Mostly completing in HTML

    View Slide

  9. 3 steps for HTML Optimization
    1. Understanding Critical Rendering Path
    2. Measuring Performance Metrics
    3. Optimizing HTML

    View Slide

  10. Understanding
    Critical Rendering
    Path

    View Slide

  11. Browser Loading Process
    1. Download HTML
    a. Parse HTML to construct DOM
    2. Download subresources
    a. Parse CSS to construct CSSOM
    b. Parse and evaluate JavaScript
    synchronously
    c. Parse images, audios, videos, etc.
    3. Create Render Tree using DOM
    and CSSOM
    a. Wait for DOM and CSSOM
    b. Layout nodes
    c. Paint nodes
    Construct
    DOM Tree
    Construct
    CSSOM Tree
    Create
    Render Tree
    Layout & Paint
    Execute
    JavaScript

    View Slide

  12. 1st step. Load HTML
    ● Download HTML from requested
    URL
    ● Parse HTML to construct DOM tree
    ● HTML will be evaluated from the
    top



    Basic HTML structure









    View Slide

  13. 2nd step. Load subresources
    ● Download subresources specified
    in HTML elements

    ○ <br/>○ <img><br/>○ <iframe><br/>○ etc…<br/>● CSS will be downloaded and<br/>evaluated asynchronously<br/>● JavaScript will be downloaded and<br/>evaluated synchronously<br/>○ will affect DOM and CSSOM<br/><html><br/><head><br/><meta charset="utf-8"><br/><title>Basic HTML structure</title><br/><link rel="stylesheet" href="foo.css"><br/><link rel="stylesheet" href="bar.css"><br/></head><br/><body><br/><img src="hero.jpg"><br/><script src="app.js">

    View Slide

  14. 3rd step. Render pages
    ● Wait for DOM and CSSOM are
    completely parsed
    ● Create Render Tree using DOM and
    CSSOM
    ● Display page
    ○ Layout nodes
    ○ Paint nodes
    without CSSOM with CSSOM

    View Slide

  15. Measuring
    Performance
    Metrics

    View Slide

  16. Wait, Load and DOMContentLoaded events?
    ● They are not user-centralized performance metrics
    ● We want to score the real-user experience

    View Slide

  17. Which experience would you prefer?

    View Slide

  18. Time to Interactive Demo (Airbnb mobile web)

    View Slide

  19. User Centric Performance Metrics

    View Slide

  20. Speed Index
    ● Visual Progress Score of the page
    ● Introduced at WebPagetest
    ○ Speed Index - WebPagetest
    Documentation
    ○ Further information in Japanese: Speed
    IndexというWebパフォーマンスの指標
    ● Slightly difficult to understand and
    calculate. We need simpler metrics!

    View Slide

  21. First Paint and First Contentful Paint
    ● First Paint: When anything on the first
    view is visible to the users
    ● First Contentful Paint: When any
    content on the first view is visible to the
    users

    View Slide

  22. Largest Contentful Paint
    ● Timing when the biggest content
    on the first view was painted
    ● These elements are considered
    ○ , in ,
    ○ An element with a background image
    loaded via CSS url()
    ○ Block-level elements

    View Slide

  23. Long Tasks
    ● The process make the main thread
    busy
    ● Long Tasks will cause the UI to
    freeze
    ○ Delay time-to-interactive
    ○ Input latency

    View Slide

  24. Time to Interactive
    ● How long it takes a page to become
    fully interactive
    ● Use GoogleChromeLabs/tti-polyfill
    to measure
    ○ It requires Long Tasks API is supported

    View Slide

  25. PerformanceObserver API
    ● Enables you to measure the web
    application performance on the
    user’s device
    const po = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
    // `entry` is a PerformanceEntry instance.
    console.log(entry.entryType);
    console.log(entry.startTime);
    console.log(entry.duration);
    }
    });
    // Start observing the entry types you care
    about.
    po.observe({
    entryTypes: ['resource', 'paint']
    });

    View Slide

  26. To measure FP, FCP, LCP:
    const observer = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
    ga('send', 'event', {
    eventCategory: 'Performance Metrics',
    eventAction: entry.name,
    eventValue: entry.startTime + entry.duration,
    nonInteraction: true
    });
    }
    });
    // Start observing the entry types, FP, FCP, LCP.
    observer.observe({
    entryTypes: ['paint', 'largest-contentful-paint']
    });

    View Slide

  27. To measure LongTasks:
    const observer = new PerformanceObserver(list => {
    for (const entry of list.getEntries()) {
    ga('send', 'event', {
    eventCategory: 'Performance Metrics',
    eventAction: 'longtask',
    eventValue: Math.round(entry.startTime + entry.duration),
    eventLabel: JSON.stringify(entry.attribution),
    });
    }
    });
    // Start observing the entry types, Long Task.
    observer.observe({
    entryTypes: ['longtask']
    });

    View Slide

  28. Performance Audit Tools

    View Slide

  29. Lighthouse
    ● Automated auditing, performance
    metrics, and best practices for the web.
    ● Bundled on Chrome DevTools
    ● GoogleChrome/lighthouse to use from
    the command line
    ● GoogleChrome/lighthouse-ci to
    integrate with CI

    View Slide

  30. WebPageTest
    ● Measuring and analyzing the
    performance of web pages
    ● Open-sourced at GitHub.
    ● SpeedCurve - WebPageTest wrapper
    ● Calibre - WebPageTest wrapper
    ● The test result of shogosensui.com
    ● The lighthouse test result of
    shogosensui.com

    View Slide

  31. How to optimize
    HTML?

    View Slide

  32. All (sub-)resources
    should be minified

    View Slide

  33. Optimize CSS Loading
    1. Put in
    a. To prefer loading CSS and constructing CSSOM
    b. Putting multiple s is OK! Because browser will load them asynchronously
    2. Separate CSS files as possible
    a. Should NOT be concatenated

    View Slide

  34. Optimize JavaScript Loading
    1. Put at the end of
    a. To prefer constricting HTML
    b. To prefer loading subresources
    2. Add defer attribute to that loads 3rd party JavaScript<br/>a. To prefer rendering the current web page<br/>

    View Slide

  35. Basic HTML structure will be...



    Basic HTML structure









    View Slide

  36. Preload subresources
    ● Load subresources actively
    ● Specify preload attribute for

    ● Preload directive: as attribute to
    specify the kind of subresource
    ○ as=media: Audio, Video
    ○ as=script: Script file
    ○ as=style: CSS file
    ○ as=font: Font file
    ○ as=image: Image file
    ○ etc...
    as="media">



    View Slide

  37. Preload for module scripts
    ● Load module scripts actively
    ● Specify modulepreload attribute
    for
    ● Further information about
    modulepreload: ES Modulesを優先
    的にロードするmodulepreload





    View Slide

  38. Native lazy-loading for and
    ● loading attribute to defer the
    loading of off-screen images and
    iframes


    ● Don’t have to use
    IntersectionObserver and to
    observe scroll and resize
    events.

    loading="lazy">

    View Slide

  39. Priority Hints for subresources
    ● importance attribute to suggest
    the resource priority


    ○ <br/>○ <iframe><br/><!-- An image the browser assigns "High"<br/>priority, but we don't actually want that. --><br/><img src="in_viewport_but_not_important.svg"<br/>importance="low" alt="..."><br/><!-- We want to initiate an early fetch for a<br/>resource, but also deprioritize it --><br/><link rel="preload" href="/js/script.js"<br/>as="script" importance="low"><br/><script src="/js/app.js" defer<br/>importance="high">

    View Slide

  40. Resource Hints
    ● Load subresources speculatively
    ● DNS Prefetch
    ○ Resolves DNS
    ● Preconnect
    ○ Creates TCP connection
    ● Prefetch
    ○ Fetches resources
    ● Prefender
    ○ Renders HTML page


    crossorigin>
    as="document">


    View Slide

  41. quicklink
    ● Faster subsequent page-loads by
    prefetching in-viewport links during
    idle time

    View Slide

  42. Conclusion

    View Slide

  43. Conslusion
    1. Understanding Critical Rendering Path
    a. Browsers wait for DOM and CSSOM are parsed before rendering
    2. Measuring Web Performance Metrics
    a. Use WebPageTest and Lighthouse to audit the web page
    b. Audit the web page continuously
    3. Optimizing HTML
    a. For initial loading
    b. For runtime
    c. Minimizing payload is the premise for both

    View Slide

  44. Further information?
    ● 基礎知識と実践的なノウハウを体系的
    に解説し、Web パフォーマンスに関する
    本質的な理解を促します
    ● 詳しくは https://webperf.guide を御
    覧ください

    View Slide

  45. Thank for listening
    Ask me anything ❤ by @1000ch

    View Slide