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

000000000

Addy Osmani
February 15, 2011
85

 000000000

0000000000000

Don't share. Just a draft. Thx.

Addy Osmani

February 15, 2011
Tweet

Transcript

  1. 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
  2. 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
  3. "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
  4. "We tested pre-fetching JS in search results, which caused jank

    in our pages. All business metrics got worse" ~ Jonathan Klein
  5. <!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
  6. <!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>
  7. <html> <body> <section> <h1> <img> Styling the DOM section h1:after

    { content: "<333 pseudo elemz" } <h1:after>
  8. 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 <html> <body> <section> <h1> <h1:after> <img> Laying out the document
  9. 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
  10. Frame budget At 60fps, you have 16.7ms budget for Logic

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

    JS engine, renderer processes - Margin for slower devices like mobile.
  12. Recalculate style triggered when styles are computed or changed. Heavy

    use of JS to rearrange the page (e.g onscroll) is bad
  13. 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
  14. 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/3d may be required*
  15. 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
  16. Useful Settings red shaded rectangles around repainted regions orange borders

    around composited layers yellow border around touch handler listeners
  17. 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)
  18. The slow way while (i--) { var greenBlockWidth = sizer.offsetWidth;

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

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

    until the end of the current frame to reflow.
  21. For each Y pixels of vertical axis scrolling, move an

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

    absolutely positioned image in the same direction. window.onscroll() backgroundPosition marginTop or el
  23. Elements can be promoted to a layer using translateZ() or

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

    'translate3d(0px,' + (window.scrollY/2) + 'px, 0px)'; } Optimized parallax example
  25. BS3 much more viable for sites that need to work

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

    well on under-powered mobile and tablet devices
  27. 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
  28. 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.
  29. 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
  30. Forced Synchronous Layouts Timeline shows where your code is causing

    synchronous layouts Remember to scroll down for the second stack trace.
  31. There’s now lots of tooling to improve the responsiveness of

    your UIs. BROWSER SUPPORT CATS HAVE BEEN LISTENING