VelocityConf: Rendering Performance Case Studies

VelocityConf: Rendering Performance Case Studies

Jank-free rendering performance has been shown to positively affect user engagement and user experience in a number large sites, yet remains an area many developers are unaware of how to diagnose or optimize for.

To highlight how widespread rendering is a performance issue, we’re going to walk through case studies of Flickr, Pinterest, Google+, Twitter Bootstrap and more.

Learn about common paint issues in modern sites, caused by fixed-backgrounds, heavy CSS, doing too much in your onscroll handlers, compositing and more. We’ll also look at changes Pinterest made to get up to a 40% improvement in rendering times.

By the end if this session you’ll be equipped with the knowledge to use the performance profiling tools in Chrome DevTools to find and fix rendering issues in your own sites.

To learn more about rendering performance, checkout jankfree.org.

Also, anything on Chrome rendering by Paul Lewis, Paul Irish and Jake Archibald is generally pretty reliable :)

96270e4c3e5e9806cf7245475c00b275?s=128

Addy Osmani

November 13, 2013
Tweet

Transcript

  1. Rendering Performance Case Studies Gone in 60 frames per second

  2. Addy Osmani - @addyosmani Chrome Developer Relations Google

  3. Network Compute Render 3 Pillars Of Performance

  4. Our agenda for today... 1. DOM to pixels on the

    screen 2. Rendering performance tooling 3. Real-world case studies Flickr Bootstrap Pitchfork Pinterest Google+
  5. #perfmatters

  6. What we build for the web is evolving.

  7. None
  8. Users ❤ snappy experiences.

  9. Silky smooth scrolling Buttery animation Great performance everywhere. High performance

    web apps have:
  10. None
  11. Speed must be treated as an essential design feature.

  12. The fastest web page is..

  13. None
  14. Everything we add increases the work the browser has to

    do to put pixels on the screen
  15. None
  16. Mobile web performance goals 1. Connectivity - Show above the

    fold content in < 1s - Serve critical path CSS in first 14KB 2. Max of 200ms server response time 3. 60fps scrolling, 60fps transitions 4. Speed index under 1000* * average time visual parts of the page display per WebPageTest
  17. Today we’ll focus on this. 1. Connectivity - Show above

    the fold content in < 1s - Serve critical path CSS in first 14KB 2. Max of 200ms server response time 3. 60fps scrolling, 60fps transitions 4. Speed index under 1000
  18. Rendering performance impacts user experience.

  19. "In an A/B test, we slowed down scrolling from 60fps

    down to 30fps. Engagement collapsed" ~ Shane O'Sullivan * in their native app, fluctuating between 30 to 45fps. * Consistent 30fps performed second best
  20. None
  21. "We tested pre-fetching JS in search results, which caused jank

    in our pages. All business metrics got worse" ~ Jonathan Klein
  22. Response rates matter.

  23. See the flow of how Chrome renders pages

  24. DevTools Timeline

  25. None
  26. drag here to filter record/stop 30fps = 33ms per frame,

    60fps = 16ms per frame
  27. what do these records mean?

  28. Let’s dive in!

  29. Parse HTML

  30. GET / HTTP /1.1 host: www.example.com Make a request

  31. <!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>MA RESPONSE</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/main.css"> </head> <body> <section> <h1>HTML wizaaaaard</h1> <p>I am teh HTML masterz.</p> </section> </body> </html> Get a response
  32. <!DOCTYPE html> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title MA RESPONSE</title>

    <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/main.css"> </head> HTML wizaaaaard</h1> I am teh HTML masterz.</p> </section> </body> </html> Parse HTML Get a response <html> <head> <title> <link> <body> <section> <h1> <p>
  33. <html> <body> <script> <section> <h1> <img> <p> <head> <title> <link>

    Get a response
  34. Recalculate Style

  35. DOM CSS + Recalculate Style Styling the DOM

  36. Render tree Styling the DOM

  37. <html> <body> <section> <h1> <img> <p> Styling the DOM

  38. <html> <body> <section> <h1> <img> Styling the DOM section p

    { display: none; }
  39. <html> <body> <section> <h1> <img> Styling the DOM section h1:after

    { content: "<333 pseudo elemz" } <h1:after>
  40. Layout

  41. html, body { marg: 0; width: 300px; height: 700px; background:

    white; color: white; } body { background: #888; } section { display: block; margin-top:30%; padding-top:60px; width:100%; background:#444; } section h1:after{ content: '<3 pseudo'; height: 40px; margin-top: 10px; display: block; } img { margin: 30px; border-radius: 4px; border: 3px solid white; box-shadow: 0 2px 2px rgba(0,0,0,3); } Layout Laying out the document
  42. Rasterizer Raster

  43. drawPoints drawOval drawRectangle drawRoundedRect drawPath drawBitmap drawText drawLine drawArc clear

    translate save restore clipPath moveTo lineTo Rasterizer
  44. Paint

  45. Rasterizer

  46. Instant replay

  47. Image Resize

  48. Image Decode + Resize Draw Bitmap

  49. Move Elements

  50. Composite Layers

  51. Composite Layers Layers

  52. Layer creation criteria

  53. To the screen

  54. To the screen CPU GPU Composite Layers

  55. All together, you should expect to see..

  56. width margin border left/top box-shadow border-radius background outline transform opacity

  57. DOM to pixels on the screen Recalc styles Calc styles

    that apply to elements Layout Generate geometry for each element Paint Fill pixels for each element into layers (Paint) Composite layers Draw layers out to the screen
  58. What about frame rate?

  59. Frame rate Rate at which a device produces consecutive images

    to the screen
  60. To see what’s impacting rendering, look at FPS

  61. A consistent frame rate is our ideal

  62. Why target 60fps?

  63. Match the refresh rate of the devices you are targeting.

  64. Jank Disruption in consistent frame rate that manifests itself visually

  65. None
  66. < 15fps Your users will perceive jerkiness and jank

  67. None
  68. 30fps Smooth as long as it’s a constant 30fps

  69. 60fps Smooth animations and transitions with no stutter

  70. Frame budget At 60fps, you have 16.7ms budget for Logic

    processing Compute processing Rendering
  71. Frame budget It’s more like 8-10ms budget because - Browser,

    JS engine, renderer processes - Margin for slower devices like mobile.
  72. What causes jank?

  73. Properties that trigger layout (reflow) Correct as of November, 2013.

  74. Correct as of November, 2013. Reading offsetTop in a loop

  75. Correct as of November, 2013. Cache that read outside loop

    or don’t use offsetTop
  76. Drop-shadows Blurs Linear-gradients Fixed background images Heavy styles can cause

    jank* *Correct as of November, 2013. Likely to change!
  77. CSS Styles that affect paint, layout

  78. None
  79. Recalculate style triggered when styles are computed or changed. Heavy

    use of JS to rearrange the page (e.g onscroll) is bad
  80. Heavy onscroll() handlers Doing shit inside of scroll is terrible

  81. None
  82. Scrolling Correct as of November, 2013. Watch out for: Unnecessary

    paints: position:fixed overflow:scroll hover effects touch listeners Long paints: Complex CSS Image decodes Large empty layers
  83. Long image decodes and resizes Remember to pre-scale your images!

  84. Should be pre-scaled. Instead using overly high-res sources with more

    costly resizes.
  85. DOM elements with measurably high paint cost Measure what elements

    might be slowing you down.
  86. Too much inside your event handlers

  87. None
  88. Heavy animation or data processing Where possible rely on rAF

    or Web Workers
  89. Position transform: translate(npx, npx); Scale transform: scale(n); Rotation transform: rotate(ndeg);

    Opacity opacity: 0....1; 4 things a browser can animate cheaply Move all your visual effects to these things. Transition at your own risk. translateZ(0) or translate3D() may be required
  90. None
  91. None
  92. Hardware acceleration GPU compositing

  93. Old-skool painting All your elements get painted into one big

    bitmap
  94. Old-skool painting What if we had separate bitmaps, or "layers"?

    Click.
  95. Old-skool painting What if we had separate bitmaps, or "layers"?

    Click.
  96. Layers & Compositing Hardware compositing uses the GPU to help

    build the page Elements are broken out to a bunch of layers Those layers are uploaded to the GPU as textures The GPU composites those textures together
  97. More: DevTools Settings

  98. Useful Settings red shaded rectangles around repainted regions orange borders

    around composited layers yellow border around touch handler listeners
  99. Layer promotion hacks -webkit-transform: translateZ(0); -webkit-transform: translate3d(0,0,0); 1 -webkit-transform: translate3d(0,0,0)

    Use with caution!! Blink/Webkit iOS -webkit-perspective: 1000; -webkit-backface-visibility: hidden; 1 -webkit-transform: translate3d(0,0,0)
  100. None
  101. New! Layers panel Visualize elements promoted to a layer with

    the new layers panel (experimental)
  102. None
  103. Layout thrashing

  104. When JS violently writes, then reads from the DOM repeatedly

    causing reflow
  105. None
  106. The slow way while (i--) { var greenBlockWidth = sizer.offsetWidth;

    ps[i].style.width = greenBlockWidth + 'px'; }
  107. The right way var greenBlockWidth = sizer.offsetWidth; while (i--) {

    ps[i].style.width = greenBlockWidth + 'px'; }
  108. None
  109. Writes to the DOM invalidate layout Browser wants to wait

    until the end of the current frame to reflow.
  110. Querying geometric values before a frame completes, forces early layout.

    Forced synchronous layout
  111. None
  112. It’s a performance killer.

  113. FastDOM Batches DOM reads/writes on the next frame using rAF

    for scheduling.
  114. None
  115. None
  116. ~ Paul Irish

  117. Case studies

  118. Don’t guess it, test it!

  119. Case study: Flickr with thanks to Scott Schiller @ Flickr

  120. Web seeing a trend of vertical parallax effects.

  121. inception-explained.com

  122. None
  123. flickr.com (optimized)

  124. None
  125. But scroll used to be significantly slower.

  126. For each Y pixels of vertical axis scrolling, move an

    absolutely positioned image in the same direction.
  127. For each Y pixels of vertical axis scrolling, move an

    absolutely positioned image in the same direction. window.onscroll() backgroundPosition marginTop or el
  128. window.onscroll = function(e) { var parallax = document.getElementById('parallax-background'); parallax.style.marginTop =

    (window.scrollY/2) + 'px'; } Minimal parallax example
  129. Neither marginTop or backgroundPosition alone perform well. They don’t use

    hardware compositing.
  130. Demo (slow)

  131. None
  132. Timeline view

  133. Have the GPU help with accelerating compositing of the expensive

    parts Trick
  134. Elements can be promoted to a layer using translateZ() or

    translate3D() Avoid expensive paints Reminder
  135. window.onscroll = function(e) { var parallax = document.getElementById('parallax-background'); parallax.style.transform =

    'translate3d(0px,' + (window.scrollY/2) + 'px, 0px)'; } Optimized parallax example
  136. Promoting the element to a new layer

  137. Demo (fast)

  138. None
  139. Timeline view

  140. Twitter Bootstrap 3

  141. None
  142. None
  143. background- image: linear- gradient( to bottom, #ffffff, #e6e6e6);

  144. 100% faster paint time.

  145. BS3 much more viable for sites that need to work

    well on under-powered mobile and tablet devices
  146. BS3 much more viable for sites that need to work

    well on under-powered mobile and tablet devices
  147. Pitchfork

  148. Why is scrolling in this Daft Punk site so slow?

  149. None
  150. Image shipped (high-res) Size actually needed High image resize cost

  151. Pre-scale images where possible to avoid resize cost.

  152. None
  153. Live case study: Pinterest

  154. Post-optimization Great scrolling performance

  155. None
  156. Pre-optimization

  157. None
  158. None
  159. Sub-optimal position:fixed use causing unnecessarily large repaints Slow scrolling due

    to excessive use of styles (currently) expensive to paint Doing a lot during hover on scroll Main issues
  160. Case study: Google+ with thanks to Steve Kobes @ Google+

  161. Perf went from 12fps to 60fps

  162. None
  163. Jank bustin’

  164. Simplified G+ layout

  165. Simplified G+ layout position:fixed position:fixed

  166. Problem.

  167. A position:fixed element causes a repaint when moved within its

    layer.
  168. To avoid the repaint, put the element in its own

    layer.
  169. Simplified G+ layout translateZ(0) translateZ(0)

  170. Caveats of translateZ - more layers = more time compositing

    layers - text anti-aliasing requires an opaque background within the layer - triggers Safari positioning bugs inside iframes
  171. Too many layers? Sometimes a style creates compositing layers for

    all positioned descendants.
  172. Another problem.

  173. G+ styles for card-flip animation

  174. -webkit-backface-visibility: hidden

  175. Causes every descendent element to get its own layer

  176. Remove it, apply it through JS for duration of the

    card animation The Fix!
  177. one last problem

  178. Forced synchronous layouts Modifying the DOM invalidates layout. element.innerHTML =

    '...'; // Layout invalidated.
  179. Measuring the DOM depends on the layout If previously invalidated,

    this forces synchronous layout (since execution cannot continue until the correct value is obtained). alert(element.offsetHeight); // Layout forced.
  180. G+ reduced synchronous layouts cards.forEach(function(card){ appendHTML(card); measure(card); }); write read

    write read.. cards.forEach(function(card){ appendHTML(card); }); cards.forEach(function(card){ measure(card); }); write write read read.. They reduced them from O(n) to O(1) by refactoring a loop
  181. Forced Synchronous Layouts Timeline shows where your code is causing

    synchronous layouts Remember to scroll down for the second stack trace.
  182. Bonus optimization Animate with translate instead of left/top

  183. Paint performance tooling in other browsers

  184. There’s now lots of tooling to improve the responsiveness of

    your UIs. BROWSER SUPPORT CATS HAVE BEEN LISTENING
  185. IE F12 Developer Tools UI Responsiveness Tool shows frame rate

  186. Firefox DevTools: Paint flashing Highlight areas being painted

  187. WebKit Nightlies: Paint counts of layers

  188. WebKit Nightlies: Reasons for compositing

  189. Audience check

  190. None
  191. In summary...

  192. Frame rate matters and can impact engagement

  193. Don’t over-do layout. Do reads before writes.

  194. Be mindful of paint costs. Use the DevTools.

  195. Check your perf on desktop and mobile.

  196. Mobile-first performance benchmarking Test on low-end hardware. Get 60fps there.

  197. DevTools Remote Debugging

  198. If you’re building something, set performance objectives up front.

  199. Hit those objectives, add tests to measure and then never

    regress!
  200. If all goes well, this could be you!

  201. To learn more checkout jankfree.org

  202. Use tools. not rules.

  203. Thank you. @addyosmani +AddyOsmani