The JavaScript-Dependency Backlash: Myth-Busting Progressive Enhancement
In Louis’ recent forum topic, Are we in a scripting-dependency backlash?, he commented:
I think, in some sense, we are in somewhat of a scripting-dependency backlash, and it’s probably a good thing.
TL;DR
- I agree. So do several others including web gurus PPK (The problem with Angular) and Jeremy Keith (Angular momentum) and Jake Archibald (Progressive enhancement is still important).
- Relatively few web applications are suited to JavaScript frameworks despite their meteoric rise.
- Progressive Enhancement remains the best option for solving web development issues such as wide-ranging browser support, maintenance and future-proofing your application.
Let’s define the terms we’re discussing…
What is JavaScript-Dependency?
There has been a rise in the use of client-side frameworks. These provide server-side-like coding patterns such as MVC, template views, reusable components, form validation and more. AngularJS is probably the best known and most popular but it’s not the only solution.
Unlike server-side frameworks, the client-side alternatives must run on a modern JavaScript-enabled browser. Without JavaScript, they fail. TIDAL is a typical case; if JavaScript isn’t available, the user sees a blank page. There is no content, no error and no sign-up form.
While there’s little excuse not to show a message, there are good use cases for JavaScript-dependent apps:
- Prototypes
It’s quick to mock-up sites and apps because client-side frameworks provide rich components and shortcuts. - Client-side-only applications
If your app is simple and requires no server interaction other than an initial download, a JavaScript framework may be a good fit (presuming you can remove stuff you don’t need). - Internal corporate applications
Enforcing JavaScript isn’t a problem when you know your audience and the devices they use. Angular was initially designed for enterprise applications. - Sophisticated interfaces
Consider action games, Google Maps and Docs. Developing JavaScript-less alternatives is futile. Google created a basic HTML version of Maps but it was effectively a different application and was dropped in 2010.
There are other cases but the majority of public-facing web sites and applications do not fall into these categories. No one will stop you using a client-side framework but, when you have a hammer, everything looks like a nail. To quote Louis again:
Developers seem to be using flashy new tools just for the sake of it, and not because they are solving an actual problem.
What is Progressive Enhancement?
Progressive Enhancement (PE) is not a technology but a development approach. I wrote several tutorials and examples in 2009 but the concept has been discussed since 2003.
You establish a base level of user experience then add more advanced functionality when the browser supports it. Taking PE to a logical extreme:
- You create an HTML-only application where all important processing is done server-side. It would work in any browser; mobile devices, Lynx, IE1.0 or whatever you throw at it.
- You enhance the layout with CSS. CSS is PE-ready because browsers ignore properties they don’t understand. You can enhance it further using options such as media queries or @supports rules. The application still works everywhere but offers an improved experience for browsers with modern CSS capabilities.
- You enhance the functionality with JavaScript. JavaScript is the most volatile layer since language and API support varies from browser to browser. Presuming it runs, you test facilities are available before using them. For example, you could turn a table of data into a pretty chart when
canvas
orSVG
is supported.
Every browser receives the best application it can handle. It’s possible that no two browsers offer quite the same experience. Mobile-first responsive design and the lesser-used offline-first are examples of Progressive Enhancement techniques.
Let’s examine the criticisms of PE.
MYTH: No One Disables JavaScript
Few people know what JavaScript is. Few browsers allow users to (easily) disable JavaScript.
This is absolutely true.
PE critics then conclude:
those without JavaScript get what they deserve
It’s dangerous to presume JavaScript will be available to everyone, everywhere, every time to the level your app requires. Everyone has JavaScript, right? illustrates the point.
Progressive Enhancement is not about catering for those who disable JavaScript. It’s about enhancing the experience when certain JavaScript features are available. The application may offer a miserable interface when JavaScript is disabled but the user still gets something.
MYTH: No One Uses Old Browsers
What do we mean by “old”? For most developers, it’s any browser released more than twelve months ago. Not everyone can use the latest and greatest applications:
- large organizations and government departments
- people with disabilities
- people in developing countries
- less affluent sectors of the community
- anyone with an iPhone 5.0 or Android 4.0 and below.
These sectors may not be important to you. But will they never be important?
Progressive Enhancement makes no assumptions about your audience. That’s not true for client-side frameworks. Those who can’t use your application will disappear from server logs. It quickly becomes a self-fulfilling prophecy: “no one using our app is on an old browser so we can carry on as-is…”
MYTH: Progressive Enhancement is Anti-JavaScript
Progressive Enhancement embraces the fundamental strengths of the web. It’s possible to develop a site or application which works on any web-capable device anywhere in the world. The better that device, the better the user experience.
Client-side frameworks make JavaScript an absolute dependency. You’re no longer coding for the web. Your application uses the web as a delivery mechanism to specific runtime engines. The browser is your operating system and an update could break your app.
MYTH: Progressive Enhancement Makes Assumptions About Users and Devices
PE is about NOT making assumptions. You don’t presume anything — it’s the core premise of the technique.
JavaScript frameworks lull you into thinking everyone is using a capable browser on a powerful device. We’ve made these presumptions before. Is it any different to assuming everyone’s on broadband? Or that everyone has a 17″ screen at least 960px wide? Or that everyone will use IE6 now and forever more?
MYTH: Progressive Enhancement Means Supporting Archaic Browsers
Progressive Enhancement critics presume you’ll spend all your time dealing with old browsers. In reality, it’s the opposite: you never need to deal with old browsers because appropriate fallbacks are in-place.
Supporting old browsers is a benefit of PE — not an objective. You can support the lowliest of browsers but you can establish whatever baseline you like.
For example, I’m currently working on an application where addEventListener
is a requirement for most JavaScript to run. IE8 and below will therefore fail to show functional enhancements. I could fix that but it’s not worth the investment since it’s a corporate app with no oldIE users. However, IE8 users can still use the system and it could be improved if required.
MYTH: JavaScript Framework Apps are Cooler
You can create an identical-looking app using PE techniques. The confusion arises because most JavaScript frameworks provide a range of good-looking pre-developed widgets. Those same widgets could be used in a progressively-enhanced app but, without JS, they’d fallback to basic HTML alternatives.
PE also allows you to use modern HTML, CSS and JavaScript APIs which are yet to appear in any browser. Consider the Fetch API — a modern replacement for XMLHttpRequest. It has minimal support yet I could use it without problems because I can either fallback to XMLHttpRequest or server requests.
JavaScript frameworks are firmly stuck in the present — not the future.
MYTH: Progressive Enhancement Holds Back the Web
Or, more specifically, client-side frameworks are on the cutting edge and pushing the web forward.
Sorry, but this is an illusion. AngularJS-like frameworks implement magical features but, dig below the surface, and you’re still using HTML, CSS, JavaScript and DOM manipulation. At best, it’s an abstraction. At worst, it’s a distraction.
Your client-side framework is only as good as the browsers it was developed for. AngularJS 2.0 is a complete re-write because features such as Object.observe()
and Web Components weren’t commonly available when AngularJS 1.x was released. The framework forces you to use older technologies but hides the implementation from you.
PE allows you to use any modern API without breaking your application. Best of luck upgrading from Angular 1…
MYTH: JavaScript Frameworks Make Development Simpler
This is partly true — but only when you’re starting to build your application. You have access to a range of controls which cut the initial development time. But you’re then stuck within the confines of that framework and that can lead to problems later.
Presume your app has been running for a while and the client demands support for BrowserX. It’s used by a major customer and is not particularly old; the Blackberry browser, iPhone 4, Android 3.3 etc. They’re probably expecting a development time of a few days but it could be impossible if your JavaScript framework is incompatible.
The question may never arise for an app developed using PE techniques; you’re possibly supporting that browser already. Further enhancements can be added without a major re-write.
MYTH: Progressive Enhancement is Twice the Effort
This is the favorite quote of the critics. The only people who say PE is too much effort are those who’ve never tried it or somehow failed in the attempt.
PE will only take twice as long if you didn’t consider it from the start. Trying to retro-fit PE into an existing application is doomed — that’s especially true for one which depends on JavaScript.
Let’s consider a simple example such as a paged list of results from a search query. The first page load returns all the HTML. It’s fast and there’s nothing for JavaScript to do. Behind the scenes, we’re using a database query and slotting the results into an HTML template. You could quickly adapt the same service to return the results as JSON data or results HTML without the header and footer. When the user clicks “page 2”, the second page of results is shown:
- With JavaScript, we can intercept the click and use Ajax techniques to fetch that page of results. HTML data can be slotted into the page using
innerHTML
. Alternatively, we could use page 1 as a template for returned JSON data. - If JavaScript, XMLHttpRequest or Fetch isn’t available — or the Ajax call fails — we can request a second full page of HTML.
It’s a little more work but it’s certainly not double the effort. We have the benefit of a cross-browser fault-tolerant solution.
MYTH: Progressive Enhancement is Pointless — Websites Evolve or Die
The logic behind this argument is that websites eventually become obsolete. Therefore, you can use a framework which targets specific technologies at a specific point in time.
I wish. If your code’s good, it’ll be used far longer than you expected. Bad code lives even longer because no one wants to touch it.
But again, use Progressive Enhancement and you’re not making any presumptions other than the web will continue as a client/server-based HTML-based system. The web would need to fundamentally change for your app to fail — it would no longer be the web!
MYTH: Progressive Enhancement is an Old Technique Recommended by Old Timers
To quote Oddz:
The proliferation of client side JavaScript frameworks puts you in the minority along with the rest of the “old timers”.
Yeah, thanks!
The JavaScript backlash is led by people who’ve been developing for the web for a considerable period. Are we all Luddites failing to move with the times? Perhaps. Or perhaps it’s because we learned something from our many, many historical mistakes?
JavaScript frameworks raise familiar issues:
- Some intermingle HTML and functionality like we used to do with
onclick
handlers, e.g.<form ng-submit="doSomething()">
- They target specific browsers. There has been a resurgence of “best viewed in…” messages and
<noscript>
tags. - They make presumptions about today’s web — such as JavaScript works everywhere and 2MB per page is reasonable.
- They do not plan for the future.
JavaScript frameworks mostly benefit the developer — not users. They can offer a short-term gain but the cost is fewer visitors and painful long-term maintenance.
And let’s not forget SEO. Google indexes JavaScript pages but following every logic branch won’t necessarily be possible. It can also be difficult to link back to a specific URL unless you’ve coded carefully.
Progressive Enhancement compliments the strengths of the web:
- it separates content, layout and functionality for easier maintenance
- you’re writing defensive, fault-tolerant, device-agnostic code for the web — not browsers
- you can support a wide range of devices
- your testing burden is reduced because your app remains operative on failure
- SEO and accessibility are baked-in (or require less effort)
- sites and apps will work on browsers released today, yesterday and tomorrow
- no one has disproved the benefits of Progressive Enhancement or proposed a better technique.
There’s only one downside: it’s evident many developers still don’t trust or understand Progressive Enhancement.
Long live the JavaScript-Dependency backlash!