Andy Davies

Independent Web Performance Consultant

Three Ways of Checking Rel=preconnect Resource Hints Are Working

After explaining the preconnect Resource Hint to clients or workshop attendees, I often get asked “How can I check it’s working?”

Here’s a few ways of checking:

Safari Inspector

Safari’s Inspector displays a console message when it successfully preconnects to another origin. I find this the fastest and simplest way of checking whether preconnects are working:

  • Navigate to a page that uses preconnect e.g. https://andydavies.github.io/test-rel-preconnect/tests/preconnect.html

  • Open Safari Inspector

  • Switch to Console Tab, ensure the option for All messages is selected (top right)

  • If the preconnect worked then there should be a message, in this case Successfully connected to “https://www.wikipedia.org/”

Console Tab in Safari Inspector showing "Successfully connected to https://www.wikipedia.org/

WebPageTest

For other browsers WebPageTest is next on my list of choices:

  • Enter the page to be tested as the URL e.g. https://andydavies.github.io/test-rel-preconnect/tests/preconnect.html

  • Select the location / browser you want use for the test

  • Hit Submit (and wait for the result)

Chrome

In the waterfall below, request #3 has two distinct parts – the section with DNS resolution, TCP connection and TLS negotiation, and the section with the request and response.

This is preconnect at work, Chrome has made the connection to Wikipedia before it’s discovered it needs to fetch the image from Wikipedia.

WebPageTest waterfall illustrating Chrome preconnecting to https://www.wikipedia.org/

iOS Safari

The iOS Safari waterfall is slightly different as WebPageTest can’t gather the same level of detail from iOS Safari as it can from Chrome.

In this waterfall the whole DNS resolution, TCP connection and TLS negotiation segment are missing from request #3, and that’s our clue that preconnect worked in this case.

WebPageTest waterfall illustrating iOS Safari preconnecting to https://www.wikipedia.org/

Chrome’s NetLog

If you’re not on a Mac and the pages you want to check aren’t publicly accessible (or the WebPageTest wait is too long) then Chrome’s netlog is the third option - it’s slightly more involved and so I tend to use this option the least.

  • Open a new Chrome Window (I tend to use Canary for this)

  • Enter chrome://net-export in the URL bar, Click Start Logging to Disk, and select the name / location for the netlog to be saved (mine defaults to chrome-net-export-log.json in Downloads)

  • Open a new Tab, and load the page you’re interested in e.g. https://andydavies.github.io/test-rel-preconnect/tests/preconnect.html

  • Switch back to the chrome://net-export tab, and click Stop Logging

  • Navigate to https://netlog-viewer.appspot.com/

  • Choose Import, and select the file you specified above. Once the netlog has loaded and you’ll see a page with a some metadata describing the capture

  • Switch to the Events view and you should see a list of events similar to the one below

Chrome Netlog viewer showing events

  • Scroll down, until you’ll see a Source Type of HTTP_STREAM_JOB_CONTROLLER for the origin you were expecting the Chrome to preconnect to.

In my experience there’s often a block of four events with the source types HTTP_STREAM_JOB_CONTROLLER, HTTP_STREAM_JOB, SSL_CONNECT_JOB (if HTTPS), and SOCKET.

Chrome Netlog viewer showing events

  • Selecting the event with source type of HTTP_STREAM_JOB_CONTROLLER brings up a longer description in the right hand panel, it should be similar to the one below

Line #5 is the signal that it was the preconnect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
243: HTTP_STREAM_JOB_CONTROLLER
https://www.wikipedia.org/
Start Time: 2019-04-17 14:59:20.511
t=3523 [st=0] +HTTP_STREAM_JOB_CONTROLLER  [dt=1]
               --> is_preconnect = true
               --> url = "https://www.wikipedia.org/"
t=3523 [st=0]   +PROXY_RESOLUTION_SERVICE  [dt=0]
t=3523 [st=0]      PROXY_RESOLUTION_SERVICE_RESOLVED_PROXY_LIST
                   --> pac_string = "DIRECT"
t=3523 [st=0]   -PROXY_RESOLUTION_SERVICE
t=3523 [st=0]    HTTP_STREAM_JOB_CONTROLLER_PROXY_SERVER_RESOLVED
                 --> proxy_server = "DIRECT"
t=3523 [st=0]    HTTP_STREAM_REQUEST_STARTED_JOB
                --> source_dependency = 244 (HTTP_STREAM_JOB)
t=3524 [st=1] -HTTP_STREAM_JOB_CONTROLLER

And examining the HTTP_STREAM_JOB below it we can see it had an IDLE priority meaning there wasn’t a request waiting for that connection.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
244: HTTP_STREAM_JOB
https://www.wikipedia.org/
Start Time: 2019-04-17 14:59:20.511
t=3523 [st=0] +HTTP_STREAM_JOB  [dt=1]
               --> expect_spdy = false
               --> original_url = "https://www.wikipedia.org/"
               --> priority = "IDLE"
              --> source_dependency = 243 (HTTP_STREAM_JOB_CONTROLLER)
               --> url = "https://www.wikipedia.org/"
               --> using_quic = false
t=3523 [st=0]    HTTP_STREAM_JOB_WAITING  [dt=1]
                 --> should_wait = false
t=3524 [st=1]   +HTTP_STREAM_JOB_INIT_CONNECTION  [dt=0]
t=3524 [st=1]     +HOST_RESOLVER_IMPL_REQUEST  [dt=0]
                   --> address_family = 0
                   --> allow_cached_response = true
                   --> host = "www.wikipedia.org:443"
                   --> is_speculative = false
t=3524 [st=1]        HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK
                     --> cached = true
                     --> ipv6_available = false
t=3524 [st=1]        HOST_RESOLVER_IMPL_CACHE_HIT
                     --> addresses = ["91.198.174.192"]
                     --> expiration = "13199983755512496"
t=3524 [st=1]     -HOST_RESOLVER_IMPL_REQUEST
t=3524 [st=1]      TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS
                   --> group_id = "ssl/www.wikipedia.org:443"
t=3524 [st=1]      SOCKET_POOL_CONNECTING_N_SOCKETS  [dt=0]
                   --> num_sockets = 1
t=3524 [st=1]   -HTTP_STREAM_JOB_INIT_CONNECTION
t=3524 [st=1] -HTTP_STREAM_JOB

Using netlog requires a bit of practice, it exposes what’s happening in Chrome’s network layer so there’s a lot of information and often seemingly duplicate entries where Chrome is racing connections.

Closing Thoughts

Using Safari is by far the simplest way to check preconnect is working and it would be great if other browser makers made it as easy!

I also came across a few bumps in my tests…

  • It appears that preconnect doesn’t currently work in Firefox even though it’s supposed to

  • I like to use a rel="preconnect dns-prefetch" pattern so there’s a fallback for browsers that don’t support preconnect. Unfortunately it appears this breaks preconnect in Safari, so I either need to drop the dns-prefetch fallback or switch to two separate statements.

Further Reading

Resource Hints

Firefox failing to preconnect

Safari failing to preconnect when preconnect and dns-prefetch specified in same rel attribute

My collection of rel=”preload” test pages

Comments