I have embarked on a mission to start using jQuery and JavaScript properly. I'm sad to say that historically I have fallen into the class of developer that makes a lot of really terrible mistakes with jQuery (polluting the global namespace, not caching jQuery selectors, and much more fun stuff - some of which I'm sure I have yet to discover).
The fact of the matter is that jQuery allows people to easily implement some really powerful functionality. However, because everything "just works", performance concerns and best practices immediately take a back seat.
As I've been reading articles on JavaScript and jQuery performance and best practices, I've learned just enough to fully realize how inexperienced I really am. I'm left feeling frustrated because I'm unsure of when I should be using jQuery or just plain JavaScript. The main reason jQuery is so appealing to me is that it takes care of browser compatibility. From what I understand though, there are things you can do with jQuery that you can also do with regular JavaScript that aren't subject to compatibility issues. Basically I'm looking for a guide that explains when using jQuery over regular JavaScript is wise.
A few questions to recap:
Are there parts of jQuery that you shouldn't use due to performance?
What are the parts of jQuery that you should always use to avoid browser inconsistencies?
What are the parts of jQuery that you shouldn't use because there is a reliable and faster way to do the same thing natively in JavaScript?
What are the parts of jQuery that offer multiple ways to do the same thing, with one way being more efficient? For example, the :not() selector versus the .not() method.
I'm looking for existing articles, blog posts, books, videos, etc. I know where the docs are. I read them frequently. I'm hoping for more of an overview that addresses the above issues.
Thanks!
EDIT:
Check out this very similar question: When to use Vanilla JavaScript vs. jQuery?
Wow, I simply cannot believe noone has mentioned storing objects in variables for future use.
Consider this scenario.
You have a complex menu that you're going to write 100 lines of jQuery for.
VERY OFTEN I see something like
$(".menu").fadeIn("slow");
$(".menu li").each(bla bla);
$(".menu li").hover(more bla bla);
if($(".menu").attr('id') == 'menu1') {some hoo ha}
If you're going to reuse an element in jQuery, ALWAYS store it in a variable. It's also common practice to add a dollar sign ($) before the variable name to indicate a jQuery object.
var $menu = $(".menu"); // store once and reuse a million times
var $menu_item = $("li", $menu); // same here
$menu.fadeIn("slow");
$menu_item.each(bla bla);
$menu_item.hover(more bla bla);
if($menu.attr('id') == 'menu1') {some hoo ha}
I definitely say
use the event model as it abstracts the differences across browsers and also provides a means to raise your own custom events too.
don't use .each() or $.each() unneccessarily. Sometimes it can help as it introduces a closure, but often a simple loop will suffice.
the only way to know whether a complicated selector string or a bunch of chained function calls is going to be faster is to benchmark all approaches.
use event delegation when binding the same event handler to more than three elements (I'll see if I can dig out the resource for more than three elements, I seem to remember an article that benchmarked direct binding versus delegation on a number of different factors and found more than three to be the magic numbers).
Above all else, don't worry about performance unless it's a problem. 200ms compared to 300ms, who'll know the difference? 200ms compared to 1000ms, maybe time to look at optimizing something :)
be as specific as possible with your selectors and help those poor older versions of IE out.
Several of your questions focus on performance.
As a rule, jQuery cannot possibly perform better than the underlying native Javascript. jQuery does not interact directly with the browser or operating system; it's just providing a wrapper around built-in Javascript functions. So at an absolute minimum calling a jQuery function incurs the overhead of an extra function call.
In many cases, jQuery is indeed doing quite a bit of heavy lifting in order to produce a result, when hand-written "pure" Javascript might be able to avoid that work.
The point of the framework is to make the programmer's life easier, and historically everything that's ever made programmers' lives easier cost performance. Hand-written machine language is almost universally more efficient than the best compiled code ever assembled.
So the best answer to your questions about performance is: don't worry about it. If you ever encounter a performance problem, then consider jQuery as one possible target for optimization.
As far as browser inconsistencies, one of the major purposes of the framework is to avoid them entirely. There have been bugs historically where certain features didn't work in one browser or another, but these were bugs specific to a particular version of the library. So avoiding them entirely wouldn't be quite the right solution. And trying to identify them here (rather than jQuery's own bug reports) would make this discussion almost instantly out of date.
Nowadays, the primary rule of thumb with javascript is that it has wicked-fast execution time (on non-ie modern browsers), but dom access/manipulation is crazy slow. The faster the JS runtimes get, the more the DOM becomes the bottleneck.
As a rule, you shouldn't really overly worry about performance until it becomes an issue, since most code doesn't need to be fast, and you usually don't know where the problems will be until you test it. That being said, try to minimize dom interaction wherever you can.
as a side note, idiomatic jquery is using javascript the right way. Favor composing functions over OOP, use closures for encapsulation, don't mix javascript handlers (or heaven forbid, script blocks) in your html, and treat objects as property bags that you can attach or detach things to at will.
I'm no expert but I learnt a couple of things.
Don't abuse HTML attributes, that means don't store your intended roll-over images in a rel/rev, use a background image instead. This also helps with the performance of roll overs in IE, as IE doesn't like it when you are changing the src attribute on the fly.
Also hover-intent is very useful to have instead of just using .hover :)
My two cents: do not underestimate the power of the jQuery team (Resig an Co.)---their intent is not to lead you easily into performance gotchas. That being said, here's one: when you use a selector (which is the query in jQuery), do insure to use [context].
So let's say you have a table with 243 rows---and you have not tagged each tr with an id (because you are cool). So you click, say, a button in a row with an event. The event for the button needs to search the current row for a select widget. The innards of the click() event might have these lines:
var tr = $(this).closest('tr'); //where $(this) is your button
$('td select', tr).css('color', 'red');
So the last line there does a search for select elements in the context of a table row (tr). This search means to be faster than searching the entire table (or the entire page) for an id or something similar.
What is also implied here is that I'm putting my trust in the jQuery team that their implementation of the jQuery.closest() method is fast and efficient. So far, I've no reason not to have this trust.
Related
Using jQuery, if I am writing code like this
$('blah').doSomething();
//bunch of code
$('blah').doSomethingElse();
//bunch of code
$('blah').doOtherStuff();
Is a new jQuery object being created each time I say $('blah') ?
If so, would it reduce object creation overhead to do something like this instead:
var blah = $('blah');
blah.doSomething();
//bunch of code
blah.doSomethingElse();
//bunch of code
blah.doOtherStuff();
Make sense?
Absolutely correct!
Why Cache
Another benefit of caching is code maintainability. If the selector is only in one place, changing it only needs to be done in one place. Trust me that makes life easier when maintaining code.
Chain
Although you can go one step further (where relevant), and chain your calls:
$('blah')
.doSomething()
.doSomethingElse()
.doOtherStuff();
This is slightly better for 2 reasons. Firstly, you're not using the extra variable, so you save a tiny amount of memory. Secondly, the language doesn't perform lookups for each identifier use, so it's quicker.
So, why do people still [over]use $()
One reason people use lots of $() is because they don't know any better.
Another reason is because element selection used to be slower. But as with most things in the browser, querying objects with selectors is fast being optimised (document.querySelectorAll), which means it's not such a big deal to cache or not to cache, so maybe with that in mind they allow themselves not to cache.
Finally, there are benchmarks hanging around (one two from a quick google) that try to claim that it doesn't matter or is maybe even faster not to cache. The problem with most of these benchmarks and why I suggest you be very wary about drawing conclusions from them, is that the DOM in the example is not real-world; it's overly simplistic. Secondly, the selectors are simplistic as well. So of course querying will be lightning fast and caching won't make a big difference, but I don't find them at all conclusive.
That said, if your example is similar to those of the benchmarks, then maybe you can draw your own circumstantial conclusions, and caching might just be a nuisance.
I'm a very beginner to jQuery, and I'm having some basic questions:
Is it advisable to use jQuery whenever it is possible to replace something by using it? For example, is it prudent to bind all events to elements using it, instead of through HTML?
Is it better to host the jQuery .js file and all other relevant files (like JQuery UI) myself, or is it perhaps a better choice to use Google's link (they seem to host it for others too)?
When it comes to executing a script when the page is done loading, what way is preferred?
$(document).ready(function() {})
$(function() {})
$().ready(function() {})
They seem to all do the same thing, but what is the preferred way of scripting?
Yes. This way your JS is cleanly separated from your html. You can look at your file and in one glance, see how it is affecting your HTML. If it was embedded in the HTML, you would have to look for onClick, onLoad etc and it can get pretty messy for large applications.
Client browsers will cache files, so if you use the google version of JQuery, it will not have to download it off your server. Saving you bandwidth.
$(document).ready(function() {}) Is the preferred choice. $(function() {}) Just defines the block for execution, it will only execute after the page is ready if it is the last thing on the page to get executed.
1.) Yes and No. It is considered best practice to bind events unobtrusive regardless of using jQuery or not (this means, strictly separate javascript, html and any other language). Since jQuery allows to easily bind events it's a better way to use inline-handlers.
2.) You should use a CDN (like google) to deliver static files like jQuery for Caching purposes + they have a huge server network which may even be faster than your own host.
3.) I would stick to the first two calls. Anyway, basically they all will do it, but the best readability probably has $(document).ready(function() {});
1) Keep all your event binding in your script. This makes it easy to change later. You'll also appreciate having a single place to look for all event-related logic.
2) This has been answered very well already.
3) I prefer #2 for its brevity, but really the ideal way to do it is like this:
jQuery(function($) {
// Your code using failsafe $ alias here...
});
That avoid conflicts if you are using other frameworks that define $.
1: no this is completely up to you. generally jQuery incurs a performance penalty, because it is an extra layer of abstraction. Only use it, if you feel it helps you do your job easier. However, unless you truely need to optimize for performance the benefit in using it will far outway the cost. jQuery gives you tried and tested crossbrowser compatibility, which, if you wish to cater to all the different browsers out there, can be a costly affair to implement yourself.
2: Use Googles version: that way there is a chance that your users already have it cached and don't need to load it again from your site.
3: 2nd option, the shortcut is very widely used to a point where i'd say it's prefered even though 1st option is nice and specific. I'd never use 3rd option
For the 3d point, none of them. it is generally recommended, for performance reasons, to place your scripts just before the closing </body> tag. Thus you will not need to wait for the ready event: at this stage, the page is already loaded.
Check Jquery Cookbox (O'Reilly), Chapter 1.2: Executing jQuery/JavaScript Coded Ater DOM Has Loaded but Before Complete Page Load (that book is a must read all in all)
To have a quick idea about this technique, check Move jQuery to the end of body tag? (there are many other posts on SO about this subject)
I personally don't subscribe to the "cleanly separate JS from HTML" philosophy. I rarely see real world use cases where that has any benefit. Separating HTML from JS often leads to buttons that say "click here to do X" in the HTML but do nothing unless the appropriate javascript is with them. Kind of misses the point.
With the case of jQuery and events... I find it much easier to debug an app if I can inspect an HTML button in firebug and see what that button does (by looking at the onclick attribute).
Using the google version can aid with caching, but don't link directly to jquery.com. We did that here once and they went down, took us with them.
This isn't about a side-by-side technical comparison, rather about how to "think in jQuery" versus "thinking in Prototype".
I've used Prototype heavily for several years, and jQuery somewhat less heavily until about a year ago when I started doing a lot with it.
With Prototype, I can write some fairly elegant code; my boss once reviewed a large amount of my code and remarked that it was the first Javascript he'd ever found a pleasure to read. I understand - and understood pretty much from the beginning - almost instinctively what Prototype's trying to do, and know how to work with it.
My jQuery code is a lot more, how can I put this, "workmanlike". I feel as if I'm fighting jQuery every step of the way. I have to (try to) force myself to stick with it and not drop down into "native" JS, where I know I could bash out clean cross-browser code more quickly. Working with it more makes it more, not less, frustrating.
It's not (or at least not entirely) a lack of familiarity with the functions available. I'll often know I need to use a given function, but the way in which it's used seems truly bizarre. That's usually a sign that I'm coming at something entirely the wrong way.
The more I think about this, the more I think I'm trying to use jQuery in a Prototype way.
There has to be some blinding flash of light that hasn't happened to me yet. Especially if you've worked a lot with both, what do you find are the most fundamental differences in approach? How do you need to adjust your mindset when switching from one to the other?
Don't be afraid to state the blindingly obvious, because it may just be that blinding flash...
I went through that transformation. The main thing to tell yourself over and over again is that jQuery is, first and foremost, about making DOM manipulation easier and more cross-platform safe. There's no "reduce" (Prototype used to call it "inject", I think) in jQuery. Why? Because the maintainers don't consider it important for the primary task of jQuery.
Thus, the way that Prototype's base object extensions creep into your coding style as you write your code to get your own work done, well, that pretty much doesn't happen in plain ol' jQuery. (See, however, the lovely Underscore.js library for a way to get some of that functionality in a jQuery-friendly way.)
For me, that's made it easier to figure out how to build on jQuery. It's just a different sort of thing. Now, jQuery is very solid and it really does make DOM manipulation and HTML wrangling a lot nicer than what you get from plain Javascript. (I think Prototype does an OK job too, but jQuery is super-focused on the problem.)
The best advice i can give is "Embrace this". In jQ, you're nearly always talking about iterating over a set that is wrapped in the jQuery object. Invoking one of the set's methods performs the method on all the elements of the set, whether its 1 or 100. That method is always going to return the same instance of the set (aside from accessors that get a property). In the context of the interation this is the value of the item in that set youre manipulating - usually the raw DOM Element, but it could be the value of an object property or array item.
Why do you need to think differently? Instead of adapting your style to every framework or language that comes along, why not adapt the framework or language itself to your liking. Then all you'll have to do is be open to the idea that there might be better ways of writing or structuring code than you already know, and when those ways present themselves, objectively analyze and then include them in your repository.
The choice is almost never all or nothing. Both frameworks have great offerings, and you can use techniques from both in harmony for building a great application.
I've seen alot of jQuery implementations of existent JavaScript functions that merely wrap the JavaScript code in a jQuery wrapper and don't actually rely on any of jQuery's base for their operation.
What are the benefits of using Javascript as a jQuery plugin?
If there are none is there a speed loss to use a jQuery plugin that could have easily been implemented outside the wrapper just as well?
Many thanks in advance (just trying to learn something here).
Updated with example:
http://plugins.jquery.com/project/base64
was originally
http://www.webtoolkit.info/javascript-base64.html
Much of jQuery is just a clever wrapper around existing JavaScript functions. $('#some-element') is perhaps a little easier to type than document.getElementById('some-element') but is otherwise not much different.
(I exaggerate, but only slightly.)
The main utility of jQuery is being able to combine together its various components. If I can select elements with a jQuery selector and then perform some action on those elements directly through a jQuery function, that's preferable to having to extract the underlying DOM elements and manipulate them manually, for example.
So it really depends on what functions you're seeing get wrapped. Some of them might very well add no value, and the authors are simply accustomed to everything being in jQuery. (We definitely see that phenomenon on StackOverflow — people who can't find a standard JavaScript function simply because it's not in the jQuery documentation). In other cases, there might be some hidden benefit even if the wrapper does little if anything to modify the underlying function's behavior.
There's also a lot of momentum around jQuery, and general trust. Including arbitrary javascript in your code base may not be as 'acceptable' to higher-up-types as including a new jQuery plugin.
So it may be a mistaken perception, but by being a jQuery plugin, a library benefits by being associated with high quality code.
IMHO the only reason to create a plugin is to execute some functionality against a selector ie a set of selected elements eg
$('.myelements').someFunction();
If your plugin ends up looking like this (case in point the newly released Microsoft Globalisation plugin)
$.doSomeStuff();
then there isnt much benefit that couldn't be gained from using a closure. However a lot of developers dont understand closures and namespaces in javascript, and by following a plugin development templatethey can get the benefit without fully understanding the pattern.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Javascript (jQuery) performance measurement and best practices (not load time)
Good ways to improve jQuery selector performance?
Hello,
This might be a bit of a vague or general question, but I figure it might be able to serve as a good resource for other jQuery-ers.
I'm interested in common causes of slow running jQuery and how to optimize these cases.
We have a good amount of jQuery/JavaScript performing actions on our page... and performance can really suffer with a large number off elements.
What are some obvious performance pitfalls you know of with jQuery? What are some general optimizations a jQuery-er can do to squeeze every last bit of performance out of his/her scripts?
One example: a developer may use a selector to access an element that is slower than some other way.
Thanks
Not caching queries
I see something like this way too often (exaggerated to make a point):
$("div#container ul > li a.myselector").imagine();
$("div#container ul > li a.myselector").this();
$("div#container ul > li a.myselector").code();
$("div#container ul > li a.myselector").in();
$("div#container ul > li a.myselector").a();
$("div#container ul > li a.myselector").loop();
Binding events to all rows in a table...when the table has 1000+ rows
This smells bad:
$("table tr").click(function(){}).hover(function(){},function(){});
or worse (function declarations inside a loop [yes, each() is a loop]):
$("table tr").each(function(){
$(this).click(function(){});
$(this).hover(function(){},function(){});
});
instead you can do:
$("table").delegate("click","tr",function(){}); //etc
jQuery performance usually comes down to selector performance. The following are guidelines I provide to the team Im currently working with:
Cache your selectors
Try use Id's instead of classes eg $('#myDiv')
Qualify your classes with the type of element eg $('div.content')
2019 edit:
Modern browsers expose a very efficient getElementsByClassName() method that returns the elements having a given class. As seen in this answer.
So in modern browsers, $('.content') is faster than $('div.content')
$('.content') // 925,600 ops/s ±0.9%
$('div.content') // 548,302 ops/s ±1.2% --- 40.76% slower
Provide a scope for your selector , especially if nested inside another selector eg $('div.content', this)
Use chaining of selected elements eg $('div.content').css('display', 'block').show();
There are also non-selector based optimisations such as
Upgrade to the latest version of jQuery! Each release seems to bring more performance enhancements
Make sure you are using the minified
version of jQuery.
Minify your own jQuery code (Google Closure compiler is the best imho)
Beware of poorly written third party plug-ins
Move your jQuery script tags (including jQuery) to the bottom of the page - this gives a faster page load time.
Understand the difference between statically bound events and live events (using the live or delegate functions)
When appending to the DOM, try group all the code into one insert instead of lots of little appends
Also, be sure to find out about javascript performance optimisations, as these two things go hand in hand and can make a huge difference.
In some cases, an overuse of jQuery itself can be cause for slower performance. For example, $('#selector').html(<VALUE>) has more overhead than document.getElementById('selector').innerHTML = <VALUE>;
Usually the biggest single thing you can do is improve your DOM selectors to limit the amount of querying/walk-throughs when carrying out actions. I'd suggest googling "improve jquery performance" for the tons of blog articles on the topic since the question is vague. Here are two that cover the points I mostly think about when doing my own jquery coding:
http://jonraasch.com/blog/5-performance-tuning-tricks-for-jquery
http://hungred.com/useful-information/jquery-optimization-tips-and-tricks/
The most obvious performance bottleneck is none-cached queries:
$('.selector').hide();
// and later
$('.selector').css("height", "23px");
// and even later still
$('.selector').attr("src", "http://blah.com");
This is a very primitive example but matching many elements and looping at the same time could drastically reduce performance, especially on browsers that don't support querySelectorAll or where using complex selectors that aren't supported by the browser (thus requiring use of Sizzle to do all the DOM iteration). Storing the matched collection in a variable is the smart thing to do:
var $sel = $(".selector");
$sel.hide();
// and later
$sel.css("height", "23px");
// and even later still
$sel.attr("src", "http://blah.com");
Well jQuery performance is synonymous with Javascript performance. There are lots of articles about this. Check out some tips here
There are also some good slides on this by Nicolas Zakas (Yahoo! Front End Engineer and author of Javascript Performance books) here
Here are the important tips:
Limit DOM Manipulation and DOM
Parsing - parse by ID when you can
because it is fastest. Parsing by
Class is way slower.
Limit what you do inside Loops
Check Variable Scope and Closures and
use Local Variables
Check your Data Access Methods - it
is best to access data from Object
Literals, or a local variable
The deeper the property is within an
object, the longer it takes to access