Friday, July 15, 2011

Firefox Pipelining is Silly

‹prev | My Chain | next›

After a couple of days investigation, I realized that my experiment with pipelining in Firefox was actually perfectly crafted. Perfectly crafted for failure, that is.

My pipeline.html page referenced 10 images, each around 150 kb in size. I had hypothesized that, after loading a start page, Firefox would attempt to load pipeline.html and all 10 images in the same pipeline. I was wrong. After loading pipeline.html, Firefox downloaded 6 of the images in 6 different interweb tubes (all modern browser have 6 interweb tubes to load resources in parallel). When the first of those images completed, Firefox then proceeded to download the next 4 images over a single tube.

Given that those next 4 images, pipelined or not, were 600 kb in total, it took nearly a full second to download them over a single tube. Ultimately, pipelining was a significant loser over just using the normal 6 tubes.

I am unsure why Firefox choose this strategy. It already knows that the server can handle HTTP/1.1, why not try pipelining right away? Maybe it wants to ensure that it loads enough data to appear responsive before attempting something out of the norm?

If that is the case, then once Firefox knows that the server supports HTTP pipelining, surely it will use pipelining for all subsequent requests. Using a single tube will allow its TCP/IP congestion window (CWND) to quickly grow to a healthy maximum between the client and server since it would not have to compete with 5 other tubes. Large CWND means more data for each round trip, which means fewer round trips, which means speed (this is why SPDY uses a single tube for everything).

To test this hypothesis, I use a third page after pipeline.html. On this third page, I use smaller images (~10 kb each) to better represent normal web pages. Clicking on this page after pipeline.html should re-use the HTTP tube that ended up pipelining the last four images in pipeline.html.

After restarting Firefox and clearing my cache, I access the start page, the pipeline page and my new page (a hello world from SPDY Book). Checking things out with Wireshark, I find that the same four images from pipeline.html are still pipelined:

But, when I access the next page, Firefox goes back to its old ways. Specifically, it tosses all CWND goodness from the previously pipelined tube and makes 6 different connections on 6 different tubes:

When the first of those images are downloaded, Firefox again starts pipelining. The remaining 5 images from the final page are then loaded on the same tube.

That seems like a terrible strategy. First create 6 tubes that compete with each other for full access to the bandwidth between client and server, which does not allow any to quickly increase the CWND. Then pick one tube and ramp it up with a burst of data. With that tube properly warmed, then ditch it to use the other 5 tubes again, some of which may not be warmed enough to transfer data very fast. What's worse is that, because those 6 tubes are again competing with each other, the CWND may decrease because there is congestion going on. And finally, switch back to pipelining now that the 6 tubes are just getting warmed up.

Maybe there is some reason to this seeming madness. If so, I will try to dig it up tomorrow. For now, back to putting that hello world page to good use—in SPDY Book!

Day #74

No comments:

Post a Comment