According to many of the tests on jsperf.com, jQuery is slow. Really slow. The jQuery team gets bug reports from web citizens who've discovered these egregious flaws via jsperf and want them fixed. Now, jsperf.com can be a great tool when used knowledgeably, but its results can also be misinterpreted and abused. For example:
Why doesn't jQuery use DOM classList for methods like .addClass()?
There are at least three good reasons.
- It doesn't make any practical performance difference given its frequency of use.
- It complicates code paths, since
classListisn't supported everywhere.
- It makes jQuery bigger, which makes it load slower for everyone, every time.
classListis much faster! How can you say that?
- The jQuery case works correctly for zero, one, or more elements in its collection. The
classListcase only works with one element selected, and will throw an error if no elements are selected.
- The jQuery case can add or remove multiple classes at once. The pure DOM case will not, since
classListdoes not support it.
- The jQuery case runs on browsers that don't support
classList. This includes the Android 2.3 browser (about 25 percent of all Android) and Internet Explorer before version 10 (about 36 percent of all IE).
classoperations, any attempt to use
classListinside jQuery would still need supporting code around it to deal with older browsers plus the cases of multiple elements and multiple classes. That's more code to be downloaded and parsed each time any browser (including those without
classList) loads a page with jQuery. That starts our space-vs-speed performance tradeoff in a hole that we may never dig out of.
classListadvocate might say, "What if I call this code 1,000 times? Now it's taking 12 milliseconds and eating up most of my frame budget!" Typical real-life code would only manipulate the
After just about any
classchange, the browser needs to recalculate styles and redraw at least part of the page. The cost of those operations will usually outweigh the cost of manipulating the
classproperty, but they're not reflected in jsperf because the rendering engine runs on the same thread as the benchmark. The browser doesn't get a chance to re-render the page until after the timed block of code is complete. But even if it did, the trivial size of this document (just one test element) isn't typical of the workload the browser faces in recalculating styles and layouts.
In fringe cases where jQuery is too slow, you're in luck! jQuery doesn't place "Do Not Enter" signs around DOM methods. You can freely mix many DOM methods with jQuery. That's why event handlers have the target DOM element, not a jQuery collection, as their
thiskeyword. In your checkbox event handler, you're free to use
$(this).prop("checked")-- and you should, it's shorter! Go ahead and use
this.classList.add()directly if you don't care about old Android or old IE and have strong emotions about wasting microseconds.
Knuth said, "We should forget about small efficiencies, say about 97 percent of the time: premature optimization is the root of all evil." The
classListcase is one of those small efficiencies that makes little difference to the performance of real code. There is no good reason for jQuery to blindly optimize exclusively for the CPU performance dimension that jsperf measures, particularly when it has a cost in code size and complexity. But the programmer's mentality often won't let go of these issues because, darn it, jQuery should use the native API regardless.