Hacker News new | ask | show | jobs
by franciscop 3356 days ago
Partially agree. The big problem IMO is momentum in the code. While they do solve many issues, once a browser is not supported anymore the library doesn't get "cleaned up" to reflect it because it just works. So you end up with this stark difference (disclaimer: Umbrella is my own):

- jQuery's addClass(), 35 lines: https://github.com/jquery/jquery/blob/master/src/attributes/...

- Umbrella JS's addClass(), 5 lines: https://github.com/franciscop/umbrella/blob/master/src/plugi...

So the choice is either well-tested libraries that slows your users down so you'll lose a % of them, optimize the hell out of them so you'll "waste"* time, or use a smaller library which is a compromise between them you'll loose a tiny % of users who you don't support, but you have to invest some time to learn it.

It is not black and white, so luckily we have a choice here and different scenarios warrant for different libraries.

* I specify waste since it's probably something you already know and just have to do it; if you're learning it for the first time then it's not wasted at all

2 comments

Speaking of "edge" cases:

el.addClass("btn btn-primary")

works in JQuery and fails in UmbrellaJS

What do you mean?? It seems to work perfectly:

https://jsfiddle.net/sfmdc5yy/

In Umbrella JS, you select elements with u() instead of $() because the APIs are not totally compatible so it avoids confusion for people joining a project that uses the library. Did you find a bug? Is the jsfiddle example not working on your device?

jQuery's addClass 'does more', it can also take a callback:

    $el.addClass((i, existingClass) => (i % 2 == 0) ? 'odd' : '')
Sorry to dissapoint you but Umbrella also takes a callback! It just has more sane (ES6-compatible) arguments :)

u('a').addClass((el, i) => (i % 2 == 0) ? 'odd' : '');

See example: https://jsfiddle.net/r2f87hzk/

Not only that, Umbrella will handle many more class name separations compared to jQuery. All of these (and more) are valid:

u('a').addClass('a,b c', 'd'); // No typo here, four classes added

u('a').addClass(['a'], ['b,c', ['d']]); // Again no typo, 4 classes added

Of course you normally don't use this, but you might have the class list in an array or a comma-separated string or something else which makes it really convenient and it was basically for free as the method is really reusable. See the documentation:

https://umbrellajs.com/documentation#addclass

Heh, props, I'm not disappointed, and yes that's a much better callback! But that is not implemented in the 5 lines of code you linked to is it? :)
Nop, but if you want to be fair jQuery's addClass is also not implemented in those 29 lines of code, it also uses these: each, jQuery.isFunction, getClass and stripAndCollapse.

Umbrella's single eacharg() uses in exchange .each() (which is public-facing, so it really doesn't count) and .args(), which is private but used in MANY places through the code. At 11 lines for args(), I'd say proportionally it'd be 1-3 lines corresponding to addClass. So worst-case scenario it'd be the equivalent to 8 lines exclusive for a much more flexible function with no internal dependencies which is still alot less than jQuery's 29 lines with 3 internal dependencies and 1 external.

* I wrongly counted spaces in jQuery's function while I didn't in Umbrella

Edit: the magic for the size of Umbrella JS is really through heavy code reuse and modern API usage. For this example, el.classList.add(name);

Cannot reply below, reached the limit of HN!

There is a case where jQuery cannot use it since they aim to support SVG in all officially supported browsers, and classList doesn't work properly inside SVG in IE11 (Umbrella doesn't officially support SVG).

I tried refactoring a bit of the code of jQuery, but every thing I touched or changed a lot of tests failed; so I'd have to do a ton of work ignoring the tests and then fix a ton of bugs for a low chance of success (so it was not cost-effective relatively to improving Umbrella).

Yeah I checked out eacharg in your codebase, looks tight. I learnt quite a lot from your code about how jQuery could be structured, nice job!
I can move all of those lines to a new function "addClassHelper" and then ta-da - 1 line.

You can't just exclude other functions like that.

Copy/paste from another answer:

Nop, but if you want to be fair jQuery's addClass is also not implemented in those 29 lines of code, it also uses these: each, jQuery.isFunction, getClass and stripAndCollapse.

Umbrella's single eacharg() uses in exchange .each() (which is public-facing, so it really doesn't count) and .args(), which is private but used in MANY places through the code. At 11 lines for args(), I'd say proportionally it'd be 1-3 lines corresponding to addClass. So worst-case scenario it'd be the equivalent to 8 lines exclusive for a much more flexible function with no internal dependencies which is still alot less than jQuery's 29 lines with 3 internal dependencies and 1 external.

Edit: the magic for the size of Umbrella JS is really through heavy code reuse and modern API usage. For this example, el.classList.add(name);

Doesn't matter what jquery vs umbrella is, if you're wrong from the start then everything you're basing your argument is also misleading. Not saying jQuery doesn't have more lines, but the reasons for it aren't going to be discussed if you use helper functions as your example.