Tuesday, July 12, 2011

Firefox Pipelined?

‹prev | My Chain | next›

Due to time constraints related to my impending deadline for SPDY Book, I need to move from exploring alternative protocols to SPDY to alternative approaches.

A major feature of SPDY is pipelining—using a single interweb tube for all communication. Non-pipelined HTTP requests block an HTTP tube until the server completes sending a response. Only once the entire response has been sent can a second HTTP request go out. As you can imagine, this is terribly inefficient. All major browsers get around this by opening not one, but 6 interweb tubes to a single web server. But even those tubes block waiting on responses, which means that, if you need more than 6 resources, something is going to block.

It turns out that HTTP/1.1 actually has pipelining built in—only you wouldn't know it based on browser support. Opera is rumored to support it in certain, unrealistic edge cases, but that is it. Except...

Firefox supports it through an about:config setting.

But first, I create a dummy pipeline.html that loads in 10 pipelineXX.png images:
<p><img src="pipeline01.png"/></p>
<p><img src="pipeline02.png"/></p>
<p><img src="pipeline03.png"/></p>
<p><img src="pipeline04.png"/></p>
<p><img src="pipeline05.png"/></p>
<p><img src="pipeline06.png"/></p>
<p><img src="pipeline07.png"/></p>
<p><img src="pipeline08.png"/></p>
<p><img src="pipeline09.png"/></p>
<p><img src="pipeline10.png"/></p>
The images themselves are on the large side:
➜  www  ls -lh pipeline*
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline01.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline02.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline03.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline04.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline05.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:06 pipeline06.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:07 pipeline07.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:07 pipeline08.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:07 pipeline09.png
-rw-r--r-- 1 root root 157K 2011-07-12 23:07 pipeline10.png
-rw-r--r-- 1 cstrom cstrom 351 2011-07-12 23:05 pipeline.html
To get a somewhat real-world feel for the interaction, I add a 50ms delay on my local network device:
➜  www  ping localhost
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_req=1 ttl=64 time=0.051 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_req=2 ttl=64 time=0.022 ms
^C
--- localhost.localdomain ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.022/0.036/0.051/0.015 ms
➜ www sudo tc qdisc add dev lo root netem delay 50ms
➜ www ping localhost
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_req=1 ttl=64 time=100 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_req=2 ttl=64 time=100 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_req=3 ttl=64 time=100 ms
^C
--- localhost.localdomain ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 100.164/100.197/100.226/0.025 ms
I load the page up in Firefox and capture all of the traffic in Wireshark. I save the filtered tcp.port == 80 traffic into a pcap which I analyze with tcptrace:
➜  not_pipelined git:(master) ✗ tcptrace -S -n -zx -zy  ../firefox_not_pipelined.pcap 
1 arg remaining, starting with '../firefox_not_pipelined.pcap'
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov 4, 2004

246 packets seen, 246 TCP packets traced
elapsed wallclock time: 0:00:00.024607, 9997 pkts/sec analyzed
trace file elapsed time: 0:00:17.608415
TCP connection info:
1: :0001:58463 - :0001:80 (a2b) 1> 1< (reset)
2: 127.0.0.1:54606 - 127.0.0.1:80 (c2d) 21> 23< (complete)
3: :0001:58465 - :0001:80 (e2f) 1> 1< (reset)
4: :0001:58466 - :0001:80 (g2h) 1> 1< (reset)
5: :0001:58467 - :0001:80 (i2j) 1> 1< (reset)
6: :0001:58468 - :0001:80 (k2l) 1> 1< (reset)
7: :0001:58469 - :0001:80 (m2n) 1> 1< (reset)
8: 127.0.0.1:54612 - 127.0.0.1:80 (o2p) 15> 14< (complete)
9: 127.0.0.1:54613 - 127.0.0.1:80 (q2r) 15> 15< (complete)
10: 127.0.0.1:54614 - 127.0.0.1:80 (s2t) 16> 21< (complete)
11: 127.0.0.1:54615 - 127.0.0.1:80 (u2v) 16> 21< (complete)
12: 127.0.0.1:54616 - 127.0.0.1:80 (w2x) 16> 21< (complete)
13: 127.0.0.1:54617 - 127.0.0.1:80 (y2z) 6> 4< (complete) (reset)
14: 127.0.0.1:54618 - 127.0.0.1:80 (aa2ab) 6> 4< (complete) (reset)
Perfect. I do not even need to look at the graphs to see that all 6 interweb tubes were in action here (tubes with more than 4 response packets).

To enable pipelining in Firefox, I enter about:config in the address bar:



The default pipelining settings are:



I enable pipelining and set the maximum number of requests to 8:



I believe that 8 is the recommended number of max-requests.

I clear the browser cache, an re-request the pipeline page. Looking at the output with tcptrace, I see no change:
➜  pipelined git:(master) ✗ tcptrace -S -n -zx -zy  ../firefox_pipelined.pcap    
1 arg remaining, starting with '../firefox_pipelined.pcap'
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov 4, 2004

223 packets seen, 223 TCP packets traced
elapsed wallclock time: 0:00:00.027996, 7965 pkts/sec analyzed
trace file elapsed time: 0:00:18.368731
TCP connection info:
1: :0001:47563 - :0001:80 (a2b) 1> 1< (reset)
2: 127.0.0.1:39393 - 127.0.0.1:80 (c2d) 32> 37< (complete)
3: :0001:47565 - :0001:80 (e2f) 1> 1< (reset)
4: :0001:47566 - :0001:80 (g2h) 1> 1< (reset)
5: :0001:47567 - :0001:80 (i2j) 1> 1< (reset)
6: :0001:47568 - :0001:80 (k2l) 1> 1< (reset)
7: :0001:47569 - :0001:80 (m2n) 1> 1< (reset)
8: 127.0.0.1:39399 - 127.0.0.1:80 (o2p) 13> 14< (complete)
9: 127.0.0.1:39400 - 127.0.0.1:80 (q2r) 13> 14< (complete)
10: 127.0.0.1:39401 - 127.0.0.1:80 (s2t) 13> 14< (complete)
11: 127.0.0.1:39402 - 127.0.0.1:80 (u2v) 13> 13< (complete)
12: 127.0.0.1:39403 - 127.0.0.1:80 (w2x) 13> 12< (complete)
13: 127.0.0.1:39404 - 127.0.0.1:80 (y2z) 6> 4< (complete) (reset)
Dang it. All 6 interweb tubes are still in use.

Checking it out in Wireshark, it really seems like nothing has changed. The browser still waits until it is done processing pipeline02.png before requesting pipeline07.png:



Hrm... I'm at a bit of a loss. Maybe Firefox 5's pipelined support is lacking or maybe I am just missing something. I'll see if I can figure out which is the case. Tomorrow.


Day #72

No comments:

Post a Comment