The Dangers of JavaScript Frameworks, Libraries and Plugins

PluginsThe recent explosion of JavaScript frameworks and libraries in web development has been undeniable. I can think of 10 libraries right off the top of my head and I have seen a site that lists 34 libraries just for visualizations. I am happy to see such a diverse ecosystem of easy to use tools sprouting up in the web development community. Certainly some of them make development a heck of a lot easier. But I am beginning to see a dangerous practice growing along with this that I think we all have to stop and think about a little.

Ease of use also increases lack of thinking

You are tasked with creating a website for a client. That client is, of course, asking for a whole slew of cool things that they want the site to do. No problem for you, they are not asking for anything you haven’t seen already. They want the typical fade effects, collapsing menus, animations, some sound effects and more. Damn it if it isn’t going to be the coolest looking version of a Blizzard Entertainment website even if it is for the accounting department of an insurance company.

Time to get to work. Great! We will throw on jQuery (it is a must), jQuery UI for enhanced user interface effects, howler.js for the sound, D3.js for some charts, go with knockout or angular for MVC and maybe validate.js for form validation. You use the libraries to create the dream website and pad your portfolio with some legendary work.

But now there might be a few problems:

  • You just added 150KB+ of JS code to your page. Each time someone visits, they are downloading this extra traffic (unless they have a copy cached).
  • Now each visitor is making 6+ additional file fetches.
  • You have increased your attack footprint by leaps and bounds.
  • There may now be some conflicts you don’t know about.
  • There is most likely some overlap and repetition going on.
  • Sometimes if there is a bug, good luck sifting through everything including minimized obfuscated code.

Because developers are being spoiled with some library love they haven’t stopped to think about what they are actually adding and what it could mean in the long run. It could mean degraded performance, it could mean exploitable code, it could mean unintended side effects or it could simply mean increased complexity leading to poor maintainability.

Choosing libraries/frameworks wisely

My suggestion would be to think in broad site-wide terms and think about exactly what you need. If I am going to create a simple contact form with a name, email and a comment box do I really need to use validate.js for it? Could I not write a simple JavaScript function that checks the validity of three fields? Ask yourself how much of the library functionality you are going to actually use because if you aren’t using it, it is going to be bloat. It also means that function for validating a textarea, that you don’t even use in your form, may contain code that someone could some how exploit. It is also dead weight you are carrying along for each visitor who visits. Sure each component may be “lightweight” but together they become a heavyweight setup.

Also look for overlapping features. I know people who are including libraries that do fade effects that they could have simply done in jQuery which they have already installed. If I am not doing something specialized, perhaps jQuery is all you need. Even then, how much of jQuery do you even use? Don’t include jQuery if you are just going to write a simple function to print someone’s name.

In addition to all this, we have to get into the habit of thinking “If I include it, I should support it.” If one of our components is sick and throwing up some kind of errors, we may have to dig into it a little to find the problem. Running off to some support forum may or may not work and what if no one knows the answer to your question? You want to be able to know enough about what you have included to diagnose the problems yourself.

More than just on the web

I have seen this phenomenon happy in other development circles as well. Huge stacks of technologies where one function is being used from each component in the stack, leaving 99% of the component’s functionality sitting there doing nothing. We should be looking at technologies that are robust, well used and offers a language that we can grow with rather than providing a simple solution on a silver platter to meet the immediate need. This is why I have a soft spot for jQuery. It provides a foundation to write your own stuff if needed.

All I am asking is that before we dismiss something with the off hand comment “Oh why think about that when D3.js can do it?” we should think about old vanilla JS from time to time. Sure it may seem less elegant but often times it is faster and can create that glue you need to bring that special feature to life. It doesn’t have to be complicated. It just requires some thought on our part. Thanks for reading!

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks “The Programmers Idea Book” and “Diagnosing the Problem” . He has been a programmer for over 18 years. He works for a hot application development company in Vancouver Canada which service some of the biggest telecoms in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.

  • A few thoughts.

    First, jquery is not a must. It might work for you and that’s great, but there are alternatives.

    Second, you should use a build process for production. If you write modular code using something like AMD, you can easily do builds that concatenate, minify, obfuscate, and even remove dead code. No reason to making multiple requests to pull in and evaluate unused code.

    Vanilla js is great when the project is simple, you have a limited set of target browsers, and you feel like re-inventing the wheel.

    • Sure there are alternatives to jQuery, but you have to admit that more and more plugins are being developed that work with jQuery than anything else. But your point is certainly valid and heck if you are only using 1 function of any library you should be asking yourself if you really need that library. To your second point, the build process only alleviates some of the problem. Obfuscating doesn’t help much, minifying is only treating the symptom and not the problem (having to download anything and fetching it to begin with) and I have yet to see anything that can do a good job of concatenating only the used portions of Javascript libraries. Now all these methods you suggest would work, if even in a limited capacity, but half the time people and businesses don’t do this.

      As for Vanilla js, I whole heartedly disagree that it is only good for simple projects with limited target browsers. Vanilla js is often faster in many respects and is the glue that can keep some of these libraries together. Heck, it may be the technology that you would use to help facilitate some concatenation. Two functions that need to work together but were not originally designed to work together may need a little Vanilla js to help them place nice.

      Great comments, keep them coming! 🙂

      • “I have yet to see anything that can do a good job of concatenating only the used portions of Javascript libraries.”

        Proper dependency management through AMD using requireJS, dojo’s loader, and curl.js is designed specifically for this purpose. Add in google’s closure compiler and you can even pull out dead code inside of those individual modules.

        The key is to have modules only list the dependencies that they actually need, then run a build that brings in only those dependencies.

        On top of that, the modules themselves should be small. Each one doing a small job, and doing it well.

        Jquery’s plugin system wasn’t designed with dependency management in mind. People typically include jquery, then a bunch of blocking script tags for the plugins they want and hope they all work together. If that was the current state of the art, then I’d agree with much more of your post. I just think a ton of this was solved in javascript a few years ago, but people don’t really see the problem until they build an app large enough to see what basically amounts to DLL hell from 15 years ago.

        • Thanks. I see where you are going with this now. Perhaps if a majority of those out there would know how (and take the time) to set up something like that much of the problems I have mentioned could be avoided. But then on the flip side it also sounds like you are suggesting two more scripts just to manage the loading of other scripts and their dependencies. 🙂

          • Actually you can build the whole thing into a single small file 🙂

            Think of AMD as more of a pattern than a library. Sure there’s implementation (requirejs, dojo, curl), but with a decent build process you don’t need to include more than a single script.

            Also on the subject of libraries/toolkits I think definition of vanilla js might be a bit subjective. Most of the time I’m hear people use it they mean specifically js without jquery or some large or popular framework. I personally just use the term vanilla js to mean js specific to a page without any other dependencies.

            The funny thing is that once you write a piece of js that you want to re-use, you’ve written a library. And if you have a dependency on that, are you still writing in vanilla js?

  • Jeffrey Richman

    You both raise some excellent points. And while I’m biased because I agree with Martyr’s broad essay, I don’t think that invalidates this particular idea, Luis:

    Every dependency you add to a project increases the project’s complexity not cumulatively, but EXPONENTIALLY.

    Because not only does that dependency have a relationship to your code, but it also has a relationship to every other dependency. You might see a conflict between X.js and Y.js plugins that has nothing to do with your code.

    Additionally, over-reliance on third party libraries can hamstring programmers by forcing them into thought processes where “damn, I’d really like to do this particular thing, but the library doesn’t quite support it, and I’d have to write a lot of code to support it on my own and thus waste all that time I spent integrating the library.” So they dismiss the idea itself and start thinking only within the confines of what libraries support.

    For simple projects, that probably works fine. But for complex projects it’s just not a good habit to get into.

    Personally, if something is maybe 20% more difficult to implement from scratch than to bring in a library to support, I’m usually inclined to spend the extra time implementing it from scratch. It’s like an extended warranty that covers requirement changes.

    But that’s just me.

    • I think you summarized some of my points exactly. I am of the same thinking on the 20% argument. When you know what is in the library you are using, because you built it, you can always rest assured that something is not sneaking in there or that if a bug pops up you can fully own it. If the complexity climbs, then obviously use the tools best suited for the job. 🙂