Page load performance is largely important topic these days and virtually touches every web developer. In this post, I am going to show several page-load cases and describe how to properly read (analyze) data provided by the Net panel in Firebug.
Just to quickly summarize, the purpose of the Net panel is to intercept network communication between a web-page and the server and see what's going on under the hood. All created reports (logs) can be exported by NetExport extension (in HAR format) and there is also an online viewer allowing to preview all exported logs in graphical form.
This post is also translated into Japanese.
Example 1: Simple Page Load
Let's start with a simple page load.
There are two requests in this log. Elapsed time to get the page document was 16 milliseconds and the load event (the red line) was fired in 58ms. Consequently a 5ms XHR was executed. The total elapsed time (from beginning of the first request till the end of the second/last request) is 408 ms. DOMContentLoaded event (the blue line) was fired in 46 ms.
See a tooltip with detailed timing info.
Example 2: Connection Limit
Each browser has a limit for number of simultaneous connections to the same server when downloading a page. If the limit is reached, other resources have to wait in an internal browser queue till a connection is released. See the following two page logs that show how the situation looks like if there is 8 different images on the page (each image takes ~2.5 sec to download).
#1 Cuzillion (max connections == 6)
- The limit is 6 in Firefox 3.6 by default, so the first six images start downloading immediately after the page document is available (i.e. DOMContentLoaded event fired in Firefox).
- The other two images have to wait till there is a free connection (yes, that's the light-brown phase).
- Existing connections are reused, see there is no green (connection) phase for the last two requests.
#2 Cuzillion (max connections == 2)
- The other log shows what happens if the limit is set to 2 (network.http.max-persistent-connections-per-server == 2). Notice that every image in this test takes ~2.3 sec to load.
This example comes from Cuzillion (made by Steve Souders).
Example 3: Pipelining
This example uses the same page as the previous example (#2) and compares what happens if pipelining is on.
You can see that using pipelining (network.http.pipelining == true) doesn't help in this case - the page actually takes more time to fire the load event. The first six images are again loaded using six different connection, but 7th and 8th image is downloaded using shared connection. It's not clear which connection is actually shared (there are no APIs that would allow Firebug to know), but it's clear that both last two images were downloaded using the same connection, which increased the total time.
Example 4: Persistent Connections
This test case shows impact of HTTP Connection header. This header is used to tell the server whether an existing connection should be closed or kept alive and wait for further requests (which is usually good optimization). See following log that depicts how it looks if the header is set to Keep-Alive (default in HTTP/1.1) or Close.
There are four requests to load the entire test-page. One for the initial page document and three executed by the page. The Connection header is manipulated for the three requests (file1.php, file2.php, file3.php).
#1 Test page (Connection: Keep-Alive)
- The first page log shows that only one connection was created to download entire page. All three requests executed by the page reused the initial connection. You can see that there is only one green phase (+ a little bit for DNS lookup).
#2 Test page (Connection: close)
- In the second log, there is a connection created to get the initial page document and this one is reused by the file1.php request. But as it was mentioned, these three requests use Connection: close request header and so, after file1.php, file2.php and file3.php the connection is closed and new one is must be created if there is a further request.
Example 5: Inline Scripts Block
It's not a secret that inline scripts block download of a page. Let's see following log that depicts how this looks from the network activity perspective.
- Note the gap between 3td and 4th request. This is caused by a 5 sec inline script execution.
- The second page log is showing what happens if the inline script is moved to the bottom of the page. Note that we have got a shorter loading time.
This example comes from Cuzillion.
Example 6: Redirects
This example shows how redirects looks like when reported by the Net panel.
#1 Final Page (one redirect)
- The redirect is done by the server that has to figure out what is the target file. If the last / was added, the additional redirect wouldn't be necessary since the server knows that the URL points to a directory.
#2 Final Page (infinite redirection)
- This scenario shows what happens if the redirect links to itself. In Firefox, the maximum number of redirection is limited to 20 (see network.http.redirection-limit preference)