{"id":72,"date":"2012-08-07T18:10:36","date_gmt":"2012-08-07T18:10:36","guid":{"rendered":"https:\/\/adeelejaz.com\/blog\/?p=72"},"modified":"2016-01-12T23:56:48","modified_gmt":"2016-01-12T23:56:48","slug":"revisiting-user-agent-strings","status":"publish","type":"post","link":"https:\/\/adeelejaz.com\/blog\/revisiting-user-agent-strings\/","title":{"rendered":"Revisiting User Agent Strings"},"content":{"rendered":"<p>I will start by pointing out that I will not spend time any time discussing the historic value of <a href=\"https:\/\/en.wikipedia.org\/wiki\/User_agent#User_agent_identification\">User Agent strings<\/a> (also referred to as Browser IDs). A few sites have done it rather well (<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms537503(v=vs.85).aspx\">MSDN<\/a>, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Gecko_user_agent_string_reference\">MDN<\/a>).<\/p>\n<p>In this day and age, we optimize everything from our JS and CSS files to HTTP and image requests. We use tools that compress images better (or strip bytes off it). I propose an optimization that has been over-looked for years, for one reason or another!<\/p>\n<p>For every single request made in this world via a browser, the browser adds a User-Agent header in the request, yes, <em>every single time<\/em>!<\/p>\n<h2>Mozilla\/5.0<\/h2>\n<p>My first jab is at \u201cMozilla\/5.0\u201d. Is it still 1995? No. Then why are we carrying this \u201clegacy\u201d with us. Personally, I believe it is there so whenever a new developer asks why its there, it gives the senior developer an opportunity to re-live and re-tell the story of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Browser_wars\">Browser Wars<\/a>!<\/p>\n<p>So, without any delay, lets look at what exactly is being sent by the famous browsers:<\/p>\n<p>(For sanity, I\u2019m not including IE6, IE7 or IE8 but trust me, they are <em>VERY<\/em> long!)<\/p>\n<p><strong>Internet Explorer 9 32-bit (70 bytes):<\/strong><br \/>\nMozilla\/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident\/5.0)<\/p>\n<p><strong>Internet Explorer 9 64-bit (75 bytes):<\/strong><br \/>\nMozilla\/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident\/5.0)<\/p>\n<p>First stop, Internet Explorer. I just do not understand why I\u2019m seeing the \u201ccompatible\u201d string even though I\u2019m not running in compatibility mode. But according to Microsoft, \u201c<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms537503(v=vs.85).aspx\">it indicates that Internet Explorer is compatible with a set of common features<\/a>\u201d. Umm, what common features? We\u2019ll never know. I also find it fascinating that Internet Explorer tells which 64-bit CPU you are using (that x64), <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms537503(v=vs.85).aspx#FtrToken\">Intel or AMD<\/a>. What I just love is that really useful \u201cfeature\u201d disappears for\u00a0Internet Explorer running on \u201cWindows Phone 7\u201d! Oh come on&#8230; I would love for my Windows Phone to shout to the world what&#8217;s my CPU!<\/p>\n<p><strong>Firefox 13 (74 bytes):<\/strong><br \/>\nMozilla\/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko\/20100101 Firefox\/14.0.1<\/p>\n<p>Second stop, Firefox. See something repeating? Yep, that is the version of Firefox, in this case, 14.0 that is repeated twice. Why? <a href=\"http:\/\/en.wikipedia.org\/wiki\/Gecko_(layout_engine)#cite_note-urm-22\">Because Gecko version is kept the same as Firefox since Firefox 5.<\/a> Then you might think what is &#8220;20100101&#8221; there for? I won\u2019t bother trying to explain as things get really confusing really fast, specially considering that for mobile browsers this is same as the Firefox version (Whaaat??) Just head over to <a href=\"https:\/\/developer.mozilla.org\/en\/Gecko_user_agent_string_reference\">Mozilla<\/a> for a dose of confusion as I&#8217;m starting to think they might even not know why it\u2019s there to begin with, or how it helps someone by putting this info in a UA String.<\/p>\n<p><strong>Opera 12.01 (100 bytes):<\/strong><br \/>\nOpera\/9.80 (Windows NT 6.1; WOW64; U; Edition United States Local; en) Presto\/2.10.289 Version\/12.01<\/p>\n<p>Opera does something that no one else does. They have actually dropped \u201cMozilla\/5.0\u201d. Which is my proof that the internet does not come to a halt when you remove it! Dead proud of it but my happiness doesn\u2019t last long! For <a href=\"http:\/\/dev.opera.com\/articles\/view\/opera-ua-string-changes\/\">some reason<\/a> Opera tells everyone, \u201cHey, its Opera 9.80\u201d but then at the end, confesses its 12.01. I would love to argue about why it could\u2019ve been better handled but there\u2019s something else I want to point out. That \u201cU\u201d!!! Its an <a href=\"http:\/\/en.wikipedia.org\/wiki\/User_agent#Encryption_strength_notations\">encryption identifier<\/a> that has become obsolete since 1996! If that\u2019s not enough, for some reason Opera is telling everyone that its \u201cEdition United States Local\u201d, which I assume means \u201cit\u2019s\u201d a United States edition. How does it help anyone is beyond my limited thinking! I\u2019m in the UK, and I doubt it\u2019ll change if I was in France. That \u201cen\u201d is a two letter <a href=\"http:\/\/en.wikipedia.org\/wiki\/Language_code\">language code<\/a> for English. I hope Opera is not telling everyone that I&#8217;m running a US English Edition of Opera, because I do not see how it can help the server serve me the right \u201ccontent\u201d, or someone needs to tell Opera that there is an \u201cAccept-Language\u201d header that they should use.<\/p>\n<p><strong>Safari 5.1 (106 bytes):<\/strong><br \/>\nMozilla\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\/534.57.2 (KHTML, like Gecko) Version\/5.1.7 Safari\/534.57.2<\/p>\n<p><strong>Chrome 21 (106 bytes):<\/strong><br \/>\nMozilla\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\/537.1 (KHTML, like Gecko) Chrome\/21.0.1180.60 Safari\/537.1<\/p>\n<p>Lastly, Chrome and Safari, I\u2019ll rant them together, well because Chrome just copies what Safari does. First, Safari and Chrome tell everyone, \u201cHey, its KHTML\u201d but then they say, \u201cTell you what, we\u2019re like Gecko\u201d. I also think since the project is called \u201cWebKit\u201d, it should not be \u201cAppleWebKit\u201d but I don&#8217;t want to start a fan boy war. What I find fascinating with Safari\u2019s version is that they use WebKit\u2019s version right after Safari. And then create a separate declaration for \u201cVersion\u201d which is actually for Safari. Go figure!<\/p>\n<h2>Operation Clean Up<\/h2>\n<p>My proposal is to simplify the damn thing. And here it is:<\/p>\n<p>[Browser Engine]<strong>\/<\/strong>[Version] <strong>(<\/strong>[OS]<strong>;<\/strong> [Architecture\/Others]<strong>)<\/strong> [Browser]<strong>\/<\/strong>[Version]<\/p>\n<p>And the new User Agent strings will look like:<\/p>\n<p><strong>Internet Explorer 9 32-bit (44 bytes):<\/strong><br \/>\nTrident\/5.0 (Windows NT 6.1; WOW64) MSIE\/9.0<\/p>\n<p><strong>Internet Explorer 9 64-bit (38 bytes):<\/strong><br \/>\nTrident\/5.0 (Windows NT 6.1) MSIE\/9.0<\/p>\n<p><strong>Firefox 6 (53 bytes):<\/strong><br \/>\nGecko\/20100101 (Windows NT 6.1; WOW64) Firefox\/6.0.2<\/p>\n<p>PS: Someone needs to tell Gecko team on how to do versions.<\/p>\n<p><strong>Opera 12.01 (50 bytes):<\/strong><br \/>\nPresto\/2.9.168 (Windows NT 6.1; WOW64) Opera\/12.01<\/p>\n<p><strong>Safari 5.1 (51 bytes):<\/strong><br \/>\nWebKit\/534.57.2 (Windows NT 6.1; WOW64) Safari\/5.1.7<\/p>\n<p><strong>Chrome 21 (56 bytes):<\/strong><br \/>\nWebKit\/537.1 (Windows NT 6.1; WOW64) Chrome\/21.0.1180.60<\/p>\n<h2>Savings?<\/h2>\n<p>Let\u2019s take example of <a href=\"http:\/\/uk.yahoo.com\">Yahoo!<\/a>. Its a pretty optimized website but it makes 80 HTTP requests. Lets see how it pans out in terms of savings:<\/p>\n<table>\n<tbody>\n<tr>\n<th rowspan=\"2\">Browser<\/th>\n<th colspan=\"2\">Current<\/th>\n<th colspan=\"2\">Proposal<\/th>\n<th>Savings<\/th>\n<\/tr>\n<tr>\n<th>Size per Request<\/th>\n<th>Size for 80 requests<\/th>\n<th>Size per Request<\/th>\n<th>Size for 80 requests<\/th>\n<th><\/th>\n<\/tr>\n<tr>\n<td>IE 32-bit<\/td>\n<td>70<\/td>\n<td>5600<\/td>\n<td>44<\/td>\n<td>3520<\/td>\n<td>-37.14%<\/td>\n<\/tr>\n<tr>\n<td>IE 64-bit<\/td>\n<td>75<\/td>\n<td>6000<\/td>\n<td>38<\/td>\n<td>3040<\/td>\n<td>-49.33%<\/td>\n<\/tr>\n<tr>\n<td>Firefox 13<\/td>\n<td>74<\/td>\n<td>5920<\/td>\n<td>53<\/td>\n<td>4240<\/td>\n<td>-28.38%<\/td>\n<\/tr>\n<tr>\n<td>Opera 12.01<\/td>\n<td>100<\/td>\n<td>8000<\/td>\n<td>50<\/td>\n<td>4000<\/td>\n<td>-50.00%<\/td>\n<\/tr>\n<tr>\n<td>Safar 5.1<\/td>\n<td>106<\/td>\n<td>8480<\/td>\n<td>52<\/td>\n<td>4160<\/td>\n<td>-50.94%<\/td>\n<\/tr>\n<tr>\n<td>Chrome 21<\/td>\n<td>106<\/td>\n<td>8480<\/td>\n<td>56<\/td>\n<td>4480<\/td>\n<td>-47.17%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>* All numbers are in bytes.<\/p>\n<p>Just to re-iterate. This information is <em>not cached<\/em>, <em>not zipped<\/em>, and <em>sent every single time<\/em>! For every single page request. Imagine the amount of bandwidth we can save on mobile devices! Just imagine&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content --><p class=\"wp-flattr-button\"><a href=\"https:\/\/adeelejaz.com\/blog\/?flattrss_redirect&amp;id=72&amp;md5=fb1d58f5c9d797f1806914c32fdcca6a\" title=\"Flattr\" target=\"_blank\"><img src=\"https:\/\/adeelejaz.com\/blog\/wp-content\/plugins\/flattr\/img\/flattr-badge-white.png\" srcset=\"https:\/\/adeelejaz.com\/blog\/wp-content\/plugins\/flattr\/img\/flattr-badge-white.png, https:\/\/adeelejaz.com\/blog\/wp-content\/plugins\/flattr\/img\/flattr-badge-white@2x.png 2xhttps:\/\/adeelejaz.com\/blog\/wp-content\/plugins\/flattr\/img\/flattr-badge-white.png, https:\/\/adeelejaz.com\/blog\/wp-content\/plugins\/flattr\/img\/flattr-badge-white@3x.png 3x\" alt=\"Flattr this!\"\/><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>I will start by pointing out that I will not spend time any time discussing the historic value of User Agent strings (also referred to as Browser IDs). A few sites have done it rather well (MSDN, MDN). In this day and age, we optimize everything from our JS and CSS files to HTTP and [&hellip;]<!-- AddThis Advanced Settings generic via filter on wp_trim_excerpt --><!-- AddThis Share Buttons generic via filter on wp_trim_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-72","post","type-post","status-publish","format-standard","hentry","category-web"],"_links":{"self":[{"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/posts\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":1,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"predecessor-version":[{"id":73,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions\/73"}],"wp:attachment":[{"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adeelejaz.com\/blog\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}