Regis' Blog

L'informatique, L'amour, Les vaches

Do you really need jQuery ?
September 02, 2014
|
Share this post
| |
Do you really need jQuery ?

In a couple of years, jQuery become the most well-know library for every development in a browser. It easy! You write:

$('#my-id").on('click', function(e) { alert("Hello MyId"); }

And every elements with the ID « my-id » respond to a « onclick » event.

However, that grateful simplicity has a problem: it hides you Javascript. You do not code in Javascript but in jQuery. It’s not the same thing.It’s quite common nowadays to see that horror in a code:

$('#myid').on('hover', function() {
 // Create a jquery Object $("#myid")
 $(this).css('color', 'red');
 // Create the same with different way 
}, function() {
 $(this).css('color', 'black'); // Create the same with different way 
});

A simple CSS could do the same and it’s a lot faster:

#myid:hover { color: red; }

That kind of code is a pure insult to the functionnal side of Javascript. It’s much better to write something like that:

var $myid = $("myid"); // Only one creation  
$myid.on('hover', function() {
 $myid.css('color', 'red'); 
}, function() {
 $myid.css('color', 'back'); 
});

When we are beginning, we must learn Javascript before jQuery. jQuery is just a facilitator when you code. It’s like an ORM. If you don’t know the basics on what it’s based on, you go directly in the wall.

The most jQuery I red can boils down to start the code when the page is ready :

$(document).ready(function() { // A lot of code for callbacks here });

And often, I see a lot of  $(document).ready(function() {}) with its  variant $(function() {}) in the same document. It slows down a lot the document starts.

Why not simply use:

document.addEventListener('DOMContentLoaded', function(){    // plenty of code here }, false);  

It’s faster no ? No jQuery lib to wait. We start immediatly after the DOM is ready.

In HTML and following the  W3C recommandations, there can be have one and only one element identified with an ID. Multiples ID a conception error. So why jQuery returns an object which have the same behaviour than an array?

The natural tendance for every developper is to select elements with a class name. It’s a mistake.  If the designer change the name a all classe name, nothing works correctly. A mistake in the class spelling and everything goes wrong. Using CSS class to select a element is a really bad idea. While we talking about class, if you want to play with them, use classList.

Except if you use XHTML strict you can add another tag attribute. For example  data-action. More, you can specify an action: data-action="sendMessage" a little bit like AngularJS but simplier.

And now, instead of write a vulgar:

$("[data-action]").on('click', function(e) { alert($(this).data('action')); });

You may write:

var elements = document.querySelectorAll('[data-action]');  
for(var i = 0, _len = elements.length; i < _len; i++) {  
    el.onclick = function(e) {
        alert(this.getAttribute('data-action')); 
    }
}

OK, it’s a little bit longuer to write but if you start to write your how library:

function on(els, event, callback) {  
    if (typeof callback === 'function') {
        for(var i = 0, _len = elements.length; i < _len; i++) {
            els[i].onclick = callback;
        }
    }
}

on(document.querySelectorAll('[data-action]'), 'click', function() {  
    alert(this.getAttribute('data-action')); 
});

It’s a strict equivalent and it’s much more faster and less memory greedy.

Fast ? Yes. I wrote this little HTML file:

<!DOCTYPE html>  
<html>  
<head>  
         <title>Test VanillaJS vs jQuery</title>
</head>  
<body>  
         <h1>Test javascript vs jquery</h1>
         <div><span id="resultjquery">...</span> sec.</div>
         <div><span id="resultjs">...</span> sec.</div>
         <div data-action="saveMe"></div>
         <div><button id="go">Test</button></div>
         <script type="application/javascript"
                 src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
         <script type="application/javascript">
            function on(els, event, callback) {
               if (typeof callback === 'function') {
                    for(var i=0, _len = els.length; i < _len; i++) {
                        els[i].onclick = callback;
                    }
                }
            }
            function startApp() {
                document.getElementById('go').onclick = function() {
                    var max = 100000;
                    var end, start = new Date();
                    for (var i=0; i < max; i++) {
                        $('[data-action]').on('click', function() {
                            alert($(this).data('action'));
                        });
                    }
                    end = new Date();
                    $("#resultjquery").text(end - start);
                    start = new Date();
                    for (var i=0; i < max; i++) {
                        on(document.querySelectorAll( '[data-action]'), 'click', function() {
                            alert(this.getAttribute('data-action'));
                        });
                    }
                    end = new Date();
                    document.getElementById('resultjs').textContent = end - start;
                };
            }
            
            // Obligatoire pour jQuery
            $(startApp);
 </script>      

And start it. Verdict ?




Sous Firefox 31

Sous Internet Explorer 11


Sous Chrome 36

Do I need to tell more?

A script in pure JS is up to four times faster (Firefox). Internet Explorer is still slow.

You can test by yourself  here to see how it’s fast on your computer. And why not to create a little function to replace document.getElementById buy getById to not waste time to type.

Why it’s faster?

First, jQuery use its slow  $.eachthat I already talk in a  previous post. Also because jQuery spend a lot of time to create jQuery objects. Objects that are stored in memory. With the Internet Explorer  memory profiler the method with jQuery eat 129 Mbytes of RAM and the pure javascript eat 33 Mbytes.

Don’t forget that for classic website non-2.0 or non-whatever, Internet Explorer is still the king of the marker. Imagine that you use a lazy image loader in pure jQuery… slow madness. And you lose a visitor. And you still ask yourself questions?

Of course it’s less readable, of course, it needs more code to write (not so much), of course an optimization in pure JS is far comple. But think about it. Was the effort has more benefit for you and your users? And why do you really use jQuery. Think about small mobile phones…

The learning curve of Vanilla JS  is a little bit more important than all the magical jQuery. But to be honnest, even if you really  know the DOM architecture (at least I hope for you), but who really knows how javascript interact with the DOM ? Not me. I’ve a lot to learn.

There’s still remaining the problem with animation. When I googling « Pure javascript animation » I found this website that explains how to do animations without jQuery. Everything is based on setInterval. It’s fun,  it’s beauty, it’s javascript.

So, can we stop to use jQuery? Of course yes and it’s not for nothing that UnderscoreJS was build. And be happy that the jQuery developpers are good and everything in this library is highly optimized.  Imagine how slow that kind of library could be slow with bad developpers.

Coding directly in javascript allow you to understand what appends with jQuery. So start to learn pure javascript. It will be hard to do a step back, but even if you write some jQuery code later, you will be better because you will know how it do it.

September 02, 2014
|
Share this post
| |