Hacker News new | past | comments | ask | show | jobs | submit login
Cash: An absurdly small jQuery alternative for modern browsers (github.com/kenwheeler)
177 points by tambourine_man on April 1, 2016 | hide | past | favorite | 90 comments



Hey guys, if the selling point of this framework is the size, I would suggest adding the library size to the readme, preferably in the first paragraph or so. That's what I looked for when I loaded the page, and I didn't see it.

cash.min.js is 7.8kb once downloaded, for anyone coming to this thread after me.

Nice work all around, is this comparable with Zepto? What features are missing from Cash that you guys hope to add?


Strange my numbers vary from yours. In their latest commit the minified content in their dist is 9.3kb as is and 3.2kb after gzip

https://github.com/kenwheeler/cash/blob/3cb498ca7c5776b8cadc...

curl https://rawgit.com/kenwheeler/cash/3cb498ca7c5776b8cadcce588... | wc -c # 9282

curl https://rawgit.com/kenwheeler/cash/3cb498ca7c5776b8cadcce588... | gzip | wc -c # 3225


I downloaded their cdn version: https://cdn.jsdelivr.net/cash/1.0.0/cash.min.js



I did not know you could pipe to gzip... That's awesome!


Indeed. I've been very happy with this badge service: https://github.com/ngryman/badge-size


Yesterday I found a good, extremely lightweight (986 bytes uncompressed) alternative, extends Array.prototype:

https://github.com/finom/balalaika/

If that's too much, there's an even more extreme version (379 chars):

https://github.com/finom/bala


I have an even smaller one.

> document.querySelectorAll('.my-selector')


>> is this comparable with Zepto?

Jquery functions Zepto has that Cash does not: ajax, contents, hide/show, map, offset, offsetParent, replaceWith, scrollLeft, scrollTop, size, slice, submit, toggle, unwrap, wrap, wrapAll, wrapInner

Zepto also has some optional plugins that aren't in the default build.


I was confused because I recently discovered this: https://github.com/dthree/cash/#

Finding two unrelated projects with the same name was a kik in the pants.


I guess you could say the kik was the result of a knee jerk reaction.


This looks nice!

Since browser compatibility is one of the primary purposes of jquery, I think it would be helpful if this library's readme said what its browser compatibility is.


You can't say you're "absurdly small" without showing exactly how small you are.


[flagged]


um, I was just yelled at for using a jepordy reference on hackernews! https://news.ycombinator.com/item?id=11401408


Pop culture references lower the quality of discourse. You'll notice the general lack of them on the site. They're not value neutral - they make my life worse. Enough other people here agree that it's a social norm, enforced with words and downvotes. Don't be mad! Just don't make pop culture references.


Most people forget that a huge percentage of English speakers are not brought up and are not living in USA (or other countries where those pop culture reference are relevant).

So we don't get those, it just confuses us. Thanks for clarifying it, @roflcOptic


Lecturing people on the quality of discourse, however...


Titles != comments


I thought this was the one day I could have a sense of juvenile humor... let the downvote onslaught continue!


You can have a juvenile sense of humor! Just... It's not that welcome here. The downvotes aren't a judgement on your character, just a judgement on a joke that's not appropriate in this context. It's cool. You're cool. Everyone's cool. Just don't make jeopardy jokes.


Actually, I expected this to happen and it's not a big deal. I'll save the jokes for Reddit. The interesting thing is I don't think I've ever seen my karma bounce up and down so much every few minutes.


The jeopardy part of the joke is hardly juvenile compared to the penis part of the joke.


No, you made a shitty title, blame yourself.


Sometimes this helper function will do everything that I would want jQuery for:

  var _$ = function(selector){
    var els = document.querySelectorAll(selector);
    return Array.prototype.slice.call(els);
  }
For example:

  _$('span').forEach(function(el){ el.style.color = 'red' });


Also: DOM Level 4[1] adds the iterator protocol to NodeList, so soon you won't need that slice.call line. Simply return the result of querySelectorAll ;-) Works in Chrome canary already IIRC.

1: https://www.w3.org/TR/dom/#interface-nodelist


Why have we had to wait so long though? Who in their right mind thought that it'd be a good idea for NodeList instances to NOT be iterable in the first place? It's almost people writing those specs never use their interfaces for actual work.


I reacted the same way. First I thought 'o yeah, pretty neat' then 'wait, what? it's a collection, but I can't use foreach?' finally arrived at 'ok, I just pull in jQuery again' :)


Smalljs covers everything I need when I don't need anything. Basically is < 80 lines of shorthand for finding elements, iterating over elements and messing with classes. Supports IE9+ and everything else as far as I'm aware.

https://github.com/eatonphil/smalljs


"Everything you need from jQuery, none of the compatibility." :D


9KB vs 83KB - people are really concerned about 74 kilobyte when sites like Medium send megabytes of unnecessary and invisible data to the client, https://binarypassion.net/digital-decadence-6ea59251d64d


Medium is a disaster from a website performance engineering perspective. Why would I make my website slower and heavier just because Medium is slow and heavy?


Medium's approach is unfortunately pretty standard these days.

I didnt say you should add an invisible 1MB image to your site but that a few kilobytes do not make such a difference anymore (particularly when you lose functionality at the same time).


Well, it depends on use cases. If you're optimizing your site for fast initial loads on poor mobile connections, for example, then kilobytes matter. If you find smaller replacements for more than one library, you could end up saving a megabyte. So it's good to have small libraries.


Of course it depends on use cases, but overall there is not much of a point to break up one library into "dozens" of smaller ones, if their eventual total then, in the best case, saves only <10kb or maybe even exceeds the size of the initial one library.

All these jQuery alternatives are nice and such but are not actually bringing much to the table. Yes with each of them you save a few kilobytes but also lose a lot of features. In that case you can go native straight away (querySelectorAll) and save any download in the first place.

And, mobile connections are not that poor anymore as well. Certainly also depends on the region in the world but overall they are getting closer to fixed one every year.

But yes, eventually it depends on the use case and I am sure there are cases where a trimmed down library might be useful. They wont be the common ones though


They're getting better in the normal cases, but they're still relatively unreliable. Plus with roaming charges, code bloat incurs costs for users.

Just a random example: my band's rehearsal space is under ground and has very poor connectivity. Sometimes I still want to look something up down there. In that situation, I really appreciate websites that download minimal amounts of code.

And I think lots of people have equivalent situations, whether it's their country house, their month in rural Thailand, their sailboat, prison, the wifi on the night bus between Cluj-Napoca and Budapest, etc etc etc.

Since I've been annoyed by heavy websites so many times, often in precious or precarious situations, I have a principle of caring about every kilobyte (and caring about offline functionality, too).

As for whether using this library just means you need to import more libraries to cover for jQuery's other features, that's an empirical question that also depends on use case.


But how much do they send when you are using something like ghostery or ublock. Those tools are an absolute necessity today.


These issues of bloat do not even yet include ads.


If everyone bases their own standards on existing bad practices, we won't be around much longer.


If these bad practices are very common though, one should rather try to tackle them before going after 3% of the average size of websites these days.

74 kilobytes might have been a lot a few years ago, these days it is (unfortunately) mostly "noise". Particularly if it is not a real alternative but only a subset of the original functionality.


Cool project, I released a similar library at the beginning of the year [1]. I think that the documentation of cash could be greatly improved and also a website to introduce it would be really nice. While it took a while, it's now the best part of Umbrella in my opinion [2] (feel free to copy any of it as they are largely compatible).

My metrics are aproximately 1:5:7 for lines of code:tests:documentation and I might do the same check later on for jquery, but from reading their source and documentation I think they might be in a similar situation.

[1] http://umbrellajs.com/

[2] http://umbrellajs.com/documentation


Do you really care about how big jquery is when most of people have cached version in their browser already? Maybe people should make petition to ship jquery with browsers and not try to implement next library that will be gone in one year.


That wouldn't work, because jQuery would have multiple versions in the wild, custom builds, forks, etc.. Not only would almost no one have a cache hit because of that, but every time a CDN is down or overloaded, your website is now artificially slow... or broken, which happens far more often than a cache hit.


Even if you have it cached I think that the parse tree is not, so the whole thing must be processed again and again.


That only applies if you serve from a public CDN, which there are reasons to not want to do.

Including jQuery in browsers is kind of a ridiculous idea...


In which ways this is better than Zepto? What features would made me choose cash instead of an already well tested and hardened library which is slightly bigger (around 9kb minified and gz)?


People further up are citing this as ~9kb ungzipped. To me 9kb vs 54kb ungzipped is more than a "slight" difference. It tips it over the threshold where you can just embed it rather than force a separate call. Seems like it would be idea for optimising the "first hit" when a user comes to your site and has nothing cached.


In relative terms, sure.

But if you're going to argue over 5KB perhaps you shouldn't be using JavaScript or CSS. If bandwidth matters that much, plaintext should keep the punters happiest.


I stopped using jQuery years ago. As a consequence I'm writing less Javascript because now I'm rethinking how and what to write.

I never had issues with older browsers because most of those issues are css related. And imho if you need Javascript to fix your layout you are having other issues.


Depends on what you classify as older browsers I guess. I'm in the fortunate position of developing solely for chrome at the moment so I don't have to think about css issues anymore and can use more advanced features.

I still go for jquery for the likes of http requests and css selectors. Which libraries do you use for those tasks now?



Can't speak for huuu, but querySelector() and querySelectorAll() seem to be able to handle most cases. And if you're only developing for Chrome, the built in Fetch API should work for http requests.


And the GitHub polyfill works great on other browsers.


Thanks for the hints everyone. Switching over to the github fetch polyfill to see how it goes.


Or if all you need is $.click() https://github.com/adamjgrant/clickQuery


If speed is a concern, then using a CDN like jsdelivr is a negative. Why an extra lookup for a single 9KB file? There isn't the benefit that jquery has of it having a higher chance of already being cached from that source. It makes no sense, so I'm not sure why your docs recommend it.

Self-host this file, people.


> Self-host this file, people.

At 3.8k gzipped, I'd just inline the minified version...


Inline the css as well and you'll end up with a mobile site that Google loves when crawled. I'm testing such setup and I can pretty much cover everything I need for most cases.


Inlining is no longer good practice with HTTP/2. Multiple small files can be transferred in parallel and cached independently.


A good idea, depending on the type of website.


I stopped using jQuery a good while ago now - it's greatest strength was in flattening differences between browsers. Now there aren't so many of those, I just don't feel the need.

If you haven't tried writing "raw" JS in a while give it a try. You might be surprised.


[You might not need jQuery](http://youmightnotneedjquery.com/) is a good place to start exploring not using jQuery over native modern APIs.


I don't understand libraries like this. Why would I prefer:

    $(element).is(selector)
to the standard:

    element.mathes(selector);


Browser compatibility [1], array handling instead of just single elements, chainability and flexibility come high up in my list. These are important mainly when there are several elements and not just one.

[1] https://github.com/umbrellajs/umbrella/blob/master/src/plugi...


Which are the supported modern browsers?



I would totally use this but its missing ajax.


There are many alternatives:

- Zepto : http://zeptojs.com/

- Umbrella JS (mine): http://umbrellajs.com/

- Nano ajax: https://github.com/yanatan16/nanoajax


Use the new fetch API instead.



Fetch is great and there's a tiny polyfill from GitHub to patch IE and Safari https://github.com/github/fetch


I find fetch very painful to use since the promises don't reject on non-2XX! I use axios instead. This is especially so sad when using async/await :( https://github.com/whatwg/fetch/issues/18

  fetch(url)
    .then((res) => {
      if (res.statusCode < 200 || res.statusCode > 299) {
        throw new Error("Why do I have to write this with every request?");
      }
    });


FWIW, the Response object has the `ok` property [1] as a shorcut. It is equivalent to testing whether status is between 200 and 299.

If it's really that important to you, you can always create your own wrapper around fetch

    function fetch2(uri) {
       return fetch(uri).then( (res) => {
         if (res.ok) {
           return Promise.resolve(res);
         } else {
           return Promise.reject("Request failed with status "+res.status+" ("+res.statusText+")");
         }
       } );
    }

    fetch2('some-url')
      .then( (res) => {
       console.log('Success', res.status, res.statusText);
      })
      .catch( (err) => {
       console.log(err);
      });

  [1]: https://developer.mozilla.org/en-US/docs/Web/API/Response/ok


In IE?


Does the size of a popular js library like jquery matter, really? Most browsers (if you're using one of the CDNs) will have it cached already. And the expiration is something like a year.

Maybe I'm missing something?


The caching is surprisingly bad: http://www.stevesouders.com/blog/2013/03/18/http-archive-jqu...

Facebook did a related study more recently and found that large numbers of users had cold caches (https://code.facebook.com/posts/964122680272229/web-performa...).


There are so many versions of jquery, and so many cdns, that most likely 70-90% of visitors don't have your specified jquery file cached. So yes, I believe it does matter. Jquery isn't something understood to be special to a browser, wherein the http requests would go through a special "see if any jq of the required version is cached" process.


Shouldn't the usage instructions include subresource integrity? I'm sick of having n different CDNs each be able to trivially own most websites.


These libraries appear to be falling back on querySelectorAll. Why use something like this if such facilities exist?


The result of `querySelectorAll()` is a `NodeList` which does not have a funtional iterable interface without additional transformation [0].

`Array.prototype.slice.call(document.querySelectorAll(selector)).forEach(cb)`

vs

`$(selector).each(cb)`

[0] https://developer.mozilla.org/en-US/docs/Web/API/NodeList


So how fast is this compared to jQuery? Has anyone done a jsperf?

I found this one, but it's from 2014 so I'm not sure it's the same Cash.

http://jsperf.com/cash-vs-jquery-add


Nice work and impressive savings.

Sadly, JQuery and its continued success isn't attributed to its efficiencies. It's community support, adoption, and heavy downstream reliance will keep it around as a standard for eternity.


Do any of the github CIs support testing on the browser? Would be nice to have a badge on the github page (given that the project already seems to have tests)


Yes they do with phantomJS [1] for example (see badge working example [2])

[1] http://phantomjs.org/

[2] github.com/umbrellajs/umbrella


i don't see any "badge working" related to browser testing telling me what browsers are supported, what am i missing?


Ohh, you want to know what browsers are supported. Sorry, totally misunderstood it. I thought you just meant a badge showing that it works on the browser (CircleCI in my tests uses PhantomJS) as oposed to some highly syntetic one.

You can always check yourself [1], but of course it's not what you asked.

[1] http://umbrellajs.com/tests


Just saw this :) I asked the original question and your reply was spot on, thanks. Someone else asked a different question.


I don't need JQuery, but Flot chart still depends on JQuery. I searched for a lightweight alternative, tried Zepto which isn't doesn't work correctly with Flot and it uses very bad coding practises (various suggestions even from Mozilla devs were marked as won't fix). I read Cash isn't an compatible alternative either. Hmm, hopefully Flot drops JQuery as requirement, as it's a really good charting library and the only free one that is very comparable to Highcharts.


I switched from Flotjs to c3js a while back and have no regrets. It still needs d3js as a dependency though.


Did you find a solution for its file size? For my side-project I had to choose between c3js and flot, and while flot was 56KB + a few KB for some plugins, c3js + d3js was 300KB. JQuery was already used and thus did not count against flot.

C3js made a good impression otherwise and flot seems to be dead (no activity on https://github.com/flot/flot, or is there a living fork?) making that decision hard.


Unfortunately no. We needed d3 for some other things so it wasn't a concern. C3js development doesn't seem to be very active either - hadn't looked at it in a while -, but it's still a pretty good library.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: