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

Boomerang: Measuring Web Performance With JavaScript

Boomerang: Measuring Web Performance With JavaScript

Quick talk about how boomerang works, and some of the fun stuff we've found with it.

Philip Tellis

October 30, 2014
Tweet

More Decks by Philip Tellis

Other Decks in Programming

Transcript

  1. Boomerang: Measuring Web Performance with JavaScript Philip Tellis / [email protected]

    Stockholm #WebPerf Meetup / 2014-10-30 Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 1
  2. • Philip Tellis • @bluesmoon • [email protected] • SOASTA •

    boomerang Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 2
  3. I’m a Speedfreak (the network kind) Stockholm #WebPerf Meetup /

    2014-10-30 Boomerang: Measuring Web Performance with JavaScript 4
  4. SOASTA mPulse & boomerang We measure real user website performance

    Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 5
  5. This talk is (mostly) about how we abuse JavaScript to

    do it Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 6
  6. First, a note about the code Note that in the

    code that follows, + new Date is equivalent to new Date().getTime() Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 7
  7. Sort in ascending order of signal latency • Electrons through

    copper • Light through fibre • Pulsars • Station Wagons • Smoke Signals Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 9
  8. Sort in ascending order of signal latency 1 Pulsars (light

    through vacuum) 2 Smoke Signals (light through air) 3 Electrons through copper / Light through fibre 4 Station Wagons (possibly highest bandwidth) Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 10
  9. 1 Blinking Lights It takes about 16ms for light to

    get from SF to NYC (24ms through fibre) . . . Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 11
  10. 1 Blinking Lights It takes about 16ms for light to

    get from SF to NYC (24ms through fibre) Though it takes about 100ms to ping... why? Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 11
  11. So to measure latency, we need to send 1 packet

    each way, and time it Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 13
  12. 1 Network latency in JavaScript var ts, rtt, img =

    new Image; img.onload=function() { rtt=(+new Date - ts) }; ts = +new Date; img.src="/1x1.gif"; Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 14
  13. 1 Notes • 1x1 gif is 35 bytes • including

    HTTP headers, this is smaller than a TCP packet • Fires onload on all browsers • 0 byte image fires onerror • which is indistinguishable from network error Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 15
  14. 2 Network latency & TCP handshake in JavaScript var t=[],

    tcp, rtt; var ld = function() { t.push(+new Date); if(t.length > 2) // run 2 times done(); else { var img = new Image; img.onload = ld; img.src="/1x1.gif?" + Math.random() + ’=’ + new Date; } }; var done = function() { rtt=t[2]-t[1]; tcp=t[1]-t[0]-rtt; }; ld(); Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 19
  15. Notice that we’ve ignored DNS lookup time here... how would

    you measure it? Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 20
  16. 3 Measuring Network Throughput data_length download_time Stockholm #WebPerf Meetup /

    2014-10-30 Boomerang: Measuring Web Performance with JavaScript 22
  17. 3 Network Throughput in JavaScript // Assume global object //

    image={ url: ..., size: ... } var ts, rtt, bw, img = new Image; img.onload=function() { rtt=(+new Date - ts); bw = image.size*1000/rtt; // rtt is in ms }; ts = +new Date; img.src=image.url; Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 23
  18. 3 Measuring Network Throughput If it were that simple, I

    wouldn’t be doing this talk. Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 24
  19. 3 TCP Slow Start Stockholm #WebPerf Meetup / 2014-10-30 Boomerang:

    Measuring Web Performance with JavaScript 25
  20. 3 Measuring Network Throughput So to make the best use

    of bandwidth, we need resources that fit in a TCP window Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 26
  21. 3 There is no single size that will tax all

    available networks http://www.yuiblog.com/blog/2010/04/08/analyzing-bandwidth-and-latency/ Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 27
  22. 3 Network Throughput in JavaScript – Take 2 // image

    object is now an array of multiple images var i=0; var ld = function() { if(i>0) image[i-1].end = +new Date; if(i >= image.length) done(); else { var img = new Image; img.onload = ld; image[i].start = +new Date; img.src=image[i].url; } i++; }; Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 28
  23. 3 Measuring Network Throughput Slow network connection, meet really huge

    image Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 29
  24. 3 Network Throughput in JavaScript – Take 3 var img

    = new Image; img.onload = ld; image[i].start = +new Date; image[i].timer = setTimeout(function() { image[i].expired=true }, image[i].timeout); img.src=image[i].url; Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 30
  25. 3 Network Throughput in JavaScript – Take 3 if(i>0) {

    image[i-1].end = +new Date; clearTimeout(image[i-1].timer); } Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 31
  26. 3 Network Throughput in JavaScript – Take 3 if(i >=

    image.length || (i > 0 && image[i-1].expired)) { done(); } Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 32
  27. 3 Measuring Network Throughput Are we done yet? Stockholm #WebPerf

    Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 33
  28. 3 Measuring Network Throughput Are we done yet? sure... Stockholm

    #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 33
  29. 3 Measuring Network Throughput Except network throughput is different every

    time you test it Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 34
  30. 3 Measuring Network Throughput The code for that is NOT

    gonna fit on a slide Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 35
  31. 3 Bandwidth is different around the world Stockholm #WebPerf Meetup

    / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 36
  32. 4 Page Load Time Stockholm #WebPerf Meetup / 2014-10-30 Boomerang:

    Measuring Web Performance with JavaScript 37
  33. 4 Page Load Time is Simple 1 Get a timestamp

    when user initiates page request 2 Get a timestamp when page completes loading 3 Pass it through advanced Mathematics engine: t_done = t_end − t_start Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 38
  34. 4 Page Load Time This is easy with Navigation Timing

    enabled browsers (Except for all the versions with bugs) Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 39
  35. 4 Page Load Time But what about legacy browsers? Stockholm

    #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 40
  36. 4 Page Load Time End time is measured in the

    onload or pageshow events Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 41
  37. 4 Page Load Time Start time is measured in the

    onbeforeunload event Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 42
  38. But what if the user opens a link in a

    new tab? Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 43
  39. 4 Page Load Time Start time is measured in the

    onbeforeunload or onclick or onsubmit events Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 44
  40. But not if the click happened on a FLASH object

    Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 45
  41. 4 Page Load Time We also measure the onunload or

    pagehide events... This gives us first byte time Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 46
  42. 4 Page Load Time We cannot attach events for first

    page loads, but with enough data we can estimate using statistical analysis Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 47
  43. But... it’s not over yet <link rel="prerender"> Stockholm #WebPerf Meetup

    / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 48
  44. 4 Page Load Time A pre-rendered page’s onload event can

    fire before the user even clicks on the link Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 49
  45. boomerang takes care of this by measuring "click to visible",

    "request to load", "request to visible", and "load to visible" Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 50
  46. Using the Resource Timing API, get timing information for all

    resources on the page Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 52
  47. Yes, this results in very large beacons, so we use

    POST, and we will soon merge in a patch to compress the data Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 53
  48. And some hackery to capture XHR requests Create a wrapper

    around window.XMLHttpRequest and set timers on all its events Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 54
  49. 6 Other Stuff We Measure • NavTiming, SPDY, FirstPaint –

    navtiming.js • navigation.connection.* – mobile.js • window.performance.memory – memory.js – Chrome 22+ reporting now. • Number of DOM nodes, images, scripts and byte size of HTML – memory.js Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 57
  50. And we try to do it fast Stockholm #WebPerf Meetup

    / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 58
  51. 7 Keep it Clean Stockholm #WebPerf Meetup / 2014-10-30 Boomerang:

    Measuring Web Performance with JavaScript 59
  52. We recently started capturing all JavaScript errors that happen inside

    boomerang, and beaconing them back Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 60
  53. So now we can find bugs as soon as it

    affects an end user Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 61
  54. We found that Firefox 31 started throwing exceptions on direct

    dereferences of window.performance inside anonymous iframes https://bugzilla.mozilla.org/show_bug.cgi?id=1045096 Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 62
  55. We tried to use if (window.hasOwnProperty("performance")) but that doesn’t work

    in IE10 because window is a host object Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 63
  56. You have to use if ("performance" in window) which JSLint

    doesn’t like... Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 64
  57. You have to use if ("performance" in window) which JSLint

    doesn’t like... But no one likes JSLint so it’s okay Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 64
  58. And speaking of IE, did you know that "TypeError: Permission

    Denied" is localized, so you have to capture every single language to detect it? Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 65
  59. On a more interesting note, IE11 running in compatibility mode

    can make it seem like IE7 has magically received Navigation Timing support Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 66
  60. We found that Chrome 38 started reporting 0 for firstPaintTime,

    and that helped the Chrome team realise, "This code (in Chrome)... we don’t know how it ever worked" https://code.google.com/p/chromium/issues/detail?id=422913 Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 67
  61. We also found a much older Chrome bug where cached

    content was reported as having a negative load time in Resource Timing Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 68
  62. We found that Mobile Safari’s NavigationTiming implementation had weird bugs,

    but could not find a good pattern Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 69
  63. And Android 2.3’s browser has a document.createEvent method that exists,

    but always throws, so capability detection doesn’t work nicely Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 70
  64. As we found that users have different bugs too ;)

    Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 71
  65. ni! din tur nu Stockholm #WebPerf Meetup / 2014-10-30 Boomerang:

    Measuring Web Performance with JavaScript 72
  66. • Philip Tellis • @bluesmoon • [email protected] • www.SOASTA.com •

    boomerang • LogNormal Blog Stockholm #WebPerf Meetup / 2014-10-30 Boomerang: Measuring Web Performance with JavaScript 76