What browsers do you need to support?
If you have to support IE8 I do not recommend that you ditch jQuery. IE8 doesn’t have many of the fundamentals to be considered “modern” and work without significant polyfilling in a way that modern Webkit browsers do. The Guardian uses a simple script to detect whether your browser is modern:
isModernBrowser:('querySelector'in document&&'addEventListener'in window&&'localStorage'in window&&'sessionStorage'in window&&'bind'in Function&&(('XMLHttpRequest'in window&&'withCredentials'in new XMLHttpRequest())||'XDomainRequest'in window))
This checks for the following functions:
- Local Storage and Session Storage
- Standards-based AJAX
- CORS (Cross-origin resource scripting)
If you’re modern, The Guardian will give you everything. If not, you get a gracefully degraded experience. IE8 will fail all but the local storage part of that test, and polyfilling that much code will negate all the benefits of removing jQuery.
With some browsers, it is possible to polyfill small parts of this functionality and still remove jQuery. For example, Yell supports iOS 4 and above, which doesn’t have Function.bind, Android 2.3 doesn’t support Element.ClassList or SVG, and IE10 doesn’t support Element.data. We chose to polyfill these functions for the older browsers, but not SVG or Element.data, as these can be resolved by other techniques or just coding differently.
In the end, it’s your choice what browsers you support, but you have to be careful. There is a complete list of ECMAScript 5 functions and browsers that support them on Kangax’s Github page (as well as pages for ES6 and ES7 if you’re interested) that is incredible for helping you make this decision.
Plugins & Third-party code
There will be plenty of times that you will be able to find alternatives to plugins that work without jQuery. The simple way to find them is to use Google, Github, StackOverflow and Twitter to search for alternatives. I wish that there was a repository that told you the good alternatives for common jQuery plugins – but there isn’t one (note to self: do this). This can be laborious, and involve a lot of trial and error to find alternatives that match the feature set you’re looking for.
I went through this same process with my team for yell.com’s mobile site. Luckily, there was only one plugin that we needed to keep, Photoswipe – a cool plugin that creates a touch-friendly lightbox from a list of images. We looked high and low for vanilla JS alternatives that 1. were mobile-friendly, and 2. worked on Windows Phone 8 & Firefox OS and Firefox mobile. That last part was the hard bit, and I’m sad to say that we didn’t find an answer. So, we had to build this ourselves – you can see it on any business profile page on your smartphone like this one (though you’ll have to change your browser user agent to a mobile phone to see it).
TL;DR: you’ll need to find replacements for all plugins, and if you don’t, your options are to write it yourself, or drop the functionality.
Once you’ve found solutions for third party code, you need to focus on your own custom code. To find out what could break, you’ll need to look over your JS and see what jQuery methods and properties are in use. You can do this manually, but I don’t fancy looking over 10,000 lines of code by hand. I asked “how can I do this” on Stack Overflow and got a great answer from Elias Dorneles:
-ooption for grasp and adding a sed filter to get only the function names:
grasp '$(__).__' -e -o *.js | sed 's/.*[.]//' | uniq -c. This fails for some code for the same reasons that grep, but maybe it can help you get an estimate.
You can run this on one file, or an entire directory. Here’s what Bootstrap.js looks like (after I’ve tabulated it in excel):
This is the list of functions that you will have to find alternatives to in order for your JS to function correctly, along with an approximate count of the number of times a function is used. I say approximate, because in my experience, the grasp script doesn’t get everything, especially where chained functions are concerned. The good news with this set is that there aren’t many complex functions in use – the vast majority can be replaced with a line or two.
The results of this query can bring back all sorts of jQuery functions, things like .live, .die, .delegate, .browser, .size, .toggle, and other deprecated functions from over the years. These are the warning signs that the rest of your code may not be ready for a move away from jQuery, and if you get these, you should seriously consider why you’re doing this. I listed my reasons in the introduction post and there are more besides, like minimal memory footprint whilst adding Windows Phone 8 and Firefox OS support. You may end up spending a lot more effort on your code than you originally intended, just to bring it up to par with the current state of web standards. Clearly, this isn’t a bad thing, but your boss may be wondering why it’s taking so much time. For a great article on technical debt, try Paying Down your Technical Debt from Chris Atwood’s Coding Horror site.
Up next, replacing individual functions with standards-based code
That’s it for this part, in the next one, I’ll cover replacing the functions identified above with standards-compliant code to create your own min.js.