While building boomerang, we developed many interesting methods to measure network performance characteristics using JavaScript running in the browser. While the W3C's NavigationTiming API provides access to many performance metrics, there's far more you can get at with some creative tweaking and analysis of how the browser reacts to certain requests.
In this talk, I'll go into the details of how boomerang works to measure network throughput, latency, TCP connect time, DNS time and IPv6 connectivity. I'll also touch upon some of the other performance related browser APIs we use to gather useful information. I will NOT be covering the W3C Navigation Timing API since that's been covered by Alois Reitbauer in a previous Boston Web Perf talk.
Dev Dives: Streamline document processing with UiPath Studio Web
Abusing JavaScript to Measure Web Performance
1. • Philip Tellis
• .com
• philip@lognormal.com
• @bluesmoon
• geek paranoid speedfreak
• http://bluesmoon.info/
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 1
2. I <3 JavaScript
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 2
3. So much that I wore Mustache socks to my wedding
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 3
4. I’m also a Web Speedfreak
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 4
5. We measure real user website performance
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 5
6. This talk is (mostly) about how we abuse JavaScript to do it
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 6
7. Abusing JavaScript to Measure Web
Performance
Philip Tellis / philip@lognormal.com
Boston #WebPerf Meetup / 2012-07-24
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 7
8. First, a note about the code
Note that in the code that follows,
+ new Date
is equivalent to
new Date().getTime()
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 8
9. 1
Latency
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 9
10. 1 Blinking Lights
It takes about 16ms for light to get from SF to Boston
(24ms through fibre)
...
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 10
11. 1 Blinking Lights
It takes about 16ms for light to get from SF to Boston
(24ms through fibre)
Though it takes about 100ms to ping... why?
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 10
12. 1 HTTP
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 11
13. So to measure latency, we need to send 1 packet each way, and
time it
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 12
14. 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";
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 13
15. 1 Notes
• 1x1 gif is 35 bytes
• including HTTP headers, is smaller than a TCP packet
• Fires onload on all browsers
• 0 byte image fires onerror
• which is indistinguishable from network error
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 14
16. 2
TCP handshake
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 15
17. 2 ACK-ACK-ACK
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 16
18. 2 Connection: keep-alive
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 17
19. 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();
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 18
20. Notice that we’ve ignored DNS lookup time here... how would
you measure it?
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 19
21. Network Throughput
3
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 20
22. 3 Measuring Network Throughput
data_length
download_time
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 21
23. Should you fly a 747 or a 737?
• A 747 seats 400+ passengers
• A 737 seats about 150
• Both take about the same time to fly from SFO to BOS
• A 747 takes longer to load and unload
The best selling aircraft to date is the 737
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 22
24. 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;
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 23
25. 3 Measuring Network Throughput
If it were that simple, I wouldn’t be doing this talk.
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 24
26. 3 TCP Slow Start
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 25
27. 3 Measuring Network Throughput
So to make the best use of bandwidth, we need resources that fit
in a TCP window
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 26
28. 3 There is no single size that will tax all available networks
http://www.yuiblog.com/blog/2010/04/08/analyzing-bandwidth-and-latency/
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 27
29. 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++;
};
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 28
30. 3 Measuring Network Throughput
Slow network connection, meet really huge image
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 29
31. 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;
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 30
32. 3 Network Throughput in JavaScript – Take 3
if(i>0) {
image[i-1].end = +new Date;
clearTimeout(image[i-1].timer);
}
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 31
33. 3 Network Throughput in JavaScript – Take 3
if(i >= image.length
|| (i > 0 && image[i-1].expired)) {
done();
}
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 32
34. 3 Measuring Network Throughput
Are we done yet?
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 33
35. 3 Measuring Network Throughput
Are we done yet?
sure...
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 33
36. 3 Measuring Network Throughput
Except network throughput is different every time you test it
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 34
37. Statistics to the Rescue
flickr/sophistechate/4264466015/
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 35
38. 3 Measuring Network Throughput
The code for that is NOT gonna fit on a slide
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 36
39. But this is sort of what we see world-wide
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 37
40. And it’s different for different countries
This is India
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 38
41. 4 DNS
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 39
42. 4 Measuring DNS
time_with_dns − time_without_dns
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 40
43. 4 Measuring DNS in JavaScript
var t=[], dns, ip, hosts=[’http://hostname.com/’,
’http://ip.ad.dr.ess/’];
var ld = function() {
t.push(+new Date);
if(t.length > hosts.length)
done();
else {
var img = new Image;
img.onload = ld;
img.src=hosts[t.length-1] + "/1x1.gif";
}
};
var done = function() {
ip=t[2]-t[1];
dns=t[1]-t[0]-ip;
};
ld();
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 41
44. 4 Measuring DNS
• What if the IP changes?
• What if DNS is cached?
• What if you map DNS based on geo location?
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 42
45. 4 Wildcard DNS Entries
*.foo.com → IP address
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 43
46. 4 Measuring DNS in JavaScript – take 2
var base_url="http://*.foo.com/",
timers = {}, gen_url="";
function start() {
var random = Math.random().toString(36),
cache_bust = Math.random(),
img = new Image();
gen_url = base_url.replace(/*/, random);
img.onload = A_loaded;
timers.start = +new Date;
img.src = gen_url + "image-l.gif?t=" + cache_bust;
}
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 44
47. 4 Measuring DNS in JavaScript – take 2
function A_loaded() {
var cache_bust = Math.random(),
img = new Image();
img.onload = B_loaded;
timers.a_loaded = +new Date;
img.src = gen_url + "image-l.gif?t=" + cache_bust;
}
I’ll let you figure out B_loaded
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 45
48. 4 Measuring DNS
Full code in boomerang’s DNS plugin
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 46
49. 5 IPv6
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 47
50. 5 Measuring IPv6 support and latency
1 Try to load image from IPv6 host
• If timeout or error, then no IPv6 support
• If successful, then calculate latency and proceed
2 Try to load image from hostname that resolves only to IPv6
host
• If timeout or error, then DNS server doesn’t support IPv6
• If successful, calculate latency
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 48
51. 5 Measuring IPv6 support and latency
Full code in boomerang’s IPv6 plugin
Note, only run this if you know IPv6 is supported by the client
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 49
52. 6
Other Stuff
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 50
53. 6 Other Stuff We Measure
• NavTiming – navtiming.js
• navigation.connection.type – mobile.js
• window.performance.memory – memory.js
• Number of DOM nodes and byte size of HTML –
memory.js
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 51
54. And we try to do it fast
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 52
55. –
.done()
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 53
56. Code/References
• http://lognormal.github.com/boomerang/doc/
(BSD Licensed)
• www.lognormal.com
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 54
57. • Philip Tellis
• .com
• philip@lognormal.com
• @bluesmoon
• geek paranoid speedfreak
• http://bluesmoon.info/
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 55
58. Thank you
Ask me about a discount code
Boston #WebPerf Meetup / 2012-07-24 Abusing JavaScript to Measure Web Performance 56