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
• Parse HTML to construct DOM tree • HTML will be evaluated from the top <html> <head> <meta charset="utf-8"> <title>Basic HTML structure</title> <link rel="stylesheet" href="foo.css"> <link rel="stylesheet" href="bar.css"> </head> <body> <img src="hero.jpg"> <script src="app.js"></script> <script defer src="3rd-party.js"></script> </body> </html>
Introduced at WebPagetest ◦ Speed Index - WebPagetest Documentation ◦ Further information in Japanese: Speed IndexというWebパフォーマンスの指標 • Slightly difficult to understand and calculate. We need simpler metrics!
the first view was painted • These elements are considered ◦ <img>, <image> in <svg>, <video> ◦ An element with a background image loaded via CSS url() ◦ Block-level elements
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'] });
• Open-sourced at GitHub. • SpeedCurve - WebPageTest wrapper • Calibre - WebPageTest wrapper • The test result of shogosensui.com • The lighthouse test result of shogosensui.com
To prefer loading CSS and constructing CSSOM b. Putting multiple <link>s is OK! Because browser will load them asynchronously 2. Separate CSS files as possible a. Should NOT be concatenated
<body> a. To prefer constricting HTML b. To prefer loading subresources 2. Add defer attribute to <script> that loads 3rd party JavaScript a. To prefer rendering the current web page
Specify modulepreload attribute for <link> • Further information about modulepreload: ES Modulesを優先 的にロードするmodulepreload <head> <link rel="modulepreload" href="app.mjs"> </head> <!-- ... --> <script type="module" src="app.mjs"></script>
defer the loading of off-screen images and iframes ◦ <img> ◦ <iframe> • Don’t have to use IntersectionObserver and to observe scroll and resize events. <img src="image.png" loading="lazy" alt="…"> <iframe src="https://example.com" loading="lazy"></iframe>
resource priority ◦ <link> ◦ <img> ◦ <script> ◦ <iframe> <!-- An image the browser assigns "High" priority, but we don't actually want that. --> <img src="in_viewport_but_not_important.svg" importance="low" alt="..."> <!-- We want to initiate an early fetch for a resource, but also deprioritize it --> <link rel="preload" href="/js/script.js" as="script" importance="low"> <script src="/js/app.js" defer importance="high"></script>
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