DEV Community

loading...

Discussion on: jQuery: the king is dead

jmau111 profile image
Julien Maury Author

88 kb seems huge, don't you think? People use preact to avoid loading 30kb of React, for example.

Thread Thread
inhuofficial profile image
InHuOfficial • Edited

88 kb is more than an entire page on my website so it is quite significant (I presume that is before gzipping as I don't remember it being that large).

But it isn't really the page weight where it is an issue (as most sites are 1-2MB so 88kb in the scheme of things isn't massive), it is the CPU time needed to parse and compile 88kb of JavaScript.

Not an issue for a decent laptop or PC, a whole other ball game for a £200 mid-tier phone running at 1.5Ghz!

That is why jQuery is dying....sadly it is being replaced with 100+kb of React for static websites so it isn't like we have learned (React is great for complex applications, but if you are using it on a brochure website you are using a sledge hammer to put in a tack (a tiny nail)!)

If you like jQuery style syntax (as I do), here is 4kb raw, less than 2kb gzipped and compressed of JS I use for common jQuery style selection, event listeners, ajax etc.

It gives you:
.on, .off, .each, .parent, .first, addClass, hasClass, removeClass, toggleClass, .text, .html, .parent, .first, .attr and .ajax.

Can occasionally get upset with complex selectors but it works for 95% of stuff and I just fall back to vanilla when it doesn't like something.

Not to be used in production on large sites, fine for personal / side projects though!

!function (b, c, d, e, f) {

    f = b['add' + e]

    function i(a, d, i) {
        for (d = (a && a.nodeType ? [a] : '' + a === a ? b.querySelectorAll(a) : c), i = d.length; i--; c.unshift.call(this, d[i]))
            ;
    }

    $ = function (a) {
        return /^f/.test(typeof a) ? /in/.test(b.readyState) ? setTimeout(function () {
            $(a);
        }, 9) : a() : new i(a);
    };

    $[d] = i[d] = {
        on: function (a, b) {
            return this.each(function (c) {
                f ? c['add' + e](a, b, false) : c.attachEvent('on' + a, b)
            })
        },
        off: function (a, b) {
            return this.each(function (c) {
                f ? c['remove' + e](a, b) : c.detachEvent('on' + a, b)
            })
        },
        each: function (a, b) {
            for (var c = this, d = 0, e = c.length; d < e; ++d) {
                a.call(b || c[d], c[d], d, c)
            }
            return c
        },
        splice: c.splice
    }
}(document, [], 'prototype', 'EventListener');
$.prototype.find = function (selector) {
    return $(selector, this);
};
$.prototype.parent = function () {
    return (this.length == 1) ? $(this[0].parentNode) : [];
};
$.prototype.first = function () {
    return $(this[0]);
};
$.prototype.focus = function () {
    return this[0].focus();
};
var props = ['add', 'remove', 'toggle', 'has'],
        maps = ['add', 'remove', 'toggle', 'contains'];
props.forEach(function (prop, index) {
    $.prototype[prop + 'Class'] = function (a) {
        return this.each(function (b) {
            if (a) {
                b.classList[maps[index]](a);
            }
        });
    };
});
$.prototype.css = function (a, b) {
    if (typeof (a) === 'object') {
        for (var prop in a) {
            this.each(function (c) {
                c.style[prop] = a[prop];
            });
        }
        return this;
    } else {

        return b === []._ ? this[0].style[a] : this.each(function (c) {
            console.log(a, b, c);
            c.style[a] = b;
        });
    }
};
$.prototype.text = function (a) {
    console.log(a);
    return a === []._ ? this[0].textContent : this.each(function (b) {
        b.textContent = a;
    });
};
$.prototype.html = function (a) {
    return a === []._ ? this[0].innerHTML : this.each(function (b) {
        b.innerHTML = a;
    });
};
$.prototype.attr = function (a, b) {
    return b === []._ ? this[0].getAttribute(a) : this.each(function (c) {
        c.setAttribute(a, b);
    });
};
$.param = function (obj, prefix) {
    var str = [];
    for (var p in obj) {
        var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
        str.push(typeof v == "object" ? $.param(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return str.join("&");
};
$.prototype.append = function (a) {
    return this.each(function (b) {
        b.appendChild(a[0]);
    });
};
$.ajax = function (a, b, c, d) {
    var xhr = new XMLHttpRequest();
    // 1 == post, 0 == get
    var type = (typeof (b) === 'object') ? 1 : 0;
    var gp = ['GET', 'POST'];
    xhr.open(gp[type], a, true);
    xhr.responseType = (typeof (c) === 'string') ? c : '';
    var cb = (!type) ? b : c;
    xhr.onerror = function () {
        cb(this, true);
    };
    xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
            if (this.status >= 200 && this.status < 400) {
                cb(this.response, false);
            } else {
                cb(this, true);
            }
        }
    };
    if (type) {
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        xhr.send($.param(b));
    } else {
        xhr.send();
    }
    xhr = null;
};

Enter fullscreen mode Exit fullscreen mode
Thread Thread
jmau111 profile image
Julien Maury Author

I would certainly agree with you, jQuery syntax is so convenient, nice minilib by the way, thanks for sharing ;)

It is also why I choose Hugo in 2021, as much as I love React and while it still brings great value for app with many interactions, that's too much for a blog or some small project.

Fewer bytes to process, better perf for sure.

Thread Thread
mariocalin profile image
Mario

I am pretty sure that 88 KB nowadays means nothing in any common device.

Thread Thread
inhuofficial profile image
InHuOfficial

It is nothing in a lot of devices, I would say 75% will parse and execute in under 50ms.

But that other 25%, the phones with little power may take 100+ms just to parse and execute jQuery.

And that is just jQuery without it doing anything.

Come May when the web vitals update rolls out that extra few ms could add up to thousands for a mid sized firm in slight position losses on Google.

Personal project with 0 traffic..jQuery away. E-commerce site doing 500k+ a year, optimise the hell out of it and dropping jQuery is a definite quick win!

Thread Thread
jmau111 profile image
Julien Maury Author

Not any.

There are many cheap devices out there as @inhuofficial said, but I also don't like having a "fat footprint", especially when it does not take unreasonable extra time to code it in vanilla js.

This approach often brings me great rewards, especially when you need to scale, but not only.

As I said in the post, the world is not black and white. If you absolutely need a framework to speed up dev, there are much better alternatives in 2021, IMHO.

Thread Thread
Sloan, the sloth mascot
Comment deleted
oenonono profile image
Junk • Edited

Yes, yes, yes. Thank you.

Another important nuance is that the general characteristics of an app using jQuery versus React are likely to be different. Most people using jQuery are server side rendering and progressively enhancing, which makes the comparison of 88kb and 30kb quite different in context. That 88kb may not block rendering or interactivity and it may be 88kb of only 500kb of JS, while that 30kb is most likely a CSR-only SPA and 30kb of 2MB of JS.

Generalizations, yes, but for valid reasons.

Thread Thread
aghost7 profile image
Jonathan Boudreau

What about developing countries? I think it still matters for certain markets.

Thread Thread
jmau111 profile image
Julien Maury Author

A significant part of the world is often neglected, for sure, old android phones can tell.

Thread Thread
oenonono profile image
Junk

What do you mean? I guess as the thread gets deeper it loses some specificity in replies, so assuming you're talking to me...

Do you mean does jQuery's size matter in developing countries? Yes, of course, it matters. But you may not understand the details of what I'm saying if you don't know why it doesn't matter as much in the "progressive enhancement" scenario I'm referring to.

In a "progressive enhancement" scenario jQuery doesn't block anything important before it loads. HTML is server-side rendered (SSR) and jQuery doesn't block either rendering or interaction. While jQuery is loading, the end user can view content and click on links and navigate. If jQuery doesn't load, some functionality and some widgets may not be available, but there will be a worthwhile and usable experience.

If someone adopted jQuery today and used it and dozens of direct and hundreds of transitive dependencies to build a single page application (SPA) that was client-side rendered (CSR) only, it would perform just as poorly as a similarly-architected and similarly-implemented React app. But it wouldn't be because it's 88kb compared to React's 30kb (last I checked it's more than that, these must be gzipped sizes which are only relevant to network transfer time, the parse time correlates more with unzipped size where React + React DOM are >120kb, not to mention the CPU and memory intensiveness of a React app).

It's not usually any single library/framework that makes or breaks performance. It's the architecture and the aggregate. Ironically, React wasn't originally designed, implemented, or used by its authors to build CSR-only SPAs. It was used more like progressively-enhanced jQuery and it's my understanding that is still how it's used on critical Facebook properties. (That may have changed since I last checked in.)

But libraries and frameworks often have architectures that are typically associated with them in their ecosystems. There is plenty of diversity, but still. If you guess that any random React app is a CSR-only SPA, you'll probably be right. If you guess that any random jQuery-using site isn't, you'll probably be right. It was a combination of factors that led to the problems we now see. React + npm + bundlers + CSR-only + SPAs + FAANG cargo-culting SaaS monoculture led us here.

But it's not only "old" Android phones in "developing" countries impacted. It impacts me, a well-paid engineer in a "developed" country, when I'm walking around San Francisco on my current-generation Android phone. In which circumstances a React web app is often painful, if begrudgingly possible, to use (if I am patient). It impacts my users in Idaho with their couple-generations-behind, refurbished iPhones driving country roads with spotty internet. It impacts my uncle, who has an old and occasionally used PC for paying bills. It impacts my mother, who is a technophobe and only uses her Kindle that she has become comfortable with.

On the web, not everyone is like us, and there are far more people not like us than most of the engineers I talk to acknowledge. Not everyone has the wealth, the privilege, the leisure, the connectivity, or the new and powerful machine. The people around us at work aren't the average, typical user. The people at the startup a few streets over who our UX researchers interview are conveniently in proximity, but aren't the average, typical user either.

And no one says when interviewed, "I hope this will work when I'm running late and on the train." But they do wish that when the situation arises. We're capable of delivering it technically, we just don't and that's very sad.

xkcd.com/1367/

Thread Thread
jmau111 profile image
Julien Maury Author

Thanks for your detailed comments.

But it's not only "old" Android phones in "developing" countries impacted.

Never said "developing countries". Said "a significant part of the world", that would include all people with old phones.

However, if you want to take that example, some countries have very poor networks, limited bandwidth. The internet is reaaally expensive. Loading external libraries can have a high cost.

I'm not comfortable with the idea of loading all those bytes for nothing, and I remember that web vitals have a significant impact now on SEO.

PS: I like this read. I don't read it at face value, it's just interesting IMHO.

Thread Thread
aghost7 profile image
Jonathan Boudreau

From what I've read its actually even worse than that. In developing countries some phones can have a hard time parsing the libraries. This is why browsers such as UC browser are popular in places like Africa.

Thread Thread
oenonono profile image
Junk

That's a great article, yep!

Much as I am always ready to be on one about using less JS, sometimes it's not entirely for nothing. PWA app shells are an example of optimizing for first time UX in a scenario where offline support is needed. Building an offline app and/or something like an image editor does have different requirements and trade-offs and a good reason to go heavier on script and care less about startup cost.

Thread Thread
jmau111 profile image
Julien Maury Author

I agree with you, and it is something that I've discovered at work. The implementation must sometimes be different, and using CDN for example is not a good solution, especially in countries that do not have the infrastructure for that.

Forem Open with the Forem app