top | item 19447059

Preload, prefetch and other link tags

157 points| iamakulov | 7 years ago |3perf.com

26 comments

order

kevingadd|7 years ago

It's unfortunate that Chrome's definition of 'mandatory' is flexible in a bad way. If you've done enough performance profiling of webapps in Chrome you may have noticed that even cached resources can take over 20ms to load from cache - this is because all cache loads have to go between processes, so they get delayed until thread/process switches can happen and messages can get ferried back and forth. If you're unlucky, you eat this delay on every resource you load. In some cases this can add over a second to load time for an application.

You might think 'well this calls for prefetch, right? load them all at once'. You're right! Except it doesn't work. Chrome content processes ignore prefetch directives, all they seem to do is ensure that they're in cache - so there's no way to avoid eating this 20+ms hit per-resource.

Ideally you control all the code being run in your app so you can just issue the relevant XHR requests to load everything up-front and not block on those requests, but I've frequently run into cases where a downloaded resource loads other resources, etc. Really frustrating that caching and prefetch are so slow in Chrome and there's no indication that they will fix it.

It's my understanding that in comparison Safari does not have this hit per-asset, loading the applications I've tested is dramatically faster on an iPhone compared to Chrome on a desktop PC. :(

strictnein|7 years ago

Random question: for the preconnect, is there some Javascript API now that allows for the monitoring of the TLS handshake?

As specified in the article, the handshake is:

   TLS handshake (only for HTTPS sites). Perform two roundtrips 
   (a message goes client → server → client → server → client) to initiate a secure TLS session
Is there any part of that which could be used to send a custom message to the client? A short bit of text or a number or something. Don't really have a practical use for this, just more of an esoteric one.

tyingq|7 years ago

You can't do it from a browser, but the "tls client hello" could certainly hold a custom message of sorts. Either in the "random bytes" it's supposed to send, or stuffed in as a fake cipher preference in the supplied list.

Good breakdown of the handshake here: http://www.moserware.com/2009/06/first-few-milliseconds-of-h... (skip down to the client hello)

Crosseye_Jack|7 years ago

It’s silly o’clock here (unable to sleep) and the following is just going off the top of my head, apologises if I mess it up.

Don’t believe so as during the first round trip in http1 (wasn’t this “fixed” in http2? Silly o’clock, can’t remember, anyways) the client and the server are just working out which cyphers to use.

If you are trying to pull data from the same domain, you have already set up a connection you can reuse saving the need to repeat the need for the first round trip on your next connection to the server. So you are only really losing that first round trip on the first connection. So even if you were pinging another domain regularly as long as you are using a server configured to keep the connection alive for long enough you are not really going to save much any time then just doing it the standard way.

I guess (never tried) you could create your own raw socket connection with say webasm but Browsers do here hardest to keep you away from the raw socket level and I believe they also do even in webasm. (just thinking out loud...)

Then smuggle in your value based on the the cyphers you are requesting the client to pick from. But at which point you might as well just be using plain old un-encrypted socket connections.

EDIT: If you are just trying to send metadata along with a xhr response then you can just send custom headers along with the response and read them with getAllResponseHeaders(), just remember to set the Access-Control-Expose-Headers header too include the custom headers you want to expose to JS.

If you are trying to push data from the client to the server I guess you could do it via DNS. Make a request to http(s)://uuid.part1.thisisamessage.example.com and http(s)://uuid.part2.sentoverdns.example.com and on your dns server record the requests, resemble the parts and you have your data. You could bitbang data back to the client by having the dns reply with a server or not. It would be slow as hell (as your making a dns request and opening up a connection for each bit) but it could be done but unless you are trying to be sneaky (and it’s not that sneaky at all) it’s not worth the hassle over just opening up a “full fat” connection and reusing that connection. (Again just unable to sleep thinking out loud...)

wiml|7 years ago

Sure, both the ClientHello and ServerHello (which are the first two messages during setup) can contain arbitrary extension fields; these are already used for things like SNI, ALPN, "early data" (optimistic 0-RTT data), and so on. You could define an extension in the private-use range for your esoteric use.

I don't think there's any way to see this from Javscript, though. At least, not web-browser Javascript.

smacktoward|7 years ago

I'm not sure where the submitted title came from; it's not the title on the article, and it's factually incorrect -- there's only one tag (LINK), which includes an attribute (REL) that can be set five different ways. That's a lot cleaner and more orderly than "5 different tags to preload something" suggests.

dang|7 years ago

We've replaced the title with that of the article. (Submitted title was "HTML has 5 different tags to preload something. Here’s a deep-dive into all".)

theoh|7 years ago

"TCP has 11 different state machines."

mr_toad|7 years ago

If we’re splitting hairs, I believe that according to the default SGML concrete syntax a tag is delimited by angle brackets, so both the element and the attributes are part of the tag.

sureaboutthis|7 years ago

Just because I can...

I find it interesting that he is inconsistent in his usage of <link>. Some of his markup has a closing slash and some of it doesn't. However, my main gripe, is that the HTML spec has never specified or required a closing slash. While it is allowed, putting that slash there has no meaning, it does nothing, and the spec tells browsers they are to ignore for those reasons.

When I ask why some people insist on putting it there, I get wildly different, unreasonable answers.

"It's just a bad habit I picked up."

How do you pick up a bad habit for something that does not exist?

"I do it so it's XHTML or XML compatible."

Well, you aren't serving it as either XHTML or XML and are very unlikely to do that. In addition, the rest of your HTML is probably not XHTML or XML compatible on top of that.

"The spec does allow it."

It allows it, as I always tell them, due to backwards compatibility with (X)HTML uses in the past, but it also says you're wasting your time and effort. See my comment at the top.

To end this, no HTML specification in the history of the universe has ever stated you need to or should put a closing slash on <link> or <img> or <input> or any other HTML tag and there is no example of such usage anywhere in said documentation either.

underwater|7 years ago

HTML doesn't require a closing slash, but without it needs to be context-aware and maintain a whitelist of tags that are self closing (one effect of this is that custom elements can never be self closing).

It's not really surprising that a developer would gravitate towards an encoding that is not dependent on maintaining a whitelist of tags, because that is the solution that intuitively feels more "correct".

runarberg|7 years ago

prettier-js puts them there. I don’t know why, and I don’t care, so I leave them there.

reaperducer|7 years ago

I do it because it feels right and logical. If something has a start, it should have an end. If you’re making a <div> that is only going to be used as a spacer with styling, you wouldn’t just do a <div> and leave it hanging.

00N8|7 years ago

personally, I don't care one way or the other, so I always leave them whichever was my most recently used linter/IDE's default preference & basically ignore it beyond that

the spec says to ignore it either way & I think my way aligns w/ that (while being nearly optimal in terms of effort efficiency)

shawnz|7 years ago

Some template engines require well-formed XML (like Thymeleaf, in certain configurations)