Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a limit to how many domains we should "dns-prefetch preconnect" with Chrome?

When we want to make sure a blazing fast website who uses third-party widgets/plugins/add-ons/analytics etc.. One of the many requirements to achieve this is to "dns-prefetch preconnect" for each individual domain name (basically saving a little for the DNS lookups etc.)

I could not find a document that would advise how many domain names we could "dns-prefetch preconnect" before we lose any potential benefit. Remember how in the old times Internet Explorer had a limit to how many images could be downloaded in parallel, just wonder if Chrome could have some reasoning for limiting "dns-prefetch preconnect" request?

For example: how many is too many?

<link rel="dns-prefetch preconnect" href="https://admin.typeform.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://api.amplitude.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://api.segment.io" crossorigin />
<link rel="dns-prefetch preconnect" href="https://app.launchdarkly.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://bam.nr-data.net" crossorigin />
<link rel="dns-prefetch preconnect" href="https://cdn.amplitude.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://cdn.segment.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://customer.api.drift.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://embed.typeform.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://event.api.drift.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://events.launchdarkly.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://fonts.googleapis.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://images.typeform.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://js-agent.newrelic.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://js.driftt.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://load.sumo.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://metrics.api.drift.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://renderer-assets.typeform.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://static.addtoany.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://sumo.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://weclean1.typeform.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://www.google-analytics.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://www.googletagmanager.com" crossorigin />
<link rel="dns-prefetch preconnect" href="https://www.youtube.com" crossorigin />

Any links feedback/advice is greatly appreciated!

like image 228
dankilev Avatar asked Mar 31 '19 20:03

dankilev


2 Answers

Resource hints shouldn't be over-used

First, as mentioned below, you should prefer preload. If you don't know exactly what resources your page will include, the dns-prefetch and preconnect can be appropriate.

The resource hint specification indicates that the optimal number of connections is highly contingent:

The optimal number of connections per origin is dependent on the negotiated protocol, users current connectivity profile, available device resources, global connection limits, and other context specific variables. As a result, the decision for how many connections should be opened is deferred to the user agent.

Both dns-prefetch and preconnect indicate the user agent "should" initiate the process, which means they don't have to do so.

Ilya Grigorik, the editor of that spec, says

That said, use it wisely: each open socket incurs costs both on the client and server, and you want to avoid opening sockets that might go unused. As always, apply, measure real-world impact, and iterate to get the best performance mileage from this feature.

Sérgio Gomes, also a Googler, echos Ilya's warning with a bit more specificity:

Bear in mind that while <link rel="preconnect"> is pretty cheap, it can still take up valuable CPU time, particularly on secure connections. This is especially bad if the connection isn’t used within 10 seconds, as the browser closes it, wasting all of that early connection work.

In general, try to use <link rel="preload"> wherever you can, as it’s a more comprehensive performance tweak, but do keep <link rel="preconnect"> in your toolbelt for the edge cases.

Sérgio continues to illustrate a couple examples where preconnect, rather than preload, is appropriate. I highly recommend taking a look at those.

Ivan Akulov, former Googler and current web performance startup CEO, ventures a numerical recommendation:

You want to speed up more than 4-6 domains. It’s not recommended to use <link rel="preconnect" /> with more than 4-6 domains, as opening and keeping a connection is an expensive operation. <link rel="dns-prefetch" /> is more lightweight, so use it for other third-party domains if you want to speed them up too.

But Ivan, though a reputable source, doesn't provide hard technical support for this recommendation.

Without reading the source code for each relevant browser, it's impossible to defensibly say how many dns-prefetch/preconnects are too many. Even after reading source code, it can only offer a hint as to how many are appropriate. There is no hard limit, but the authoritative sources above give us reason to be cautious.

But it's difficult to know where to draw the line

There's only one way to improve performance:

  1. decide which metrics matter to you and your users
  2. use the best available synthetic and real-user numbers to measure the status quo
  3. make changes and measure the difference

It would take a number of iterations to land on the best possible configuration. And the optimal hint selection could change over time. From a maintainability perspective, it would be best to aggressively preconnect everything that meets Sérgio's "edge case" requirements, and trust the browser to do its job. But again, never without testing.

A couple other notes

That's a lot of third-party dependencies for that page. I'm sure you're working within your requirements, but this may be a great time to ask management to re-evaluate the necessity of some of those.

Finally, keep in mind that crossorigin isn't appropriate for every resource hint. It depends on whether the resource(s) to be downloaded will use CORS. If you don't know, that could double the number of preconnects needed.

The crossorigin attribute, when used with rel="preconnect", doesn't describe where the target origin is but rather what kind of assets will be downloaded from that origin. If the assets use CORS, crossorigin is needed. If CORS won't be used, crossorigin should be omitted. If both types of assets will be present, two resource hints are necessary.

Take a look at this list of resources that use CORS for guidance.

like image 78
crenshaw-dev Avatar answered Oct 10 '22 18:10

crenshaw-dev


Also be aware of this bug if you care about Safari:

https://web.dev/preconnect-and-dns-prefetch/

Browser support for dns-prefetch is slightly different from preconnect support, so dns-prefetch can serve as a fallback for browsers that don't support preconnect.

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

Recommended — To safely implement the fallback technique use separate link tags.

<link rel="preconnect dns-prefetch" href="http://example.com">

Not recommended — Implementing dns-prefetch fallback in the same tag causes a bug in Safari where preconnect gets cancelled.

like image 34
Null Avatar answered Oct 10 '22 17:10

Null