Mobile Web: Cost of JavaScript Frameworks
In many of my previous posts I've discussed the importance of mobile, and the company where I am employed as the lead software engineer; the users have shown us over the past couple of years that they prefer to visit our site on their mobile over their desktop.
It's clear to me that we need to not only understand that our users want a good mobile experience, we actually need to be proactive in supplying the best experience possible to keep up with users expectations, or the users will go where their expectations are met.
A mobile device doesn't have the processing power of desktop or laptop computer, we know this, but do we actually do anything with that knowledge? If you use a JavaScript framework like Polymer, Angular, React, Backbone, or Ember; have you benchmarked it on mobile compared to the desktop experience? If you haven't already, look up benchmarks done already or perform your own. You will find vanilla JavaScript outperforms all frameworks. By an unbelievable margin.
tl;dr Mobile devices are slow, Frameworks are all proven to be slower than vanilla JavaScript. I'm going to discuss how I have made changes to a large scale site to remedy this issue.
Libraries can be swapped out and replaced if they prove problematic. Frameworks on the other hand, tend to be a lot more difficult to swap, often requiring a rebuild of the app in question and inherently a lot bigger and under-utilised.
I’m concerned by the costs of frameworks on mobile, so I'll focus on frameworks and not libraries.
I see the ergonomic benefits in frameworks, but I can’t help but feel that, for many developers, investing in knowledge of the web platform (JavaScript) itself is the best long-term investment. Frameworks come and go, they do contribute ideas and patterns but if you ever find that the one you use no longer works for you, or has a bug that remains unfixed, being able to understand the platform that the framework abstracts will help enormously.
Your project code should functionally provide a feature your users interact with, Frameworks only provide developers a tool to start writing that code not the feature itself.
Good developers use frameworks, great developers understand how frameworks abstract the real vanilla functionality.
Frameworks are an inversion of control. They control the lifecycle of the app, and give you entry points where your code runs. You’re still responsible for the final code, but you’re not in control. One day you’re just coding, developing your app, and in the console you see a warning telling you that there’s been a deprecation. That often requires figuring out what the latest version of the framework is and what it needs you to do differently, and that may also mean refactoring projects. You have to take time out to learn any new or updated framework: what it means to write idiomatic code for that framework; its patterns, practices, and ways of doing things.
That's more control taken from you by Frameworks, you can't even focus on your app sporadically and those deadlines or stakeholders or clients are calling while you're upgrading, refactoring, and re-learning.
You could be creating features or fixing UX bugs with that valuable time wasted
But how to avoid frameworks effectively?
I'm going to share some tips on how to tackle the benefits frameworks provide while remaining vanilla JavaScript.
One of the most helpful Framework features is abstraction, which is commonly said to mitigate complexity. It does mitigate complexities that arise I admit, yet a lot of complex code I've seen is actually written to circumvent the strangle hold frameworks themselves impose on you. Frameworks aside though, complex code is inevitable and the key to handling complexity is in understanding the difference between abstracting and SoC. Look to design patterns rather than frameworks.
Abstraction is for simple, single purpose, reused functionality, it will allow you to be DRY. SoC can be misconstrued, put simply SoC can be DRY and it can be code duplication. Being DRY is not always best practice, and abstraction can be the downfall of a project.
Complex functionality should be respected, do not try to abstract it as abstractions are inherently complex due to imperative programming fundamentals and are an unnatural thought process for humans. Respect the complex functionality and do not attempt to make it reusable for the sake of one day it might be reused. Functional programming patterns are great tools for dealing with complexity as it allows a human mind to process concisely what is happening, the real challenge is first learning all of the possible patterns and you will be able to easily identify how to best tackle any coding problem you encounter with the right pattern.
The idea of a design pattern is an attempt to standardize what are already accepted best practices. Effective software design requires considering issues that may not become visible until later in the implementation. Reusing design patterns helps to prevent subtle issues that can cause major problems and improves code readability for coders and architects familiar with the patterns.
Often, people only understand how to apply certain software design techniques to certain problems. These techniques are difficult to apply to a broader range of problems. Design patterns provide general solutions, documented in a format that doesn't require specifics tied to a particular problem.
In addition, patterns allow developers to communicate using well-known, well understood names for software interactions. Common design patterns can be improved over time, making them more robust than ad-hoc designs.
All of this is actually how the frameworks are written, yet these frameworks don't provide your product and users any features on their own, whereas you as a developer can cut out the framework entirely by employing the patterns yourself in your own code.
Instead of learning a framework, learn design patterns.
It's been talked about above briefly once or twice, but I strongly believe that all developers would benefit greatly if they invested the same time it took them to learn, refactor, update, re-learn a framework; and instead use that valuable time to learn the platform itself, learn JavaScript. jQuery is not JavaScript, Angular is not JavaScript, any framework or library you've used is not JavaScript.
Take the time to learn Web Workers (not to be confused with the awesome new Service Workers), they're more than 10 years old and I doubt you know the first thing about them, they offer multithreading and mitigate everyday issues with laggy animations, golty scrolling, and page lock ups. Learn about prefetching and prerendering, use them if you've read about them. Create a manifest.json and utilise Progressive App features like geo-fencing and Push notifications. Learn about OOLO, prototypal inheritance is a unique and powerful beast, You're still sleeping and you need to be woken up from your nightmare - JavaScript is not evil and not untamable, it is elegant and really powerful when it is used as it was meant to be used, not hacked to be something it isn't meant to be, such as classical OOP, it is not designed for it, it is designed for prototypal programming.
Looking forward
If we can achieve fast-booting, low-memory, smooth-executing frameworks with good ergonomics we’ll be onto a winner. Basically, the best framework can only be one that is available natively on the platform; I just wish one day the developers who toil at frameworks contribute back to the greater community by enhancing the open web itself.
Until then, for mobile at least, I’ll be sticking to the vanilla web platform.
Final words
Learn pure JavaScript, use prototypes; you will finally see the truth and until then you'll doubt everything written on this page.
Just remember, the best way to be the best developer is to learn the underlying platform and all of the design patterns, and hire those whom you know respect the language as you have come to by doing the same.