Frontend Development 19 min read

Why Responsible JavaScript Matters: Performance, Accessibility, and Sustainable Front‑End Practices

JavaScript’s growing size threatens web performance and accessibility, so developers must evaluate when to use frameworks, adopt progressive enhancement, reduce unnecessary code, and leverage native browser features like prefetch and service workers to build faster, more sustainable, and inclusive web experiences.

WecTeam
WecTeam
WecTeam
Why Responsible JavaScript Matters: Performance, Accessibility, and Sustainable Front‑End Practices

JavaScript is a key factor in web performance; modern pages often deliver 400 KB of compressed JavaScript, which expands to over 1 MB after decompression, placing a heavy load on browsers, especially on low‑end devices.

Measurements on a 2017 MacBook Pro show a 23 KB uncompressed script executing in about 25 ms, while the same script takes roughly 190 ms on a Nokia 2 Android phone, illustrating the performance gap across devices.

We must responsibly use JavaScript by understanding what we build and how, distinguishing between simple informational sites and full‑featured web applications, and avoiding unnecessary heavy frameworks that add hundreds of kilobytes of code.

Website vs Application

Confusing terminology can hide the true nature of a project; a plain website and a full‑featured web app are not the same, and using heavyweight frameworks for a simple site hurts users and efficiency. When building a web app, the installed modules can bring hundreds (or thousands) of dependencies, some of which may be unsafe. Run

npm ls --prod

to inspect the production dependency tree, though this does not guarantee all third‑party scripts are safe.

Both sites and web apps share the same network and device constraints; choosing to build an “application” does not eliminate those limits, nor does it magically grant users new device capabilities.

We have a responsibility to assess who uses our product and recognize that their internet conditions may differ from our assumptions. Knowing our goals lets us build solutions that meet them, even if the result is not exciting.

This means re‑evaluating our reliance on JavaScript and the way we use it; rejecting HTML and CSS in favor of JavaScript leads to unsustainable development, harming performance and accessibility.

Don’t let frameworks force unsustainable patterns

In team environments I have seen odd code that depends on frameworks for productivity but ends up degrading accessibility and performance. The following React class component illustrates the problem:

<code>import React, { Component } from "react";
import { validateEmail } from "helpers/validation";

class SignupForm extends Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.updateEmail = this.updateEmail.bind(this);
    this.state.email = "";
  }

  updateEmail(event) {
    this.setState({ email: event.target.value });
  }

  handleSubmit() {
    // If the email checks out, submit
    if (validateEmail(this.state.email)) {
      // ...
    }
  }

  render() {
    return (
      Enter your email:
      SignUp
    );
  }
}
</code>

Accessibility issues in this component include:

Forms that are not built with a

&lt;form&gt;

element; using

role="form"

on a

div

is insufficient.

Replacing

&lt;label&gt;

with

&lt;span&gt;

loses native accessibility.

Client‑side click handlers on

&lt;button&gt;

should be moved to the form’s

onSubmit

event.

HTML5 form validation already handles email validation; using JavaScript adds complexity and requires extra tricks to work well with screen readers.

Additionally, the component does not rely on state or lifecycle methods and could be a stateless functional component, reducing JavaScript.

Refactored, the component becomes:

<code>import React from "react";

const SignupForm = props => {
  const handleSubmit = event => {
    // Needed if we send data via XHR
    event.preventDefault();
    // Carry on...
  };

  return (
    <form method="POST" action="/signup" onSubmit={handleSubmit}>
      <label for="email" class="email-label">Enter your email:</label>
      <input type="email" id="email" required />
      <button>Sign Up</button>
    </form>
  );
};
</code>

The new component uses less JavaScript and improves accessibility, leveraging many free browser features.

Frameworks are useful productivity tools, but regardless of the tool chosen, continuous learning of core web technologies is essential for creating good experiences.

Single‑page applications

Developers often adopt SPA models blindly, even when unsuitable. While client‑side routing can improve perceived experience, it sacrifices native browser navigation, history handling, and accessibility for users without JavaScript. Server‑side rendering is required to keep SPAs usable without JavaScript.

Figure 2. Comparison of a JavaScript‑heavy SPA (left) with a server‑rendered page that hydrates on the client (right) under a slow network.

If client‑side routing does not announce page changes, accessibility suffers for assistive‑technology users.

System overhead is another concern: adding React, React Router, and a state‑management library can lock in roughly 135 KB of code that cannot be optimized away. Consider whether such a stack is truly necessary.

When concerned about navigation performance, use

rel="prefetch"

to preload same‑origin documents; preloaded resources are cached and available instantly, improving perceived load time with minimal bandwidth impact.

Figure 3. The HTML for

/writing/

is preloaded on the initial page, allowing instant load from cache when requested.

Quicklink, a tiny Google script, checks for slow networks or data‑saver mode before preloading links, and it does not preload cross‑origin resources by default.

Regardless of client‑side routing, Service Workers can dramatically improve the experience for returning users. By pre‑caching routes with Service Workers, you gain the same benefits as link prefetching with finer control over requests and responses. Adding Service Workers is one of the most responsible ways to use JavaScript today.

JavaScript is not a layout solution

When tempted to solve layout problems with third‑party JavaScript modules, remember that CSS is designed for layout. Modern layout engines like Flexbox and Grid, along with

@supports

feature queries, enable progressive enhancement without extra JavaScript.

<code>/* Your mobile‑first, non‑CSS‑grid styles go here */

/* The @supports rule below is ignored by browsers that don’t support CSS grid */
@supports (display: grid) {
  /* Larger screen layout */
  @media (min-width: 40em) {
    /* Your progressively enhanced grid layout styles go here */
  }
}
</code>

Using JavaScript to solve layout and presentation issues is an outdated practice; progressive enhancement should be the primary goal.

I’m not trying to kill JavaScript

I have no ill will toward JavaScript. It has been my profession for over a decade, and it is a mature, feature‑rich language that continues to evolve.

However, I am critical of the trend that treats JavaScript as the primary means of building the web. When I untangle a tangled bundle of code, it becomes clear that JavaScript has become over‑used.

In upcoming articles I will share practical advice to curb excessive JavaScript use, making web content more resilient and inclusive for everyone.

References

[1]

JavaScript is a performance key: https://httparchive.org/reports/state-of-javascript#bytesJs

[2]

How devices handle large JavaScript bundles: https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4

[3]

One‑off project: https://devmode.jeremy.codes/

[4]

Android Nokia 2: https://www.gsmarena.com/nokia_2-8513.php

[5]

Some dependencies may be unsafe: https://snyk.io/blog/malicious-code-found-in-npm-package-event-stream/

[6]

Identify all production dependencies: https://gist.github.com/malchata/dae0a011033846e2cb44d315b0496f0d

[7]

Even if the build isn’t exciting: https://css-tricks.com/simple-boring/

[8]

Some extra tricks for native validation: https://developer.paciellogroup.com/blog/2019/02/required-attribute-requirements/

[9]

Browsers provide many free features: https://alistapart.com/article/paint-the-picture-not-the-frame

[10]

Specification: https://html.spec.whatwg.org/#the-history-interface

[11]

Users without JavaScript still have access: https://kryogenix.org/code/browser/everyonehasjs.html

[12]

React: https://bundlephobia.com/[email protected]

[13]

React Router: https://bundlephobia.com/[email protected]

[14]

State‑management library: https://bundlephobia.com/[email protected]

[15]

Quicklink: https://github.com/GoogleChromeLabs/quicklink

[16]

Data‑saver mode: https://support.google.com/chrome/answer/2392284?co=GENIE.Platform%3DAndroid&hl=en

[17]

Service workers: https://adactio.com/articles/13796

[18]

Pre‑cache routes with Service Workers: https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker

[19]

CSS is meant for layout: https://twitter.com/rachelandrew/status/1088870059240505344

[20]

Feature queries: https://hacks.mozilla.org/2016/08/using-feature-queries-in-css/

[21]

Not difficult: https://hacks.mozilla.org/2016/08/using-feature-queries-in-css/

[22]

Progressive enhancement: https://alistapart.com/article/understandingprogressiveenhancement

FrontendPerformanceJavaScriptaccessibilityWeb DevelopmentProgressive Enhancement
WecTeam
Written by

WecTeam

WecTeam (维C团) is the front‑end technology team of JD.com’s Jingxi business unit, focusing on front‑end engineering, web performance optimization, mini‑program and app development, serverless, multi‑platform reuse, and visual building.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.