$30 off During Our Annual Pro Sale. View Details »

DevTools: State Of The Union 2015

DevTools: State Of The Union 2015

As the complexity of the web apps you build keeps moving, so do the Chrome DevTools. In DevTools State of the Union, Addy will give you the latest update on your favourite companion; exploring new features like paint profiling, animation inspection and updates to the JavaScript editing workflow with V8.

* Note: these are annotated slides aimed at making it easy to read and follow along with what I said during the session. The video will cover demos and the original unannotated deck.

Session: http://jqueryuk.com/2015/talks.php#addyosmani
Video: http://jqueryuk.com/2015/videos.php?s=devtools-state-of-the-union

Note: This deck and all content included are licensed under a CC0 license. Use whatever you need!

Addy Osmani

March 17, 2015
Tweet

More Decks by Addy Osmani

Other Decks in Technology

Transcript

  1. State Of The Union
    DevTools
    jQuery UK, 2015
    @addyosmani

    View Slide

  2. Network Improvements
    DevTools: State Of The Union March, 2015.
    Agenda
    Performance Case Study Whirlwind tour of new features

    View Slide

  3. DevTools: State Of The Union
    Performance Matters
    Challenges: Network, Paint, Layout, Recalc Styles
    Our users have better
    experiences when the
    web is fast.
    This is why speed is one
    of the major factors in
    ranking.

    View Slide

  4. We think pages should be rendered in under one second and
    hit 60fps for animations and transitions.
    To help frame how you should think about performance this
    year, here’s a new model that’s useful to consider...

    View Slide

  5. DevTools: State Of The Union Image credits: GestureWorks, Timothy Miller, Last Call Media Inc.
    100ms
    User interacts with app
    UI causing state
    change.
    Response
    2015 Web Performance Model
    6ms
    Animations and
    transitions, either
    autonomous or user-
    initiated.
    Animation
    50ms
    App UI is in a stable
    state, awaiting user
    interaction.
    Idle
    1000ms
    Time from app start to
    appearing ready for
    use.
    Load

    View Slide

  6. DevTools: State Of The Union Learn more in “Making a silky smooth web” by Paul Lewis
    time
    finger
    down
    finger up
    do idle/cleanup in
    50ms chunks in
    case finger down
    happens again
    animation
    Max:
    100ms
    loading
    1000ms
    60fps. max
    6ms chunks
    Read more: http://bit.ly/blink-midnight-train
    2015 Web Performance Budget

    View Slide

  7. Today we’ll look at how the DevTools have evolved to better
    visualise slowness in your pages.

    View Slide

  8. New in Network Panel
    1.
    What’s new? Chrome 42+

    View Slide

  9. WebPageTest vs DevTools in Chrome 41
    Chrome 41 had only two times:
    receive time & “everything else”.
    WebPageTest (top) color coded
    timing information. So much better.

    View Slide

  10. What if this could be improved?

    View Slide

  11. Update! Load timing is now more visible.
    New: Waterfall bars now show where time was spent!

    View Slide

  12. DevTools: State Of The Union
    Hover over bars for more detailed timing breakdown
    Load event fired
    DOMContentLoaded
    event fired

    View Slide

  13. DevTools: State Of The Union
    Details pane now docks to bottom when in Dock-to-right mode.

    View Slide

  14. DevTools: State Of The Union
    Right-click to open Network files in Sources

    View Slide

  15. DevTools: State Of The Union
    See what initiated a request. Now supports iframes (Other)

    View Slide

  16. DevTools: State Of The Union
    Network protocol column (visualise use of HTTP/2, SPDY etc)

    View Slide

  17. DevTools: State Of The Union
    Filter by method: GET/POST

    View Slide

  18. DevTools: State Of The Union
    Filter by domain:

    View Slide

  19. DevTools: State Of The Union
    Filter by mime-type:

    View Slide

  20. DevTools: State Of The Union
    Negative text filters! Exclude matches from results:

    View Slide

  21. DevTools: State Of The Union
    Preserve Log - navigations can keep adding to current waterfall

    View Slide

  22. DevTools: State Of The Union
    Tip: Toggle columns displayed in the Network Panel

    View Slide

  23. DevTools: State Of The Union
    Replay XHR can now replay with credentials, cookies & all.
    XMLHttpRequest.
    withCredentials is a boolean that
    indicates whether or not cross-
    site Access-Control requests
    should be made using credentials
    such as cookies or authorization
    headers.
    The default is false.

    View Slide

  24. DevTools: State Of The Union
    Emulate spotty network connections in Device Mode!

    View Slide

  25. DevTools: State Of The Union
    Pro-tip: Click/hold Reload to empty cache & do a hard reload
    Normal Reload performs a
    standard refresh but tries to use
    the cache where possible.
    Hard Reload re-fetches
    everything.
    Empty Cache and Hard Reload
    completely empties local cache
    before re-fetching everything.

    View Slide

  26. Performance Case Study
    2.
    Wikipedia

    View Slide

  27. Lately, the DevTools team have been diving in to performance
    audits of popular sites. Wikipedia was one of the first.

    View Slide

  28. View Slide

  29. Specifically, they were looking at the performance of the
    Wikimedia visual editor. This one..

    View Slide

  30. View Slide

  31. It turns out using jQuery for toggling visibility was their major
    performance bottleneck. This totally surprised them.
    Off the back of this, Paul shared a recommendation..

    View Slide

  32. View Slide

  33. The advice was really saying, don’t use hide(), toggle(), :
    visible, or :hidden because under the hood they’ll call
    getComputedStyle() before setting any inline styles.
    This forces costly style recalculations.
    Before we continue, Paul wanted to say..

    View Slide

  34. Tools Not Rules
    Paul’s sorry
    DevTools
    “Sorry everyone!”

    View Slide

  35. He kinda broke one rule of performance profiling - Tools not
    Rules :)
    So, let’s try to justify his recommendations by digging into our
    tools.

    View Slide

  36. Measurement time!
    Let’s start by enabling two new options - Causes & JS Profiler

    View Slide

  37. View Slide

  38. JS Sampling
    JS Profiler integrates JavaScript Sampling in Timeline!
    Get charts of JS execution time, call stacks visualised next to paint & layout. This is a game changer.

    View Slide

  39. The new Causes option can be enabled in the DevTools Timeline.
    Causes explains what’s happening in Timeline.
    Useful for seeing what caused layout invalidations, recalc styles & forced layout.

    View Slide

  40. Timeline for Wikipedia Editor on first load took ~20 seconds!

    View Slide

  41. Let’s break this into ~ 3 Acts of work.

    View Slide

  42. Act 1

    View Slide

  43. Wikipedia has an edit notice system. They wrote a
    jQuery plugin ($.getVisibleText) to determine if a
    notice was visually empty. They then filter out
    notices based on this check.
    Editor Notices
    Edit Notice System on Wikipedia.com

    View Slide

  44. This causes some hefty recalc styles because the plugin
    relies on the :hidden selector behind the scenes...

    View Slide

  45. Heavy ~120ms
    Recalc style

    View Slide

  46. :hidden use in their
    jQuery plugin
    Jump to source from
    Timeline records
    Source for their $.getVisibleText plugin
    Pretty print optimised
    source so we can read it

    View Slide

  47. Problem
    Too much magic in :hidden & the other visibility utilities.
    :hidden isn’t part of the CSS spec. In addition, jQuery can’t
    take advantage of perf boosts from using qSA().

    View Slide

  48. Let’s see how Wikipedia are using their plugin in practice.

    View Slide

  49. View Slide

  50. For jQuery’s :hidden, an element is assumed to be hidden if it
    or any of its parents consumes no space in the document.
    CSS visibility isn’t really taken into account.
    Notice the use of offsetWidth/offsetHeight. Reading these
    properties can cause costly layout (reflow) in the browser.

    View Slide

  51. https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js

    View Slide

  52. Advice
    Don’t trust :hidden. Use your own logic to compute
    visibility.
    element.hidden is just one option.

    View Slide

  53. Let’s look at another really expensive block and the source of
    the parent function behind it..

    View Slide

  54. View Slide

  55. View Slide

  56. Looks straight-forward, right?
    We assume .children() requires getting childNodes and
    running matchesSelector() on each of them. But, there’s
    actually a lot more being done here.
    Let’s go back to our Timeline.

    View Slide

  57. View Slide

  58. The blue parseHTML bits at the bottom of those flames is
    Sizzle’s code for handling qSA() regex. It’s weird that we’re
    hitting it every single time.
    Digging deeper, this is actually due to a bug in Sizzle where
    setDocument is called and expensive processing is performed
    each time jQuery is used on a document that isn’t window.
    document.
    The jQuery team are exploring this at the time of publishing.

    View Slide

  59. Wikipedia ended up dropping their use of jQuery children():

    View Slide

  60. Advice
    Be careful with .children().
    Also just use querySelectorAll() & DOM methods where
    you can.

    View Slide

  61. Another thing we noticed was the editor had a particularly
    gnarly DOM size. It was pretty huge across the board.

    View Slide

  62. Large DOM Node Count DOM size is an issue here
    > 14,000 Elements! Crazy.

    View Slide

  63. Advice
    Kill any superfluous spans/divs you don't absolutely
    need.
    When you have serious recalc style issues, try keeping
    your DOM element count under 1000 for more
    predictable performance.

    View Slide

  64. Act 2

    View Slide

  65. Next we’re going to jump into the JavaScript CPU profiler.

    View Slide

  66. View Slide

  67. View Slide

  68. This one method oo.copy() is doing a LOT of JS work. They
    actually used jQuery.html() quite a lot behind the scenes.
    Wikipedia are working on eliminating all their .html() calls, but
    we can look at just one instance of them fixing this up..

    View Slide

  69. View Slide

  70. Advice
    Avoid $(elem).html(str) for DOM insertion, use
    innerHTML or DOM methods. They’re massively
    faster.
    Batch. Don’t stamp out HTML into DOM a ton of
    times. Just use innerHTML once.

    View Slide

  71. Let’s look at our CPU profile some more.

    View Slide

  72. View Slide

  73. Crazy. createSurface() calls are taking a HUGE amount of
    time. 1/3rd of our editor initialisation is spent here.
    We’ve also got some pretty hefty recalc styles for the method,
    taking > 100ms.

    View Slide

  74. View Slide

  75. If you look at the source, they’re using the .css() method to set
    visibility and remove hidden classes.

    View Slide

  76. View Slide

  77. This leads us to our largest bottleneck in the entire editor...

    View Slide

  78. Our largest bottleneck
    curCSS!

    View Slide

  79. It’s got the heaviest self-time stack of JS during editor load,
    coming from one jQuery curCSS call of ~319ms.
    Almost all of this work is coming from .hide() and .show().
    In fact, this is littered throughout our traces.

    View Slide

  80. 100ms recalc styles. Lots of $(elem).hide(), $(elem).css(prop)

    View Slide

  81. If curCSS sounds familiar, it’s because you’ll see it when
    digging into the source for jQuery’s .css() method.
    If a computed value exists for an element, it’ll use curCSS to
    go and set your styles.

    View Slide

  82. View Slide

  83. Wikipedia were very surprised when they learned .hide() was
    their biggest bottleneck.
    Their usage of it was pretty atypical for jQuery code.

    View Slide

  84. Their usage

    View Slide

  85. Unfortunately, there’s a lot more magic going on here.
    jQuery is calling getComputedStyle() before setting any inline
    styles for visibility. That isn’t a good call & is a good way to
    cause layout.
    They do it to support two edge-cases: display:none & inline
    styles that you might want to use with .show()/.hide().
    jQuery are exploring optimisations for these issues at the time of publishing.

    View Slide

  86. Advice
    Don’t use .hide() for high performance visibility
    toggling.
    Use el.hidden = true/false or add/remove/toggle
    class.

    View Slide

  87. Act 3

    View Slide

  88. 140ms recalcs on .show/.hide()
    DevTools: State Of The Union
    More visibility toggling slowness
    Lots more jQuery.html(str) 300ms recalcs in $.fn.animate()

    View Slide

  89. Overall advice
    If you think it’s slow, profile it.
    I’m not saying don’t use jQuery. I’m saying understand how
    your abstractions work. Know where your bottlenecks are.

    View Slide

  90. Summary
    jQuery is not your friend for high-performance visibility toggling
    Track visibility on your own rather than using :hidden, :visible, .show(), .hide()
    Avoid $(elem).html(str) for DOM insertion. Use innerHTML or DOM methods.
    jQuery does a lot of magic around querySelectorAll. Use it on its own if possible.
    Keep your DOM size low for predictable performance
    Try to touch the DOM less. Batch changes. Mutations just make things harder.
    DevTools: State Of The Union Wikipedia Case Study

    View Slide

  91. DevTools: State Of The Union
    SFGate.com
    ..and It’s not just Wikipedia!
    For more case studies, keep an eye on Paul Irish’s blog!

    View Slide

  92. Grab bag of tips
    3.
    Chrome 42+

    View Slide

  93. DevTools: State Of The Union
    New Eye Dropper in the Element panel Color Picker!

    View Slide

  94. DevTools: State Of The Union
    New! We now highlight DOM updates. Visualise what parts of
    a node have changed with ease:

    View Slide

  95. DevTools: State Of The Union
    New Cubic Bezier Function Editor!
    With preconfigured bezier functions!

    View Slide

  96. DevTools: State Of The Union
    Timeline: Check “Paint” for graphics layer insights

    View Slide

  97. DevTools: State Of The Union
    Timeline: New Layers panel for advanced profiling

    View Slide

  98. DevTools: State Of The Union
    3D view for visualising composited layer stacking

    View Slide

  99. DevTools: State Of The Union
    Inspect individual layers with ease

    View Slide

  100. DevTools: State Of The Union
    ● What Layers were created?
    ● What were the reasons for compositing?
    ● Why does an element have those
    dimensions?
    ● See memory estimates
    Layers are those portions of a page uploaded
    to the GPU for compositing.
    Layers: dive into reasons for compositing, memory, slowness.

    View Slide

  101. DevTools: State Of The Union
    New Paint Profiler! See draw calls executed to draw pages

    View Slide

  102. DevTools: State Of The Union
    New! Web Animation playback: Playback and speed controls
    for controlling animation. Slow motion. Pause.

    View Slide

  103. DevTools: State Of The Union
    Animation Inspector (coming soon!)
    In Experiments at the time of publishing

    View Slide

  104. DevTools: State Of The Union
    Console: Inspecting an object? Right-click functions to jump to
    their definition in your source code

    View Slide

  105. DevTools: State Of The Union
    New editing features in the Sources Panel!
    Multiple cursor support
    Autocompletion
    Column selection
    Ctrl + M to jump between matching brackets

    View Slide

  106. DevTools: State Of The Union
    V8 Proactive Compilation - spot errors in your source earlier

    View Slide

  107. DevTools: State Of The Union
    Save Console Messages to a Text file

    View Slide

  108. DevTools: State Of The Union
    New! Goodbye “undefined is not a function”
    Undefined method names now
    inform us which object they were
    called on. We’ve got callsite
    awareness!
    Rather than just “undefined” in
    this example we get foo.bar.

    View Slide

  109. DevTools: State Of The Union
    Stepping through apps that use a Framework is hard. Usually
    end up stepping into the Framework :(

    View Slide

  110. DevTools: State Of The Union
    JavaScript Framework Blackboxing fixes that. Right click on a
    Framework/Library script to blackbox..and..

    View Slide

  111. DevTools: State Of The Union
    BOOM. When stepping in/out/over, DevTools now bypasses
    the library code! Just debug your own sources.
    ● Exceptions thrown from library code
    will not pause
    ● Stepping into/out/over bypasses the
    library code
    ● Event listener breakpoints don't break
    in library code
    ● The debugger will not pause on any
    breakpoints set in library code.

    View Slide

  112. DevTools: State Of The Union
    Pre-configure frameworks to blackbox from Settings

    View Slide

  113. DevTools: State Of The Union
    New Promises Inspector (coming soon!)
    In Experiments at the time of publishing

    View Slide

  114. DevTools: State Of The Union
    Filter by Pending, Fulfilled, Rejected Promises with ease

    View Slide

  115. DevTools: State Of The Union
    Click-to-jump to where a Promise was defined:

    View Slide

  116. DevTools: State Of The Union
    Promises Inspector also supports Async call stacks!
    Enable Async call stack traces

    View Slide

  117. We hope you’ve found this preview of what’s new in the
    DevTools useful. There’s a lot more to come!

    View Slide

  118. devtools.chrome.com
    See our latest

    View Slide

  119. See Making a silky smooth web by
    Paul Lewis at SmashingConf
    Want a deep dive on the
    2015 Performance Model?

    View Slide

  120. See DevTools for designers
    & talk to us about your ideas
    Designer?

    View Slide

  121. console.thanks()
    +AddyOsmani
    @addyosmani

    View Slide