3 reasons why you should let Google host jQuery for you
AJAX, JavaScript, Performance, jQuery By Dave Ward on December 10th, 2008All too often, I find code similar to this when inspecting the source for public websites that use jQuery:
<script type="text/javascript" src="/js/jQuery.min.js"></script>
If you’re doing this on a public facing* website, you are doing it wrong.
Instead, I urge you to use the Google AJAX Libraries content delivery network to serve jQuery to your users directly from Google’s network of datacenters. Doing so has several advantages over hosting jQuery on your server(s): decreased latency, increased parallelism, and better caching.
In this post, I will expand upon those three benefits of Google’s CDN and show you a couple examples of how you can make use of the service.
Update (11/6/09): Since you’re reading this post, you may also be interested to know that Google also hosts full jQuery UI themes on the AJAX APIs CDN.
* None of this is relevant to internal applications served over a LAN. It would be as likely harm performance as improve it.
Decreased Latency
A CDN — short for Content Delivery Network — distributes your static content across servers in various, diverse physical locations. When a user’s browser resolves the URL for these files, their download will automatically target the closest available server in the network.
In the case of Google’s AJAX Libraries CDN, what this means is that any users not physically near your server will be able to download jQuery faster than if you force them to download it from your arbitrarily located server.
There are a handful of CDN services comparable to Google’s, but it’s hard to beat the price of free! This benefit alone could decide the issue, but there’s even more.
Increased parallelism
To avoid needlessly overloading servers, browsers limit the number of connections that can be made simultaneously. Depending on which browser, this limit may be as low as two connections per hostname.
Using the Google AJAX Libraries CDN eliminates one request to your site, allowing more of your local content to downloaded in parallel. It doesn’t make a gigantic difference for users with a six concurrent connection browser, but for those still running a browser that only allows two, the difference is noticeable.
Better caching
Potentially the greatest (yet least mentioned) benefit of using the Google AJAX Libraries CDN is that your users may not need to download jQuery at all.
No matter how aggressive your caching, if you’re hosting jQuery locally then your users must download it at least once. A user may very well have dozens of identical copies of jQuery-1.3.2.min.js in their browser’s cache, but those duplicate files will be ignored when they visit your site for the first time.
On the other hand, when a browser sees multiple subsequent requests for the same Google hosted version of jQuery, it understands that these requests are for the same file. Not only will Google’s servers return a 304 “Not Modified” response if the file is requested again, but also instructs the browser to cache the file for up to one year.
This means that even if someone visits hundreds of sites using the same Google hosted version of jQuery, they will only have to download it once.
Implementation
By now, you’re probably convinced that the Google AJAX Libraries CDN is the way to go for your public facing sites that use jQuery. So, let me show you how you can put it to use.
Of the two methods available, this option is the one that Google recommends:
The google.load() approach offers the most functionality and performance.
For example:
<script type="text/javascript"
src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// You may specify partial version numbers, such as "1" or "1.3",
// with the same result. Doing so will automatically load the
// latest version matching that partial revision pattern
// (e.g. 1.3 would load 1.3.2 today and 1 would load 1.4.2).
google.load("jquery", "1.4.2");
google.setOnLoadCallback(function() {
// Place init code here instead of $(document).ready()
});
</script>While there’s nothing wrong with this, and it is definitely an improvement over hosting jQuery locally, I don’t agree that it offers the best performance.

As you can see, loading, parsing, and executing jsapi delays the actual jQuery request. Not usually by a very large amount, but it’s an unnecessary delay. Tenths of a second may not seem significant, but they add up very quickly.
Worse, you cannot reliably use a $(document).ready() handler in conjunction with this load method. The setOnLoadCallback() handler is a requirement.
Back to basics
In the face of those drawbacks to the google.load() method, I’d suggest using a good ‘ol fashioned <script> declaration. Google does support this method as well.
For example:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function() { // This is more like it! }); </script>
Not only does this method avoid the jsapi delay, but it also eliminates three unnecessary HTTP requests. I prefer and recommend this method.
Conclusion
According to a recent study, Google will consume 16.5% of all consumer Internet capacity in the United States during 2008. I think it’s fair to say that those guys know how to efficiently serve up some content.
The opportunity to let the pros handle part of your site’s JavaScript footprint free of charge is too good to pass up. As often as even returning users experience the “empty cache” load time of your site, it’s important to take advantage of an easy optimization like this one.
What do you think? Are you using the Google AJAX Libraries CDN on your sites? Can you think of a scenario where the google.load() method would perform better than simple <script> declaration?
I wonder why hasn’t this been done for MicrosoftAjax.js?
Update: Microsoft now provides a similar service for MicrosoftAjax.js.
Similar posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this" link underneath the comment you're replying to.
75 Mentions Elsewhere
- Host jQuery at Google (with Intellisense support)
- Dew Drop - December 10, 2008 | Alvin Ashcraft's Morning Dew
- rascunho » Blog Archive » links for 2008-12-10
- if(JTeam && Toolman) {blog.read();} » Blog Archive » Javascript libraries hosted by Google
- Looking at Code | Have Google host libraries.
- Let Google host your jquery.js file | eKini: Web Developer Blog
- Coderies | taggle.org
- links for 2008-12-12 « boblog
- Daily Digest for 2008-12-12 | andrew . tj . id . au
- BlogBuzz December 27, 2008
- Quick Tip – let someone else serve your CSS framework
- Google hostet Javascript-Libraries
- Test
- Let Google Host Your jQuery Javascript File at Will Ayers - Design and Programming Blog
- Daily Links | AndySowards.com :: Professional Web Design, Development, Programming, Hacks, Downloads, Math and being a Web 2.0 Hipster?
- Weekly Web Nuggets #42 : Code Monkey Labs
- Event Calendar: Submitting Events » Death of a Gremmie
- Shizzle» Blog Archive » Let Google host jQuery for you
- ghettocooler.net » The Links Have Risen
- Wordpress插件:Use Google Libraries - 苍楼笔记
- Ventajas y desventajas del uso de Google como host de librerías javascript « Gerardo Contijoch
- Carron Media - Extend Google Analytics with jQuery
- DotNetShoutout
- Introducting Typekit | Industrial Brand
- Jaap Vossers’ SharePoint Blog » Using Google Ajax Libraries API to load jQuery
- Code a Tricky Login Form With Sliding Signup with jQuery. | CodeTricky
- Mike Panitz's Blog » Using jQuery with CakePHP: The Basics
- Use Google Libraries | 风云阁
- Sunfish Interactive | Blog » 3 reasons why you should let Google host jQuery for you | Encosia
- Varför ska man använda jQuery från Google? | Andreas Karman
- Consuming a Web Service in OBIEE Presentation Services using JQuery CDN | Art of Business Intelligence
- JavaScript Standards - Not Just a Hat Rack
- Lightbox Effects, smaller and quicker | Nashville Web Design by GroovySoup
- SODEVE
- 5 Fast Ways to Speed Up Your Blog
- Installing JQuery « Lonelycamel's Blog
- ZENVERSE – Fail-Proof Method to load jQuery Library via Google AJAX Libraries API
- Image Caption Slide using jquery | iamkreative - design, kidney and general blog
- Usa el jQuery de Google, anda. | Quenerapú
- Use Google Libraries | Blue Orbs
- 4 Ways Google Wants to Help Your Site’s Speed | Nashville Web Design by GroovySoup
- Splat Labs » Blog Archive » Let Google host it for you!
- Adding jQuery to a custom theme using wp_enqueue_script | Prolific Notion
- Using CDN Hosted jQuery with a Local Fall-back Copy | I love .NET!
- Ubrzajte izradu web stranica pripremom predloška | Kroativ
- What is Content Delivery Network & how to use it with WordPress? | Blog Design Studio
- Random Links #127 | YASDW - yet another software developer weblog
- Featured Slider
- We Love… » Blog Archive » Speed Up Your Web Content Delivery… the essential checklist
- Website Optimisation - iandevlin.com – blog
- 5 Cool Hacks and Tutorials Using WordPress and jQuery | wpConstructs.com - Community Blog for WordPress Lovers
- Lifesize Blog
- Notes from Day One of WordCamp Ireland | Steve Flinter
- uberVU - social comments
- Let Google host the JQuery of your Trac! « Das Weblog zur Person
- How to marry TYPOlight with jQuery | qzminski
- jQuery för nybörjare
- jQuery HTML effects - Trav's Tinkering
- jQuery – de goede manier | Code snipplets
- The Venture Foundation ::
- Teaching Online Journalism » Looking at jQuery for visual journalism
- Rhonda Friberg » Blog Archive » Google AJAX Libraries
- Caching on the Google AJAX Libraries API | Soupgiant
- DrakNet Web Hosting Blog » Site Performance: Tweaking Distribution
- Faster Speed in WordPress Using Google’s Hosted JavaScript Libraries | kevinleary.net
- Tips & Tricks « jQuery Refuge
- Simplify you Web Analytics with jQuery - 1918 Internet Services
- Cargar jQuery desde Google | GFDEZ: Laboratorio Web 2010
- RSS mixer service update | BrianDart.net Blog
- 让Google给你的网站加速 | 图腾
- First Time Website Design - Page 11 - Overclock.net - Overclocking.net
- Kestrel Internet Development
- jQuery: » The Official jQuery Podcast – Episode 32 – Dave Ward
- The Official jQuery Podcast
- The Official jQuery Podcast – Episode 32 – Dave Ward


We tried to do this, for all the reasons you state. Unfortunately, for the few weeks that we had it that way, our local development internet connection was a bit unpredictable. Every time the internet connection came down, testing ground to a screeching halt; it just wasn’t considered worth it in the end.
There are ways around this. Not certain of which framework you’re using… But in Django you set a debug settings. And you’ve got access to this in your templating framework.
Dave,
The only thing that bugs me about this is that the intellisense in VS2008 doesn’t pick up the google js file. This isn’t a big deal as I just add a local reference for working with it and then remove it before deployment.
Would be good if the intellisense worked on remote JS files.
Jon
If you’re working in JavaScript include files, you can use:
/// <Reference Path="/path/to/jquery-vsdoc.js"/>This is a great post which expands a post I made on my blog called Differences Between Local And Google Hosted jQuery Installations so hopefully anybody who comes here needing help with jQuery on Google will find all the information they need!
Keep up the good work, Ian.
@Paul: When doing development, you should have a local copy anyway IMHO. You’re not developing/testing on your live server are you?
If you’re doing this on a public facing* website, you are doing it wrong…
Strong words.
What if you are serving up content over https?
https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js
Using the google.load() method will also allow you to use Google’s ClientLocation :)
http://code.google.com/apis/ajax/documentation/#ClientLocation
True, but caution: ClientLocation is often null even when it’s clear that location information is available.
It’s a nice API and I’m glad they make it free, but just know that even with corporate, fixed-IP addresses it often doesn’t know anything about location.
What if the user’s network (for some reason) is blocking googles CDN.
This could happen if some crazy corporate policy exists, that stops the downloading of some other file on the CDN (or blocking google entirely).
These users will no longer be able to use your site correctly.
I don’t think you’re very likely to find that combination in practice. If they’re willing to block 16.5% of the Internet in one shot, they’ve probably blocked your site too.
I can speak from experience – that this happens.
It’s a royal pain, too.
Indeed it does. And the people on the other end generally won’t be back.
If you’re coding the site correctly, the experience will degrade but not lose any functionality in this scenario. Since some users turn JS off at the browser level, you should be doing this anyway.
yeah yeah, but let’s face it – not everybody has time to pour into perfect degradation when < 1% of their users fall into the no-js category
Thanks for the write-up, Dave. I’ve been using the Google hosted jQuery for a while and wondering if I shouldn’t be. Your points remind me why I started doing it in the first place and makes me feel more confident that I should continue doing so.
Couldn’t you use JS to verify google’s jQuery script loaded… Then fallback to a locally hosted version if it’s unavailable?
if(typeof jQuery == ‘undefined’)
{
// load local version….
}
https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js….
Nice one fella!
My only concern would be breaking changes with a new version. I know, not probable, but definitely possible…….
If you’re using the <script/> method, you don’t have to worry about that. The 1.2.6 URL will always load 1.2.6, even after 1.3 is released.
If you used the google.load() method and didn’t specify the full version explicitly (e.g. “1″ or “1.2″), that could definitely be a problem.
^^^
Over engineering?
This is probably the most worthless thing Google has come up with. Yeah sure it’s nice that they are supporting the libraries, but really, how is this beneficial? All we do to handle the problem you describe in your post is to download the minified versions of all the plugins and then cut and paste the code into one file.
Now we don’t have to worry about sending 15 files across the pipe (we use a lot of plugins) and all we’re really sending is the minified files and our custom javascript file. 2 files and that’s it.
Why would you want to force me to re-download jQuery in your combined include? That’s an unnecessary waste of time and bandwidth.
Script combining is generally a good idea, but rolling jQuery into your monolithic JS include will never match the performance of using Google’s CDN; not even for users with an empty cache.
You’d be very, very surprised at how much it does matter. Rolling it into 1 big JS is the preferred way to package a JS-packed site.
If you roll jQuery and all your plugins into one JS include and I use the Google hosted jQuery in conjunction with a combined include with just my plugins, my site will load faster than yours every single time. Even for users with an empty cache.
I could argue this all day long since you seem overly stuck in your ways, but 95% of the time it’s far faster to roll up your own JS file, jsmin it, and gzip compress it to your users.
Unless you’re running a heavily loaded server (and even then), it would still be faster to load one file then it would to do 2 full remote calls.
Of course the timing is also dependent upon a few things: your distance to the server hosting the files (hops), your connection, the call order, and how loaded your server is.
I’m not a big fan of someone proposing an idea as the one and only way to accomplish something — and all other ways of doing it are wrong (which is basically what you said, exempting LAN of course). Also by comparing via one tool on one browser is the wrong way to go about showing performance gains.
Anyway, I’d suggest you check out some other methods before claiming a dependency as the best way to do it. I call it a dependency because you’re now fully relying on a third-party. There’s many ways to deliver a payload faster — through things such as dynamic JS importing/loading, etc.
For what it’s worth, so you don’t think I’m picking one way of doing things and arbitrarily claiming it’s best, I’ve been testing it both ways for quite awhile. Even using the old Google Code hosted version, which was less optimized for serving users, was faster than rolling it up.
That’s before you even consider the users who will show up and already have it cached locally.
I’d love to see a post making the counterpoint, with numbers. If you made one, I would be happy to link to it from this post, to offer more complete information.
Interesting post.Thanks for sharing this.
One reason not to use it is privacy:
Google will know all of your client’s IP-addresses, referrers, etc. It’s like using google analytics, but only Google seeing your statistics.
In European data protection laws it may even be illegal.
Yeah, that’s one aspect that I’m not crazy about. At this point though, I’ve mostly given up on Google not knowing what’s going on with a public facing site’s traffic.
++
Privacy was my first thought while reading this article. One should try to not give Google more information than absolutely necessary.
That’s not true, given that a client makes a request once a year if the browser keeps the caching contract, i would hardly call it intrusive.
Chances are your clients will be using google to search for stuff more than once a year.
It would still make the request to get the 304, it just wouldn’t secure a data transfer. Google’s servers could still be logging those 304 requests.
Google currently sets an “expires” header of one year in the future on these files. If your browser has cached Google’s jQuery-1.2.6.min.js on the client side and you visit a new site that uses it within a year, the browser doesn’t even have to check for a 304.
If Google really were as prying as some of the more paranoid among us would suggest, then they wouldn’t set that expires header. They’d happily pay the bandwidth bill to log the 304s.
Thanks for this post! But why do you initialize your script with google.setOnLoadCallback() instead of $(document).ready() ?
Because i still use $(document).ready() even when i load jQuery with google’s jsAPI and it works well.
I’ve found that it depends on how fast google.load() loads jQuery and where your $(document).ready() is.
It would probably be of more value if Google also stored copies of frequently used plugins as well as the main jquery file.
Even with the delay, there is one advantage of the google.load() method.
Remember that SCRIPT tags block the download of other components and the loading of the dom. This blocking nature is primarily designed to support document.write() and other synchronous features of the language.
When a script is loaded dynamically, it is not a blocking download. (Document.write is also broken, but you shouldn’t be using that anyhow.)
So, even though the total time for jQuery’s load might be 200ms longer, if the jQuery loading takes a while, then your page is functional that whole time, rather than freezing up waiting for it.
If you’re just including jQuery, a mere 16723 bytes gzipped, it’s probably not too terrible. If you were loading lots of different scripts and modules, or if perceived load time was absolutely critical, then it could be more significant.
Isaac, that’s a great point. Depending on your existing page’s logic, switching to google.load() may or may not be an advantage if you have onload code that (un)intentionally depends on the blocking behavior of regular script tags. Definitely something to consider and test for if making the switch.
It probably bears more thorough testing, but I’ve found that google.load() exhibits the same blocking behavior as a normal script element.
I’m assuming (dangerous!) that google.load() works by injecting a script element via document.createElement(), which would be subject to the same blocking issues.
Hi Dave. But if there truly was blocking with google.load(), then this isn’t consistent with your response to Julien’s comment above where you said “I’ve found that it depends on how fast google.load() loads jQuery and where your $(document).ready() is.” when he asked about why you would need to use setOnLoadCallback() rather than jQuery’s $(document).ready().
I haven’t done any testing, but if there truly was blocking with google.load(), then I’d think there would be no reason you couldn’t use $(document).ready().
Try this, for example:
Attempting to access the jQuery object in the same block as the google.load will fail because jQuery hasn’t had time to load. Yet, if you watch in something like Firebug, the google.load() of jQuery will still block site.js until it completes loading (after the early $ access already threw an error anyway).
Just to underscore this point, this post has been receiving traffic from this search query:
http://www.google.com/search?q=%22%24+is+not+defined%22+jquery+google+ajax+api
So, people are definitely running into this issue in practice.
The google.load() function supports a callback parameter, to let you execute a function when the script has loaded. You should be using that instead for this sort of thing.
function jq_init() { alert "jquery just finished loading"; } google.load("jquery", "1.2.6", {"callback" : "jq_init" });Hi, thanks
your write but not for all conditions.
read my blog to know why you should not host it on Google.
http://tajary.blogspot.com/2008/12/1-reason-why-you-should-not-let-google.html
thank you
Any comments on this? Seems Google code might be blocked in certain countries. If so, that would be a strong argument against this method. Anyone have more info on this?
Alireza’s problem is due to the US embargo against Iran, as absurd as that is.
Anyone knowledgable as to which countries are blocked from Google code due to this embargo?
Absurd and ridiculous as it may be, it might be a production-stopper if you plan on doing business in any of those countries (and not already hindered from doing so if your company resides in the U.S).
Once again, good point this should NOT be done. I would rather 100,000 users have .5 sec of extra load time — rather than block a single user. Point made.
It’s like .. I want it to be a good idea .. I’m an optimization freak, but it practice, this is just over engineering that doesn’t help.
This is a good piece of code for testing. It demonstrates that while loading jQuery via google.load(), the browser will continue to execute/process the page until it hits another piece of external content to retrieve. I do get the “$ is not defined” error.
In contrast, there’s no error when using a script tag for jQuery since the browser completely halts execution of the page until jQuery has fully downloaded and been parsed.
But with this, as Isaac pointed out, there may be a small delay in the page fully loading compared to google.load(). Assuming all your onload jQuery logic is currently wrapped up in (document).ready(), switching to Google’s setOnLoadCallback() method seems safe to do. If Google’s CDN serves jQuery quickly, I don’t think I’d be worried about just using the script tag, avoiding google.load().
It’s all very well arguing the point of using Google’s setOnLoadCallback() to initiate your code while not hindering page loads, but at the end of the day it is quite likely that you’re calling a third part jQuery plugin locally, and the fact that this WILL be done using a script tag will no doubt result in the script loading fully before the DOM continues to load happily.
What’s the recommended pattern for lazy-loading the jquery framework (and associated plugins)? I am thinking of scenarios like webparts, where you require the use of jquery, but don’t want to cause another http request and subsequent parsing of the same library.
You could use something like this before first use of jQuery in each of your webparts:
I’m not sold on benefits of google hosted jquery.
Whats your assumption re your visitors browser cache settings (on/off)
if a majority of your visitors have clear cache sure, CDN hosting of ALL objects would accelerate loads but otherwise, there are basic principles to improving client side render performance without introducing a reliance on an external host..
- use minimized versions of jquery (remove white space, decrease file size)
- gzip (compress whats left to send over wire)
- apache mod_expires (cache for X timeframe)
- host jquery on separate host (deliver static objects and dynamic by separate hosts)
- locate JS files at bottom (prevent script blocking)
- Load all required JS files on early in visit process. don’t double up…Static object loads shouldn’t be coupled with query responses
also worth noting, once you start a browser session and your browser either confirms the objects status’s or redownloads, for the rest of that session, you won’t notice a benefit because user local cache is used for the rest of that session..
Even if you ignore the caching angle, Google’s CDN is going to serve files faster than you will be able to. Their CDN is one of the best in the world. Users potentially hitting the page with it pre-cached is just icing on the cake.
Sure, CDN hosting all static assets is even better, but how many sites really do that? The vast majority of sites in the wild use no CDN.
Even for sites that do use a CDN, using Google’s jQuery is an opportunity for cost cutting and potentially increased parallelism (assuming more than just JS is distributed via CDN).
* gzip (compress whats left to send over wire)
Totally in agreement for this. It really matters a lot compressed and uncompressed scripts.
Check the headers. Google’s hosted versions are all compressed, minimized, everything. They’ve basically taken it upon themselves to optimize the hell out of these javascript libraries for the fastest possible hosting of them, with far-future expires headers and everything else.
Using these will almost always be faster than not using them, in virtually all cases.
…but what if the user got this fine plugin named “NoScript”.
NoScript won’t load scripts from other domains as standard – the user have to accept them. :(
are there possibilities like Zach said:
excuse my bad english and greets from northrhine westfalia,
mathias
btw. this is a great article!
This is interesting. What if you are using custom jQuery plugins? Can you still use this method?
Sure. It’s just like using a local copy of jQuery, only faster.
Do you know all those sites that fetch jQuery from Google Dave? Well, 9/10 you will see calls to ajax.googleapis.com that are taking ages to reply, so I think that using a different host to fetch jQuery is slower – overall – than including it from the server that one is already connected to.
I’ve always found the opposite to be the case (Google serves it faster than my servers can). Do you have any examples of sites that hang on the dependency?
I’ve seen this with slow DNS servers.
Regarding the “$ is not defined” issue when loading using googles ajax method. I use the following and have had 0 issues with it so far…
—————————————
google.setOnLoadCallback(init);
function init() {
$(function() {
//initialise…
});
}
—————————————
So, uh, Google’s having *serious* latency issues (at least from my part of the world), and large and small sites alike that rely on the hosted jquery are hanging completely. Awesome! Granted, this will hopefully happen only rarely, but…
And that’s exactly why I don’t use Google for my jQuery stuff. Local is best. I started seeing issues with Gmail from yesterday onwards. Who knows, maybe their maps are no longer reduce (or the other way round). Again, CDN is nice in theory, but don’t think that it beats local (well, depending on most sites’ target audience).
Looks to have more to do with network routing and less with Google: http://blogs.zdnet.com/BTL/?p=18064
None of my sites were very affected by this. Remember that the CDN hosted files are served with a +1 year expires header. Returning users don’t even require a 304 ping.
It would be a problem for new users, but how many new users (who don’t have access to Google search to find you) affected by the routing issues are you likely to bounce in that couple hour window? It’s a pain, but no where near a catastrophe.
One big surprise is that with Firefox 3 fetching jquery 1.3.2. from Google I get a 200 status code every time instead of 304.
So there is no caching benefit, just the benefit from the CDN.
Can anybody confirm this ?
thanks
Because it’s served with a far-future expires header, you’ll only see a request if your cache doesn’t contain a copy of the file. For up to a year after it’s cached, no request is made at all when the browser encounters a reference to it, not even to check for a 304.
So, the only time you’ll ever see a request, it will have a 200 response. You shouldn’t see subsequent requests (and 200 responses) though, unless something’s preventing your browser from caching the file.
What you mention is true for jquery-1.2.6 but not for 1.3.2
Try the simplest page and check with firebug. If you reload the simple page with 1.2.6 you will see a 304 status code but a 200 status code for 1.3.2:
I think the issue is that the response adds a http header Age not zero which is not included when you request 1.2.6.
Try it! I was quite surprised !
It’s normal to see a 200 response on the first request.
It would be abnormal to see a 304. With a far-future expires header, the browser shouldn’t even be pinging for a 304 if it has it cached.
When it’s being properly cached, you shouldn’t even see it appear in the Firebug net tab.
Sure, the previous post skipped the basic html. I compared a page with jquery 1.2.6 and another with 1.3.2. The page with the old jquery caches properly but not the one with 1.3.2.
At least with firebug 1.3 I see the 304 because if you look at the header responses it returns a Last-Modified, which takes precedence over expires
It takes 5 minutes to do this test in firebug but I assume you haven’t even tested what I am saying.
Your script snippet in Back to Basics references 1.3.2, so you should update the article. I will also try with IE and report the findings.
I use the Google hosted 1.3.2 on several sites. I double checked them this morning, after reading your comment, to make sure it’s still caching properly in Firefox.
It is for me.
The browser never makes a request for jQuery (1.3.2), not even a ping for 304, unless I clear my cache or force an update with a shift/ctrl reload.
I also verified it in Live HTTP headers and Wireshark. Firefox is using the locally cached copy and isn’t sending even a single byte over my connection when it hits a reference to http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
Do you have a publicly available page that reproduces what you’re seeing? I’ll take a look at it.
Thanks for checking.
My issue is minor, I was refreshing both a page with 1.2.6 and a page with 1.3.2. The page with 1.2.6 checks the 1.2.6 link and gets a 304. The page with 1.3.2 gets a 200
Bravo, Google :)
If you happen to run a WordPress site, there’s a plugin that will easily do this for you, for all available JS libraries:
http://wordpress.org/extend/plugins/use-google-libraries/
Just install and activate. Operation is automatic, no configuration needed.
Thanks for sharing your knowledge!
If you are using opendns and you have set the protection level to highest, there is a great chance that the google website will be blocked for your entire network, these are some wise words though on CDN and general website performance.
Thanks a lot! You have opened my eye and now I am surely going to put the Google hosted jQuery on my blogger blog! :) thanks once again!
I’ve been doing this as a matter of course since Google first announced they were hosting the files. I’ve not personally seen any performance increase, as I always keep my pages as lightweight as possible in any case, but neither have I had any problems. I agree that this is a best practise missed by most, and it’s always worthwhile exploiting any optimisations you can!
Sorry, the first code should be:
google.load(“jquery”, “1.3.2″);
google.setOnLoadCallback(function() {
//this worked
});
And the second block of code should be:
$(function() {
//This didn’t work on IE but it did on FF
});
I am considering using google api, but I have a question.
What is the likelyhood that google will host old versions indefinatly? I have made websites for clients for almost 15 years now and one of the oldest is still running today. I would hate to think that a site I make today would not run in 20 years time because the js is no longer hosted on google?
That’s a good question that I don’t know the answer to. My guess would be that they would continue hosting it as long as it was actively serving requests. There’s so little overhead in it, I’d be surprised if they went out of their way to break something being used like that.
Worst case, it’s a very quick search-replace to globally update a site to use a locally hosted legacy version instead of Google’s.
Hmm, not very reassuring. But I still would like to use it. Best solution I can think of is to check to see if jquery has loaded, if not load a local version?
Have any thoughts on how that could be done best?
You can do this:
Because script elements block rendering until they’ve loaded and been executed, you can assume if jQuery isn’t present in the subsequent script block that it has failed to load from Google and then react accordingly.
You confirmed my thoughts. Thank you very much for the help.
I’ve tried the check and eventually load locally method above; I’ve intetionally used a bad url for google jquery to see if the local loading of jquery was really done. And indeed it was, but looking at firebug network tab, I see that others js libraries requiring jquery, load before the local copy of jquery, breaking any jquery-dependent functionality on the page.
Here’s my test code:
Firefox loads the second library as soon as google gives the 404 error, and then loads local copy of jquery after some other resource files, as ccs o gifs.
Do you know a way to correct this behaviour? Am I doing something wrong?
Thanks!
Sorry, I’ve lost some piece of code. Hope this works:
if (typeof jQuery === 'undefined'){ document.write(unescape("%3Cscript src='js/jquery-1.4.2.min.js' type='text/javascript'%3E%3C/script%3E")); }thanks for your advice
keep it up
Yeah, I just found out from another programmer out there that this is definitely better than hosting the jQuery script yourself. It was nice to see exactly why it is better after reading your article.
Thanks a lot.
It would be nice to use Google’s CDN but as google is blocked in some countries and some networks … Anyhow, it is a good idea to use some CDN, perhaps build a very own to increase parallelism and improve caching. What about latency? well, we are talking about 20kb of jquery minified and gzipped, just make sure to use less images and optimize their size :)
Thanks Dave, Encosia hasn’t been in my feeds for a very long time, but it never fails to teach me something new and interesting, I like this post and I adore the discussion opened up by the readers, you could add the pro’s & con’s to your post that have risen so far, that would be a good summary :)
thanks again and keep it up!
I have a asp.net app that has a dynamic combining of the various scripts (jquery, plugins, etc) – total of ~110Kb, combined, gzipped.
When I serve jquery combined with other scripts (1 script tag), latency is around 500ms.
When used google’s CDN hosted version of jquery (1.3.2) and firebug shows latency of around 828ms for the scripts in net tab.
All tests are done on local VS development server.
What do you think? Will these results change when I host my application on some online server?
Yes, you should expect to see the extra HTTP request be much more significant in a local setting. That won’t be the case once deployed to a live server.
I personally have other stuff within my “jQuery” file like jQuery Tools and JSHTML with I use on almost every page where I might use jQuery.
So that’s one reason I wouldn’t use it, since you can’t have any other files in it. Also, it’s yet another http request so if you’re already loading other stuff, why not have jQuery be loaded in there as well.
I can see myself using this for stuff like tutorials though, where all I would need is jQuery.
Thanks for the article! Firebug tells me, Google’s response is about 50 ms (jquery) and 150 ms (jquery ui) faster than my remote dev machine. It’s also gzipping, so I don’t have to take care of that. Seems to me like there is an advantage on using Google’s hosting the way you suggest. I also used your fallback code, thanks for that!
Although – right now I’ve got only 4 JS files, which might double or tripple at the end of development. From past experience I still suspect, that nothing is faster than combining and compressing all JS into one (as well as CSS). As far as my limited experience goes, this is always the fastes solution, although it’s more tedious to maintain. The process has to be repeated for every update to any JS or CSS file. One could still use a CDN though, by just buying some cloude space. Should not be too expensive per year for a couple of text files which are often cached.
The fallback code works like a charm if remote JS files are blocked by NoScript. That leaves only the “user lives in Iraq”-scenario, unfortunately. Maybe a country specific IP range can be considered.
For https I’m thinking it would be possible to use the Analytics code:
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
Obviously changing the URL.. Not tried yest but it should work.
It is good for most shared hosting users to offload extra scripts and resources as much as possible, but when you have a low latency, high bandwidth server, you are just as well off since you no longer require an extra DNS request, which can waste lots of time.
Only if you assume that all of your users are closer to your server than they are one of Google’s CDN edge servers and that the user doesn’t have the Google CDN copy of jQuery already cached (which would lead to the browser not making a DNS lookup or HTTP request at all).
Was doing some research into this trying to pick whether to use
jsapi+google.load or the direct library path. I noticed that with the former
method, the js lib comes with a 1yr-in-the-future expiration date while with
the latter, a 1hr. Here are the (relevant) HTTP response headers from FireBug:
using google.load():
Content-Type text/javascript; charset=UTF-8
Last-Modified Thu, 14 Jan 2010 01:36:01 GMT
Date Fri, 22 Jan 2010 20:27:03 GMT
Expires Sat, 22 Jan 2011 20:27:03 GMT
Content-Encoding gzip
Cache-Control public, must-revalidate, proxy-revalidate, max-age=31536000
Age 176
Content-Length 23807
using straight url:
Response Headersview source
Content-Type text/javascript; charset=UTF-8
Last-Modified Thu, 14 Jan 2010 01:36:01 GMT
Date Fri, 22 Jan 2010 20:33:37 GMT
Expires Fri, 22 Jan 2010 21:33:37 GMT
Content-Encoding gzip
Cache-Control public, must-revalidate, proxy-revalidate, max-age=3600
Age 161
Content-Length 23807
Turns out, the confusion is that this reference:
http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js
Is not a reference to 1.4, but the latest 1.4.x release. Since it would defeat the point of a “latest” reference to cache it for a year without requiring a 304 check, they use shorter expires headers on those.
Using this reference:
http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js
Supplies the +1 year expires header as expected.
Paul Irish has more info on that here: http://paulirish.com/2009/caching-and-googles-ajax-libraries-api/
This is a great article but when I try this approach the intellisense will not work. Is there a work around to fix that?
Assuming your code is in .js includes, download the vsdoc and place this at the top of your includes:
/// <Reference Path="~/path/to/jQuery-1.x.x-vsdoc.js" />For Intellisense inline in ASPX pages, you can use this trick:
It will never be rendered to the page, but Visual Studio will still parse the file for Intellisense.
Ok I tried this but I don’t seem to get it to work. Here is what I did
Did I put it in the wrong place? As long as I don't reference the Google page my page works but as soon as I point to Google - no intellisense.
Thanks for your help.
I don’t have VS2008 handy to test with, but that code does give me jQuery Intellisense in inline code blocks in VS2010.
@Terry: I had the same problem.
This worked for me on VS2008:
http://nitoprograms.blogspot.com/2010/02/jquery-hosted-on-googles-cdn-with.html
This method would be great if everyone used it. The problem is that only something like < %5 of sites use it meaning the extra DNS lookup to google costs more time than just hosting the file yourself. Since you are only pulling one file from google, you never beat the initial dns overhead that using their CDN costs
Having total control of your source codes outweights all of the advantages listed and discussed above. Why should you rely on someone else, even Google, may have an impact, beyond your control, on your company/business website?
For a personal website, I can see the benefit but not for company/business websites. Foolish thinking not practical.
Unless you planned on modifying jQuery.js, you still have total control of your source code. If something were to happen, you could switch the reference to a local copy in minutes. It’s no less practical than using any other CDN, which business sites have been doing for years. Unfounded paranoia is no reason to slow the web down as a whole.
The difference is that the Google CDN for javascript libraries doesn’t offer an SLA.
Automatically falling back to a local copy isn’t difficult (see the examples of that throughout the comments here). In the bigger picture, I tend to agree with Nate that SLAs are empty anyway. I’m less interested in who to blame during the .0001% than I am how to improve performance/user-experience during the other 99.9999%.
I think if you agree to an SLA which is ‘empty’ then absolutely, there’s no point to it. But if you properly set an SLA with your hosting provider which guarantees your servers, with fines etc for any problems, then to bring a key part of your page engine away from that definitely negates the whole purpose and would not be justifiable in terms of business accountability.
Switching back to a local copy is your solution if something happens. Then, why bother with that headache in the first place? Beside, your suggestion shows that you did not consider the business implication. Redirecting your customers to Google equates with Google accessing your customer’s intelligent info. Furthermore, it is practical to point out that jQuery is only about 70k. What gain you actually do? NOTHING.
Therefore, it is foolish and ill business practices, still.
Falling back to a local copy is automatic. Why bother? Eliminating a quarter-second or so of page-blocking JavaScript is well worth understanding how to best use the resources available.
As long as the majority of sites are using services such as AdSense, Google Analytics, Google Maps, etc, I have a hard time buying the FUD and paranoia. Of all the services like that, using the CDN is one of the most benign, since the browser may not even contact Google again for a full year after jQuery has been downloaded once.
I think, Billy Nguyen’s concern cannot be dismissed. He points out that there are differences for commercial and for non-commercial websites, and that they must be considered, especially the ones about privacy, and especially if you’re gaining about a millisecond in performance. A business should have the possibility to invest in a save CDN. Just as more and more businesses can’t rely on Google Analytics anymore, because then you’re sending certain 2-party-data to a 3rd party (Google). In some countries like here in Germany, this starts to go to courts already. The solution also for this problem is relying on software which can be hosted on the companie’s property.
On the other hand, since when everyone points to Google for hosting of files, they get cached a lot and Google’s servers are not contacted anymore, so it’s even harder to make “sense” of this info.
Why not do it the other way around for business sites? Use a local copy, and when that is not available, fall back to a 3rd party CDN. Seems like an unusual case (unless you do have your own CDN or CDN-like setup), but if it does happen, it seems like good service to your customers not to bother them with the tech problems.
Privacy on the Internet is a nice notion, but largely an illusion. Of all the actively invasive methods that advertisers and ISPs use to track users, focusing on the potentially once-per-year jQuery CDN accesses is a non-starter for me. If Google were really out to leverage the service for “evil”, they definitely would not serve the file with a +1 year expires header.
Sorry, but I seriously disagree with you here. This cavalier “well, we don’t have privacy anyway” attitude is the very reason that privacy is such an issue in this day and age. When they came for the trade unionists, I said nothing.
You are wrong to just dismiss these claims. At best, you are being disingenuous by not giving security in this matter an equal discussion. At worst, you’re ignorant to the real problems here. In a below response to John Sanders, you state that, “if Google’s CDN were compromised, you’d probably find that out much quicker than if your own hosting was.” I don’t necessarily agree with that. When you use the Google APIs, you don’t have an SLA with them. They are under no contractual obligation to report exposure to you.
More importantly in this day and age, and the real reason I take serious issue with your “this is the best approach for everybody, except maybe intranets” attitude, Google does not need to be compromised in order for the content to be exploited. Man-in-the-middle attacks are extremely easy to pull off, especially when the content is being served via HTTP mechanisms.
Here’s the real problem.
If somebody visits a website that uses the Google-hosted jQuery and their session is compromised just once, every single session they have on any and EVERY site they subsequently visit that uses Google’s jQuery is also compromised. If someone were to inject a modified jQuery to Joe Sixpack while he was browsing the web at Starbucks (or even as he passed by a rogue access point with wifi enabled on his phone or laptop – on a freaking plane, even), the response can be set to cache that content for decades. At which point, every single request to a Google jQuery-enabled site is now affected. The very caching that you espouse as one of your main three benefits also introduces a serious potential vulnerability.
This isn’t being overly-paranoid, this is being realistic. As long as we’re using plaintext protocols, depending upon an outside CDN to provide portions of executable code that are shared among thousands of sites is just an awful idea.
Everybody is free to make their own decisions, but you should really be fair here and give discussion to the fact that in order to enable “Eliminating a quarter-second or so of page-blocking JavaScript,” site managers are opening up a new potential avenue for attack. When explained in these terms, many businesses may make a different decision.
Parallelism is also a dubious argument. Anybody can enable parallel loading of JS content on their site without much difficulty. And if one is concerned about the two-concurrent-sessions-per-host browsers as you discuss, you can just as easily serve the content from a different hostname. Yes, it’s another DNS lookup, which adds latency (assuming they already have the Google DNS entries cached).
Everybody needs to make this decision on their own, weighing all of the benefits against all of the downsides. This is far from a “one size fits all” solution, and there are many factors to consider. Risk assessment is a real concern here.
You have a heavily-linked page on this topic. You would do well to treat the topic honestly and fairly. I’m sorry, but I don’t feel you are currently doing that.
Interesting. I doubt the benefit of users not having to download jQuery at all because it’s cached exceed that of minifying all your javascript files,including jQuery, into one file and serving it from Cloudfront, which is what I do.
Thanks for the article Dave!
What makes me most uncomfortable about this approach is security. If Google’s servers are ever hacked (improbable, but not impossible), then think about how many websites will be running malicious code. Who knows what kind of information a bad person could grab by reading your cookies, or scraping your screen. For this reason, I would only use this strategy for websites that contain no private user information.
Hacking happens.
John
That’s definitely a valid concern.
Of course, if Google’s CDN were compromised, you’d probably find that out much quicker than if your own hosting was.
Dave, have you seen this article?
http://zoompf.com/blog/2010/01/should-you-use-javascript-library-cdns
It says using CDN’s for javascript isn’t worth it – the DNS adds 1/3 second delay verses your own domain, and jQuery only takes 1/3 sec to download.
He’s also says only 2% of Alexa 2000 websites use a javascript CDN, so it’s unlikely the visitor has it cached already.
In short he says:
What do you think?
I don’t agree with their assessment about the likelihood of a cache hit. With such a wide gamut of high-traffic sites (like Time, SlideShare, ArticlesBase, Break, Stack Overflow, Examiner, Woot, and ArmorGames, to name a few) using the Google CDN, it’s becoming more and more likely that the minority of your users are the group that don’t have a local copy cached.
I totally agree D Yeager. 300%.
I tested this on my website and loading MooTools (well it’s not jQuery, but the situation remains the same) from Google CDN adds latency due to the DNS request. We switched to a locally hosted copy and the site is faster now.
My advice is to test before diving into such advice. It may be not that good as it seems…
I agree that testing is important to any optimization. For example, my browser took 678ms just now to download MooTools from your server, but only 91ms from ajax.googleapis.com.
Of course, that datapoint might be irrelevant if you don’t expect to reach a global audience with your particular site. It’s a good reminder of how effective geographically dispersed edge servers are though.
Yes, the location (geographically) of the user plays an important role here. Our server would certainly perfom better in France and nearly countries while you have a penalty from America. Your remark just made me check how many folks visit the our site from the other side of Atlantica. It looks like we have 4%, so it’s reasonnable not to use a CDN.
I guess a very good option here would be to have those major libraries hosted locally, directly embedded in the browser as instance. That would definitively save up some time for everyone!
I’m also wondering how this could affet the new criteria from Google’s pagerank: the site load time is taken into account. If the googlebot fetches everything from America, that would be a load time penality for the crawler. Even more if the DNS are cached: the CDN version would perform a lot better. Any thought on this?
I think I would rather site visitors accessed this locally on my servers than kicking off another DNS request. I think I’ll still run some tests to see if there’s really much difference. Maybe better to use the hosted version if you’re working with Google tools a lot such as Maps?
Cheers.
It’s smart to consider the DNS lookup. However, it turns out that so many of the most trafficked sites are referencing the ajax.googleapis.com domain now, the DNS lookup is going to be already cached at the browser or OS level for most users.
What happens when Skynet(Google) becomes self aware?
Is it possible to use Jquery with Google Sites?
I think I’ll stick to localhost serving of scripts, I got fast server and have run tests and got such mintue improvement it was outweighed by serving extra dns requests to another server, but a great post to highlight the point, it will be better for most sites I’m sure ;-) (lol at Jim Kennellys skynet comment)
Does it help make a decision knowing twice this month I’ve had issues getting Google Code hosted jQuery to work appropriately?
It’s hard to find information out there, but I know it happened.
Great article!
Awesome article, i was always against grabbing jquery from google for risk of it being slower, great work
I was doing this today, until I noticed that http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js is “Not Found” and will not load on my website. I reverted back to a local copy, it is more reliable.
@James P.
If you agree to use Jquery hosted externally and your problem is the reliability of the external link, you can do a little check like this:
if (typeof jQuery === 'undefined'){ document.write(unescape("%3Cscript src='js/jquery-1.4.2.min.js' type='text/javascript'%3E%3C/script%3E")); } In this way you can serve a local copy of jquery just in case google link fails.Seems like Google is moving away from direct inclusion. And want you to get an API key. Using the API method, would the file js file still be cached?
To be more specific, will this still be cached
Scripts loaded through the jsapi loader are cached.
I still prefer the direct reference for pulling a single script off the CDN. It only requires a single HTTP request, where jsapi/google.load() results in two.
The place where using google.load() makes sense is when you’re pulling several scripts off their CDN. Then, its dynamic script injection will probably be faster than static script references.
I would do this if it weren’t for the fact that I’ve corrected bugs inside jQuery that would otherwise cause errors to be served to my clients.
Thanks for the handy article. :)