Exploring Critical Rendering Path

Exploring Critical Rendering Path

This guide will not bring you a magic formula to optimize critical render path. When the subject is web performance: there's no magic formula. Analyze performance is careful and meticulous process, and it can bring different results based on various existing variables.

Ed35943d3199ea37b1b60c39615e8163?s=128

Raphael Amorim

October 08, 2016
Tweet

Transcript

  1. ~ Exploring Critical Rendering Path Why Performance Matters @raphamundi's

  2. Raphael Amorim This guy seems like a nice person, but

    he doesn’t. Seriously. He likes topics related to JavaScript, Python, Clojure, WebGL, Algorithms and sometimes force some git push.
 Working most part of his time in useless open source projects. Works in globo.com, loves to create useful tiny modules to daily use. @raphamundi
  3. We write the markup. . .
 
 Then a page

    comes out on the screen.
  4. But how does the browser rendering engine work?

  5. 1# Constructing the Object Model

  6. HTML markup is transformed into a Document Object Model (DOM)

  7. HTML markup is transformed into a Document Object Model (DOM)

    CSS markup is transformed into a CSS Object Model (CSSOM)
  8. HTML markup is transformed into a Document Object Model (DOM)

    CSS markup is transformed into a CSS Object Model (CSSOM) DOM and CSSOM are independent data structures
  9. HTML markup is transformed into a Document Object Model (DOM)

    CSS markup is transformed into a CSS Object Model (CSSOM) DOM and CSSOM are independent data structures Bytes ! characters ! tokens ! nodes ! object model
  10. <html> <head> <meta charset=“utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>The Astronaut</title> <!--

    Stylesheet --> <link href="style.css" rel="stylesheet"> </head> <body> <p>Neil Armstrong</p> <p><img src=“just-a-neil-picture.jpg”></p> </body> </html> How does the browser process this page?
  11. 3c68746d6c3ea20203c686561643ea202020203c6d65746120636861727365743d201c75746 62d38223ea202020203c6d657461206e616d653d2276696577706f72742220a20636f6e7465 6e743d2277696474683d6465766963652d77696474682c696e697469616c2d7363616c653d3 1223ea202020203c7469746c653e54686520417374726f6e6175743c2f7469746c653ea2020 20203c212d2d205374796c657368656574202d2d3e2020a202020203c6c696e6b2068726566 3d227374796c652e637373222072656c3d227374796c657368656574223ea20203c2f686561 643ea20203c626f64793ea202020203c703e4e65696c2041726d7374726f6e673c2f703ea20 2020203c703e3c696d67207372633d201c6a7573742d612d6e65696c2d706963747572652e6 a7067201d3e3c2f703ea20203c2f626f64793ea3c2f68746d6c3e <html><head>…</head>…</html>

    Conversion
  12. Tokenizing <html><head>…</head>…</html> StartTag: html StartTag: head EndTag: head EndTag: html

  13. Lexing StartTag: html StartTag: head EndTag: head EndTag: html html

    head *NodeType p body meta
  14. DOM Mount head p body meta html link “Neil Arm…”

    img
  15. While browser was mounting the DOM. It encountered a link

    tag in the head section referencing an external CSS
  16. Then the Browser make a request for this resource.

  17. We repeat the HTML process, but for CSS instead of

    HTML: Bytes ! characters ! tokens ! nodes ! CSSOM
  18. 2# Render-tree Construction

  19. The DOM and CSSOM trees are combined to form the

    render tree
  20. The DOM and CSSOM trees are combined to form the

    render tree Render tree contains only the nodes required to render the page
  21. The DOM and CSSOM trees are combined to form the

    render tree Render tree contains only the nodes required to render the page Layout computes the exact position and size of each object
  22. Captures all the visible DOM content on the page and

    all the CSSOM style information for each node
  23. head p body meta html link “Neil Arm…” img DOM

  24. p img body CSSOM color: black background: #FFF color: black

    *font-size: 14px *user agent styles *font-weight: normal padding: 10px
  25. img body Render Tree color: black background: #FFF color: black

    *font-size: 14px *user agent styles *font-weight: normal padding: 10px p “Neil Arm…”
  26. 3# Layout & Paint

  27. Layout 
 Calculate nodes exact position and size within the

    viewport of the device
  28. Then all of the relative measurements are converted to absolute

    pixels on the screen
  29. Captures the exact position and size of each element within

    the viewport <html> <head> <meta name="viewport" content="width=device-width,initial- scale=1"> <title>
 My application
 </title> </head> <body> <div style="width: 100%"> <div style="width: 50%">
 JavaScript Rocks!
 </div> </div> </body> </html>
  30. Captures the exact position and size of each element within

    the viewport <html> <head> <meta name="viewport" content="width=device-width,initial- scale=1"> <title>
 My application
 </title> </head> <body> <div style="width: 100%"> <div style="width: 50%">
 JavaScript Rocks!
 </div> </div> </body> </html> viewport size=device-width JavaScript Rocks!
  31. After know what nodes are visible, and get their computed

    styles and geometry, becomes Paint stage.
  32. Paint 
 Converts each node in the render tree to

    actual pixels on the screen
  33. None
  34. Time required to perform render tree construction, layout and paint

    varies based on the size of the document, the applied styles, and the device it is running on.
  35. rendering Document Object Model(DOM) CSS object model(CSSOM) Render Tree Layout

    & Paint In resume:
  36. "I want to reduce my 
 render time."

  37. Probably 
 you can’t reduce a specific element render time*

    [*] depends on case by case
  38. However you can prioritize the display of content that relates

    to the current user action
  39. Critical Rendering Path

  40. The goal of optimizing the critical rendering path is to

    allow the browser to paint the page as quickly as possible.
  41. None
  42. Optimizing which resources are loaded and in which order we

    can minimize the blank screen time.
  43. Let’s dive in a simple request. Considering a use of

    regular 3G, the network roundtrip (propagation latency) to the server will cost 100ms - 750kb/s ~ 250kb/s.
  44. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src="main.js"></script> </body> </html>
  45. None
  46. The HTML file took ~111ms to download

  47. Once the HTML content becomes available, the browser has to

    parse the bytes, convert them into tokens, and build the DOM tree
  48. After the DOMContentLoaded trigger, the browser starts to build the

    DOM tree
  49. 1# Note: 
 JavaScript wait til CSS files are downloaded

    and parsed
  50. 1# Note: 
 JavaScript wait til CSS files are downloaded

    and parsed Even with inline scripts?
  51. 1# Note: 
 JavaScript wait til CSS files are downloaded

    and parsed Even with inline scripts? Inline scripts force browsers to intends to know what that script does. It blocks the CSS parse if it's placed above link or style tags
  52. 2# Note: 
 Images doesn’t block the initial render of

    the page (including domContentLoaded event).
  53. When we talk about the critical rendering path we are

    typically talking about the HTML markup, CSS and JavaScript
  54. More critical content is related with above the fold, page-loaded

    and server-side rendered.
  55. Less critical content is related with below the fold, lazy-loaded

    and client-side rendered.
  56. How I improve it?

  57. Make critical assets as small as possible by minifying and

    compressing both the html and css (obfuscation process)
  58. Asynchronous strategies to unblock the parser

  59. Async keyword

  60. Specifies that the script will be executed asynchronously as soon

    as it is available 
 
 (only for external scripts)
  61. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js"></script> </body> </html>
  62. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js"></script> </body> </html>
  63. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js"></script> </body> </html> DOMContentLoaded: 1.73s
  64. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js” async></script> </body> </html>
  65. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js” async></script> </body> </html>
  66. <html> <head> <meta name="viewport" 
 content="width=device-width,initial-scale=1"> <title>Some Random Page</title> <link

    href="style.css" rel="stylesheet"> <script src="jquery.js"></script> </head> <body> <div><img src="polemic-photo.jpg"></div> <script src=“main.js"></script> </body> </html> DOMContentLoaded: 191ms
  67. Script Loaders or Defer all of JavaScript

  68. Script Loaders E.g: Requirejs, Yepnope.js, LABjs and Nautilus.js

  69. Pros: Specify which scripts will be loaded according to the

    interaction
  70. Pros: Specify which scripts will be loaded according to the

    interaction Better script dependencies management
  71. Who use it? The Guardian (best perf case) - Requirejs

    g1.globo.com - Nautilusjs
  72. Inline Critical CSS

  73. A good approach is to inline only the critical css,

    and downloading the remaining css async
  74. Concatenate and minify, always.

  75. github.com/filamentgroup/loadCSS

  76. Remove Unused CSS

  77. github.com/giakki/uncss

  78. Optimize Images

  79. github.com/imagemin/imagemin

  80. Inline Images

  81. Remove a request by inlining a base64 image

  82. Be Careful: Data URIs are slow on mobile devices!

  83. Load fonts asynchronously

  84. Load fonts asynchronous Use a fallback while fonts load "Unlimited"

    Cache Use fewer fonts, Avoid repaints
  85. npm i fontfaceonload

  86. npm i fontfaceonload FontFaceOnload("My Custom Font Family", { success: function()

    { document.documentElement.className.add(“my-custom-font-family”); } });
  87. Optimize HTTP

  88. Turn on keep-alive

  89. GZip all the text

  90. For god sake: Make less requests!

  91. Optimize TCP

  92. Increase initial TCP cwnd size

  93. Disable slow-start restart (SSR)

  94. For god sake: Make less requests!

  95. Measure your metrics

  96. developers.google.com/speed/pagespeed/insights

  97. developers.google.com/speed/pagespeed/insights

  98. webpagetest.org

  99. webpagetest.org

  100. Thank You @raphamundi

  101. https://developers.google.com/web/fundamentals/performance/ critical-rendering-path/constructing-the-object-model References: https://developers.google.com/web/fundamentals/ performance/critical-rendering-path https://developers.google.com/web/fundamentals/performance/ critical-rendering-path/render-tree-construction https://speakerdeck.com/bevacqua/ high-performance-in-the-critical-path