By TJ Van Toll
This question gets asked a lot, and I’ve yet to see a data-based exploration of this topic. Terms like “big” and “bloated” are relative terms; they don’t mean anything without numbers to back them up. The real question should be – “Does the size of jQuery adversely affect the users of my applications enough to outweigh the development conveniences that the library provides?”
To answer that question, we need to determine how long it takes to load jQuery on mobile devices. The rest of this article is dedicated to determining that number, and to get it, we have to start with a discussion of how the <script>
tag works.
Disclaimer: I’m a member of the jQuery team and am currently writing a book on jQuery UI. To keep this discussion objective, I’ll stick to numbers as much as possible.
The <script> Tag
<script src="jquery.js"></script>
We’ve seen this code countless times, but what does the browser actually do when it parses this line of HTML? The answer is: a lot – but we can break it down into two high level tasks:
- Retrieving the file (either from a cache on disk or from the network).
- Parsing and executing the script.
Let’s explore each of these individually.
Downloading jQuery
For the purposes of this article, we’ll assume a worst-case scenario: a user visiting an application for the first time with no cached resources. When the browser doesn’t have the script cached, it has to turn to the network to get the file it needs. To measure how long this download will take, there are two factors we need to be concerned with: bandwidth and latency.
Bandwidth
Bandwidth refers to the speed at which the browser can download a resource from a server, and is most commonly measured in Mbps (megabits per second).
In 2012, the average download speed of mobile networks worldwide varied from ~2 Mbps in some Asian countries to ~1 Mbps in Russia and India. That data is slightly dated, and newer networks advertise faster speeds, for example
- Virgin Mobile claims its 4G network has download speeds that vary from 3 Mbps to 6 Mbps.
- Verizon Wireless claims its 4G network has download speeds that vary from 5 Mbps to 12 Mbps.
- LTE networks offer speeds that average from 6.5 Mbps in the US to 24.5 Mbps in Australia (data is from Q1 2014).
Since this article is about jQuery, let’s use these numbers to determine how long a download of jQuery takes. We’ll base all numbers off the minified version of jQuery 2.1.0, which is 28.65KB gzipped (and only the gzip size matters here because it’s the only thing sent across the network).
A network with download speeds of 1Mbps can download 125KB in a second, which means that for every 1 Mbps your mobile network provides, you can download 4.36 jQuery’s/second. Or to put this in terms of time, it means that jQuery takes
- 229ms to download on the worst mobile networks (1Mbps),
- 46ms to download on average mobile networks (5Mbps),
- 19ms to download on awesome mobile networks (12Mbps).
We’ll return to these times later, but at a glance these numbers aren’t that concerning. In fact, from a more general perspective, bandwidth is very rarely a bottleneck for mobile web performance. For instance, Ilya Grigorik from Google found that upgrading from a 5Mbps network to a 10Mbps one improves page load times by a mere 5%.
So if bandwidth isn’t a bottleneck, what is?
Latency
In the context of web applications, latency is the amount of time it takes for the browser to connect with an external server on the network. Latency is typically measured in RTT, or Round Trip Time – which is the amount of time it takes to make a round trip from the browser to an external server.
Historically, we didn’t worry too much about latency for desktop development, as RTTs on wifi networks are small – typically well under 50ms.
We have no such luck with mobile. In 2012 the average RTT time on a mobile network in the United States was 344ms. And that 344ms applies to not only every HTTP request – which the average web page now makes 93 of – but also every DNS lookup and TCP connection.
The RTT data is from 2012, and average RTTs have improved some. For example Virgin Mobile advertises that the average latency on its 4G network is now 150ms. But while average RTTs are improving, there are only small additional gains to be had, as current networks are within a small factor of the theoretical limit dictated by physics.
But there’s a silver lining to all of this. Remember that we’re talking about jQuery, and there’s a simple way to avoid any additional latency costs when using jQuery: instead of placing jQuery and your app’s code in their own files, concatenate them and serve them together.
<!-- Before -->
<script src="jquery.js"></script>
<script src="app.js"></script>
<!-- After -->
<script src="app.js"></script>
This simple change removes a RTT needed to load jQuery in your application. This same guideline applies to loading jQuery from an external CDN. Because of the fragmentation in CDN providers, jQuery versions, and protocol usage (http vs. https), the chances of getting a CDN cache hit are shockingly low – and downloading from an external domain has the potential to perform not one, but three round trips (a DNS lookup, a TCP connection, and an HTTP GET).
To this point, we’ve seen that there is a finite cost to downloading jQuery from the network. We can expect jQuery to take around 50ms to download on an average network, but we can avoid latency costs as long as we concatenate jQuery to our application’s other JavaScript. But downloading the file isn’t our only concern. Next, let’s talk about what the browser does once it has the file.
Parsing and Executing the Script
After the browser has downloaded the textual content of jQuery, it has to turn that text into bytecode and execute it. Under the hood, this is a complex process that is well beyond the scope of this article, but since we’re only interested in the time this whole process takes, we can measure that without getting into the messy details.
I devised the following test to measure how long the parsing and execution of jQuery takes.
<script>var start = new Date();</script>
<script>
/* jQuery's minified source code in its entirety */
</script>
<script>alert( new Date() - start );</script>
I experimented with
console.time()
andconsole.timeEnd()
, but did not use them because they’re unsupported in older mobile browsers. In supporting browsers I received nearly identical times usingconsole.time()
as I did with newDate
objects.
To isolate the parsing and execution time, I take the network out of the equation by including jQuery in an inline script (hat tip to Eric Lawrence for the suggestion). The results of running this test on a series of browsers is shown below.
Browser | OS | Time to parse/execute jQuery 2.1.0 (in ms) |
---|---|---|
IE 11 | Windows 8.1 | 18, 21, 14, 16, 15 |
Chrome 33 | OS X 10.9.2 | 15, 8, 5, 7, 6 |
Safari 7 | OS X 10.9.2 | 9, 5, 3, 3, 2 |
Firefox 27 | OS X 10.9.2 | 12, 12, 11, 12, 12 |
Safari | iOS 7 | 178, 125, 44, 87, 96 |
Default Android | Android 2.2 | 1184, 268, 299, 216, 422 |
Default Android | Android 4.0 | 603, 465, 106, 145, 243 |
Chrome 33 | Android 4.4 | 219, 86, 38, 86, 123 |
Firefox 27 | Android 4.4 | 269, 367, 400, 381, 264 |
The desktop browser tests were run on a high-end MacBook Pro, and the mobile tests were performed on devices that I own. I did not clear the cache between runs; I simply hit the browser’s refresh button. This did produce an interesting result: the WebKit-based browsers appear to cache results of some portion of the parse phase, whereas Trident and Gecko do not. If any engineers from these rendering engines read this, I’d be interested in the details. I’d also love suggestions on more robust ways of obtaining these times.
All desktop browsers – IE, Chrome, Safari, and Firefox – handled this task with ease. Even the worst of the four was able to parse/execute jQuery in an average of 17ms.
Mobile, however, is a different story. Whereas Mobile Safari on iOS7 and the latest Chrome for Android handle this task decently, older Android is a completely different story. My first run of this test on my Android 2.2 device took over a full second. And although I didn’t have any feature phones handy to test on, I fear they would do even worse.
This is bad. And in my opinion, the painfully slow parsing and interpretation of scripts on mobile browsers – particularly older Android ones – is the only compelling reason to prefer tiny JavaScript libraries.
There is one piece of good news in this data: Moore’s law is clearly at play here; you can see the Android times improve as versions roll out, and there’s no reason to believe that this trend won’t continue into the future.
So is jQuery Too Big?
We’ve gone through all of the data, so now it’s time to return to the question. And like the answer to any software development question, the answer always depends on the specific situation. Let’s start by summarizing our numbers.
- Downloading jQuery 2.1.0, or 28.56KB takes
- 229ms to download on the worst mobile networks (1Mbps).
- 46ms to download on average mobile networks (5Mbps).
- 19ms to download on awesome mobile networks (12Mbps).
- Downloading jQuery adds zero latency as long as you’re concatenating it with you app’s other scripts. If you’re not, expect an additional script to add roughly 150ms to 1 full second of load time to your application.
- Parsing/executing jQuery 2.1.0 takes
- ~15-20ms on desktop browsers
- a few hundred milliseconds on most mobile browsers
- possibly a full second or more on old devices.
The numbers that stand out the most are the parse times on older Android browsers. Having the potential to add a full second or more of load time to your application is a really bad thing.
I would advise you to check your stats and know your audience. The higher the percentage of your users that visit your application on old devices and bad networks, the more reason you have to avoid jQuery. But keep in mind that this isn’t just about jQuery; this is about shipping a minimal JavaScript payload. Depending on your application, there’s a chance that using jQuery is actually saving you bytes. (Write less is the first half of jQuery’s motto after all.)
But let’s get back to the numbers. Per the data above, a typical user on an average device and network will take ~50ms to download jQuery and another ~250ms to parse it. To equate this to money, Amazon famously found that every 100ms of delay in the load time of amazon.com cost them 1% in sales. If we accept this finding verbatim, it would mean that including jQuery decreases your mobile sales by 3%. That sounds bad, but you have consider the flip side as well; if using jQuery improves your productivity enough to generate 3% more revenue, in theory including it is worth the trade off.
Another thing to keep in mind is that jQuery 2.1.0 is comprised of AMD modules internally; therefore if you’re concerned about these load times, it’s easy to reduce them by building a custom jQuery containing only the parts you need. But before you go down that route, there’s one final thing we need to touch on.
There’s Almost Certainly Something Way More Important to the Efficiency of Your Application Than Whether You Use jQuery
According to the HTTP archive the average Web page now
- is over 1.7MB,
- makes over 90 HTTP requests,
- has over 275K of JavaScript,
- makes 17 HTTP requests for JavaScript alone,
- includes over 1MB of images,
- makes only 46% of its resources cacheable.
So before you care about jQuery, first make sure you
- minify your CSS/JS assets,
- concatenate your CSS/JS assets,
- gzip your HTML/CSS/JS assets,
- compress your images,
- set appropriate cache headers,
- remove unnecessary HTTP requests.
Often removing an image or two can improve your performance more than removing jQuery, and is far easier to do. If you have performed all these optimizations, and are still experiencing performance issues on mobile devices, then look into removing libraries like jQuery – just make sure you cover your bases first.
Don’t forget that if you’re loading jQuery from a common CDN like Google’s or Microsoft’s, you’re likely introducing zero network latency as the browser will almost certainly have it cached already.
> as the browser will almost certainly have it cached already.
This claim is frequently made, but I’ve also seen many people express skepticism of it. The many different versions of jquery, and several different CDNs, combined with actual typical user behavior patterns, the limited cache capacity of some mobile environments, etc…. it MAY still be true, but I’d really want to see some evidence one way or another before assuming it either way. It’s not an easy thing to measure though, because we are making claims about “most people’s browsers”, and there’s no easy way to measure other peoples browsers.
And why does it matter?
If the ‘most peoples browsers will have it cached’ theory is really true, you would NOT want to concatenate JQuery into one big JS file for your app, as this article suggests you do.
Me, not being sure if the theory is true, I still choose to concatenate as this article suggests, for the reasons this article suggests.
Did you read the link mentioned in the article? https://www.stevesouders.com/blog/2013/03/18/http-archive-jquery/
I think it already replies to this argument.
Hi,
I appreciate the numbers you’ve put together. Thank you and I will be using them in my talks, if that’s alright.
My main question remains: is jQuery actually needed on mobile?
Thanks. I have no issue if you use these numbers. Unfortunately the answer to whether you actually need jQuery is as complex as the answer to whether jQuery is too big; there’s no easy answer and it always depends on the specific thing you’re building.
Dude, you have no idea what’s the “worst mobile network”. I live in Iran and many people still use EDGE data. ~20KBps on mobile. In many other countries, 3G is not always available and the network fallbacks to EDGE. So.
Hi Sallar,
That is an excellent point. Most of my network data was taken from Ookla/Speedtest.net aggregated in this presentation from 2012 (https://www.slideshare.net/patrickmeenan/velocity-2012-taming-the-mobile-beast). A ~20Kbps connection is ~0.15 Mbps, and is definitely way worse than the 1 Mbsp number I reference in the article. That’s the problem with using averages, but it was the best data I could find.
Do you happen to have any good aggregated data on the network speeds in your area?
fwiw a 20KBps connection takes 1.43 seconds to download jQuery, and while that is a lot of time, it’s also a tiny fraction of the time it takes to load an average website on that connection.
Or use the cache manifest to store jQuery and other assets. First time download, other times, don’t care about it. On mobile devices, I have to apps in production using angularjs, jquery and some scripts more. The average loading time was divided by 10 by using cache manifest. Cheers !
Using 1mbps as the benchmark for worst mobile network performance is embarassingly unrealistic unless your users never leave a large urban area in a well developed country.
I apologize if the data I used was inaccurate. Could you provide a reference to more accurate mobile network performance data?
Like PPK says, “The only stats that matter are yours”. Android 2.2 obviously has trouble parsing the first time around, but 2.2 has trouble with everything – including native apps.
It seems to me that latency and pathetic bandwidth are the killers. The US ranks 34th in the world in internet speed. I think that puts us right down there near the bottom. It would appears then that PhoneGap applications would be mostly immune from these issues. Do you agree?
Yes. Unless you’re dynamically loading scripts, then the only thing that matters to PhoneGap apps is parse times. On modern devices the times are negligible in a PhoneGap context, and – like you said – older-device users are not going to be shocked if the app takes a few seconds to load 🙂
Which iOS and Android device did you use? Guess it makes a difference if using iPhone 4 vs iPhone 5s.
I was using an iPhone 5 (not a 5S). And yeah the device can definitely make a difference.
Makes me wonder if storing a library in LocalStorage makes sense. I’ve almost *never* modified my version of jquery on an app once I’ve got things running well.
That’s a valid alternative, but what’s the penalty for reading and then eval’ing the code?
I think your timings are overly optimistic – take this test of your site using Chrome (in mobile emulation mode), with a 1.6Mbps down / 768Kbps up / 150ms RTT connection:
https://www.webpagetest.org/result/140310_7Y_23c89c4f3d5eca01e359dfcaebbc2fe3/3/details/
The network time for jQuery is over 3 seconds!
This test shows the importance of geographic proximity to these times. That test is running on cell towers in London, and the server that actually has jquery.js is in Seattle; so basically each request has to go half way across the world and back. A properly-configured CDN for static resources (which flippin’ awesome does not use) would significantly mitigate these times as it would distribute the files to geographically-closer positions. (When I refer to a CDN I mean your own files on a CDN provider like Akamai, and not jquery.js from Google’s CDN.)
Placing your static resources on a CDN is one of of the things that should be listed on the “There’s Almost Certainly Something Way More Important to the Efficiency of Your Application Than Whether You Use jQuery” list. Yahoo talks about it better than I do: https://developer.yahoo.com/performance/rules.html#cdn.
Thanks for bringing this up. I didn’t cover this in the article because I think the data is confusing enough as is, but it’s a big problem for a lot of sites and something worth further discussion.
I still think the bandwidth numbers are too optimistic in real world scenarios. I measured it several times in my country (Switzerland) under different – but realistic – situations. In many cases the real bandwidth was far from the theoretical value. However: get rid of one not so necessary pic and you saved the amount of data you need for jQuery (or even much more). So I use jQuery without hesitation.
Zepto.js to the rescue! 9.2k when gzipped. https://zeptojs.com/
Your comment comes off a bit flippant, like you read the headline and then skipped to the comments section to preach.
The article clearly explains that there is more to the question than just file size. While Zepto *may* also parse faster because of it’s size (testing required).
I feel the final section stands on it’s own “There’s Almost Certainly Something Way More Important to the Efficiency of Your Application Than Whether You Use jQuery”
How does performance on the client work with gzipped resouces? Wouldn’t there also be time involved with unpacking them? The whole gzipping thing is just to increase performance across the wire, right?
You make a good point. Gzipping is intended to decrease download sizes, but it does mean the browser has to unpack the resources. I’ve always *heard* that those times are negligible, but I don’t recall seeing any data to prove that. It seems like there would have to be a cost – especially on older devices.
The problem is I can’t think of any way to measure that across devices (which is probably why the data isn’t out there).
Mb per second is “Mbps”, not “Mbsp” like you wrote all over the place.
Seems like TJ uses lots of ” ” in his coding 🙂
Whoops. Those are fixed now. Thanks!
Sorry about that – fixed.
Great article. I wasn’t particularly interested in mobile load times, but the article works as an overall view of the aspects of script load time, so it’s still useful in a different context.
You l said you ran those tests in a Mac. Do you use Windows on it or you used a VM for testing IE11? As far as I know you can’t install IE on Mac but I can be wrong.
I run Windows 8.1 on a VM using Parallels (https://www.parallels.com/products/desktop/).
Nevermind. Just tested IE11 and Chrome Canary 35.
Those measures are very similar with mine using Windows 7.
I did some testing a while back to judge the effects of JS parsing speed and compilation caching with the Parse-N-Load library (https://maketea.co.uk/2012/10/30/organisation-for-better-js-performance.html). It doesn’t look like a whole lot has changed in the last 18 months!
What a beautifully written, evidenced and thought-out article!
So useful. Even seasoned Frontend, Backend and UX Developers will be learning something from this. I did.
Thank you!
Do you have the javascript timing page you mentioned somewhere so we can test with out own devices?
Yep. See https://gist.github.com/tjvantoll/9534146 (and https://gist.githubusercontent.com/tjvantoll/9534146/raw/01054233da4db6d82281e8b3e1e594a02e2f8d7c/jquery-speed-test.html for the raw file).
I’d love to hear of results from other devices.
Its very often about latencies and bandwidth. My concern is much more what people actually *do* with JQ and JQM. I saw UI worst cases generating much more frustration than some 100 millis in parsing.
Thanks a lot for the detailed post. I have always had this question on my mind yet many WordPress themes include jQuery as a default (including the one used on my responsive website). I would very much like to make my website faster and ditching jQuery was one of the way in mind. Yet, with your article, I will turn to minifying other parts first. Thanks!
Great post. It mainly says that whatever you do developing websites, you allways should to improve code efficiency. Anyway, the worst problem with jQuery is the lack of good practices using it.
In the era of quad-core/octa-core mobile devices and 3G/4G networks we are still discussing if JQuery is too big for a mobile website / application.
In a modern web site there are usually being loaded 4 to 7 libraries along with a lot of hand-written poorly optimized JS code. I have seen so many discussions about JQuery that I get the feeling that the library needs a freaking supercomputer in order to run smoothly.
There is no meaning in discussing anymore for a lib alone. The problem with old mobile devices is the same as older versions of IE in web development. At some point, if you want to offer better user experience you need to stop supporting them anymore although including JQuery to whatever code you are writing wont cause this nevertheless.
Great article TJ,
Nice that you kept it is unbiased as you did. Chrome talks about the way they precompile parts of JS to make the virtual machine as fast as it is today. It’s interesting they also cache the parsing of actual scripts. I remember I was blown away last year with the performance of loops in JavaScript. I had to iterate over about 1300 items for some layout logic. I thought it would make the browser hang for seconds, but it took only a couple of milliseconds.
I guess this is another case for optimizing elsewhere, rather than trying to build your things without jQuery, Backbone etc. (Reduce size/number of images and fonts for instance).
mmmm… aren’t we forgetting memory here too? Cause it is not only bandwidth & loading but also memory consumption which is more limited in mobile browsers. Even if it took no time to download and to execute first instance (which from your results it is arguable whether that is the case) the library could have a pattern of memory consumption that makes it unusable on memory limited devices.
Interesting article, thanks!
> If you have performed all these optimizations, and are still experiencing performance issues on mobile devices, then look into removing libraries like jQuery – just make sure you cover your bases first.
Can you explain how you can remove a library like jQuery after developing a mobile app (most like with jQuery Mobile)? I believe it’s too late “then”.
I think a lot of static mobile websites (as opposed to apps) would be better served foregoing most JavaScript and relying on the bare minimum necessary to display the content. That being said, it’s rarely jQuery that’s the performance culprit on mobile. In my experience, it’s almost always either one of the following.
* Too many badly used webfonts
* Images that aren’t optimized for mobile
* Not following basic best practices and combining CSS/JS/Sprites…too many HTTP requests. Etc.
Have you read Ilya Grigorik’s book? Unless I’ve misunderstood something, latency isn’t just about one trip to initiate the download. The download itself, if large enough, will take multiple trips because that’s simply how TCP works – it starts off by downloading a small chunk and then goes back for a bigger one and then a bigger one until the bandwidth cap is reached.
The time that appending JQuery to your core js file adds will therefore depend on the file size of your js file (that has to be downloaded already) and your server settings. With custom settings 28.6kb should add no more than 1 extra trip, though it’s important to note that that trip can happen. But with default settings it could add up to 2 trips if I have the math right.
Hi Tim,
You’re correct; I definitely simplified some of the discussion to get to the points in a reasonable amount of time. In addition to the nuances of TCP, I also didn’t get into connection pooling (browsers use ~6 parallel connections per hostname), geographical proximity, etc—which all can have a substantial effect on page performance. I probably should mentioned that I was glossing over some of this, but I wanted to keep things relatively simple for this article. Thanks for your comment.
Thanks for the great article. I tested your script on a few of my devices as well. As far as I know, this issue was first brought up by Martin Sutherland in 2011 in his blog https://sunpig.com/martin/2011/06/22/jquery-mobile-doubts/ . Since that, I’ve been writing mostly in vanilla Javascript, using jQuery mostly to write shims for old versions of Internet Explorer.
Whereas Moore’s law is at work, even relatively new devices like the original Nexus 7 (2012 quad core 1.3GHz: Chrome 34, Android 4.4.2) take 100-200ms. My opinion is that it would still take a couple of years to say that jQuery doesn’t matter anymore performance-wise.
On the other hand, IE10 has pretty good standards support and so there is less need to use jQuery as a compatibility layer.
The current situation is that due to Moore’s law, there’s less reason not to use jQuery. At the same time, IE10’s standards support means that their is less reason to use jQuery. So there are actually two things happening in the opposite directions, but both of them are actually very welcome for us developers.
Initilization is not an issue anymore. It’s the widget performance due to jQuery/javascript/DOM complexity and webpage formatting that puts newbie programmers off.
That’s a wet-tlhoughl-out answer to a challenging question
I know this is a bit old, but Jquery 2.1.4 (minified) is 84kb at time of writing. Not even close to 23kb. I’d be dropping it entirely, if Foundation didn’t require it.
Nice article and still relevant today. I’m still having arguments 4 years later about whether jQuery is needed and we can all use vanilla JS now (with a few polyfills, npm installs, oh and this code to handle those exceptions with XYZ browser).
I like particularly that we will try and scrimp and shave a couple of javascript libraries to save a couple of hundred milliseconds, but not blink about the fullscreen video playing in the background. It’s the quick wins that make the difference in a website – optimise the easy stuff first then focus on the libraries.
I can program without jQuery if I have to, but I like the confidence that comes with a library like jQuery where I don’t have to think about what browser/device support is required especially with ajax and event handling – jQuery is more than a element selector.
The base line is looking at users that are trying to access your website and how much time you are willing to spend. If you are developing a new website for a client that transacts a million $/£/etc a month (not unrealistic in the hotel sector for example) and the browser you don’t want to support accounts for 0.5% of traffic, are you (or your client) willing to say goodbye that $5000 a month? Is that worth your development costs? That is the real question. If something simple like including jQuery reduces your development (and testing and bug fixing) costs, is that worth it? A customer who can’t use your site has a 100% chance of not buying anything, and it’s the customers that you will never know about that weren’t covered by that code you cut-and-pasted from Stack Overflow.
Wow, what a rant. Sorry.
The summary is: I would be interested in a revisit to the numbers in this blog now to see how technology (and ideology) has changed anything since the original publish.