|November 22nd, 2014|
"UA strings need to die a horrible horrible death."
"The UA string is flawed by itself. it shouldn't even be used anymore. The fact that browser manufacturers have to include all sorts of stuff is proof that this system doesn't work."
"Well written sites use feature detection, not user-agent detection."
"We'd all be better off if they just stopped sending the UA string altogether"
The modern advice is to use feature detection. Instead of the server
User-Agent header to guess at what features
if the specific feature you need is supported. When this fits your
situation this is great, but it's almost always slower. Many times
but let's look at a case where the performance issues are substantial.
Let's say I want to show you a picture of a kitten:
How big is that?  It depends how we encode it:
|Unoptimized JPEG||290.0 kB|
|Optimized JPEG||38.6 kB|
|Optimized WebP||20.2 kB|
SupportsWebP() it either loads
image.jpeg. What's inefficient about this? How is this worse than just handling
Here are two example pages, containing a single external script and an
img tag. Running these both through WebPageTest (1,
here are charts showing how the browser loaded the page:
in order while when using an
img tag the two files could be
loaded in parallel. 
To emit html that references either a JPEG or a WebP depending on the
browser, you need some way that the server can tell whether the
browser supports WebP. Because this feature is so valuable, there is
a standard way of indicating support for it: include
image/webp in the
Accept header. Unfortunately this
doesn't quite work in practice. For example, Chrome v36 on iOS broke support for WebP images
data:// urls but was still sending
image/webp. Similarly, Opera added
image/webp to their
Accept header before they supported WebP lossless. And no
one indicates in their
Accept whether they support animated
This leaves us having to look at the
User-Agent header to
figure out what the browser is, and then look up what features that
browser supports. The header is ugly, I hate having to do this, but
if we want to make pages fast we need to use the UA.
(The full gory details:
 I uploaded this picture to my server as a poorly optimized jpeg, but I'm running PageSpeed. You should be seeing WebP if your browser supports it, or an optimized JPEG if it doesn't.
 Which would be a bit of an awkward function.
 This only is a problem because of the external script reference. If there were nothing to block the regular parser then both versions would be just as good. (1, 2) Most pages do reference external scripts, however, so in practice the preload scanner helps a lot and you don't want to disable it.