DEV Community

Cover image for JavaScript Should Be Your Last Resort
Olavi Haapala
Olavi Haapala

Posted on • Originally published at olavihaapala.fi on

JavaScript Should Be Your Last Resort

JS Is Your Hammer

When working on modern frontend web development, using your favorite framework of choice, it can be sometimes tempting to solve all the problems with JavaScript. Sometimes this happens unconsciously as JS is what you mostly use in your day-to-day development work.

This is similar to the situation described by Abraham Maslow in 1966:

I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.

Wikipedia: Law of the instrument

Photo of a hammer about to hit some nails

Photo by Fausto Marqués on Unsplash

Note: In this blog post, I’m only talking about JS even though I’m mostly using TS in my projects – it ends up as JS after compilation anyways.

What to Take into Account When Implementing UI

This mindset of using JS for everything causes unnecessary processing that needs to be run on your end users’ devices as client-side JS. All the JS resources on a website need to be downloaded, parsed and executed by the web browser. This is quite often the cause of slow and unresponsive websites on low-end mobile devices or slow network speeds.

How You Should Be Thinking Instead:

  1. Can this be done in HTML?
  2. If not, can I solve it with HTML + CSS?
  3. And if nothing else works, the solution probably requires a minimal amount of JS in addition to HTML and CSS

This way of thinking is not about what is easiest for you as a developer. You may be a JavaScript focused frontend developer, and solving most of your problems with it feels natural for you. However, you should be thinking about your end users. Client-side JS is the single biggest problem when it comes to web performance. You can read some of my thoughts on web performance from my other blog posts. You can find some links at the bottom of this blog post on my personal blog.

1. Can This Be Done in HTML?

Plan and implement the basic structure and semantics of the feature in plain HTML without any extra styles and using native HTML elements and functionality. If some additional styling or features are needed, go to step 2.

2. Try to Solve It with HTML + CSS

Use CSS to apply the additional styling or animation that is required, still keeping the semantics and accessibility in my mind. If some additional interactivity is required in the particular piece of UI you are building, go to step 3.

3. Use HTML + CSS + JS

Add the minimum amount of JS required to fulfill the requirements. Keep in mind that something that can be solved without JS should probably be solved without JS.

When you’re done, show your code to your colleagues and let them review it. Perhaps there is still something unnecessary parts in your code, that could be solved without having a client-side JS cost for your users.

Simple Example

This problem applies to almost anything in web frontend development, but here is a simple practical example that should help me prove my point.

Imagine you are working on a React project, and you are working on a feature that has some UI parts that should only become visible after a certain delay, let’s say after 2s.

Using React Hooks

If you are used to solving your problems with React and Hooks, your initial solution could look something like this:

const [thingVisible, setThingVisible] = useState(false);

useEffect(() => {
  const timeoutId = setTimeout(() => {
    setThingVisible(true);
  }, 2000);

  return function cleanup() {
    clearTimeout(timeoutId);
  };
}, []);

return thingVisible ? <section>Here's a thing for you!</section> : null;

Enter fullscreen mode Exit fullscreen mode

This is fine and works. Probably you notice no difference in performance either on your hyper powerful developer machine. And probably, there is no real performance issue in this case. But imagine if these pile up and suddenly you would have tens or hundreds of similar unnecessary JS computations to be run on the client-side or some larger and longer executions that are taking place.

Using HTML + CSS Animation

Using CSS, you can animate content to appear on the page with a delay using CSS animations and animation-delay. This is supported by all browsers and could even have a better end user experience as you could fade the content in or use any other ways of making the content appear more smoothly.

The HTML:

<section class="fade-in">Here's a thing for you!</section>

Enter fullscreen mode Exit fullscreen mode

The CSS:

.fade-in {
  opacity: 0;
  animation: fadeIn 2s;
  animation-delay: 2s;
  animation-fill-mode: forwards;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Enter fullscreen mode Exit fullscreen mode

Don’t Use CSS for What You Can Do with HTML

Similarly, don’t do something with CSS that you could and should be doing in HTML.

An extreme example of this was that we had accidentally been using margins to separate two words from each other, instead of using a space in between the words!

This was obviously not a good idea from at least the following perspectives:

  • It might not follow the font size, letter spacing etc.
  • It is not needed, waste of effort and processing
  • If someone would need to copy the text, there would be no space in between the words

Frontend Development Is Not Easy

Web frontend development is not an easy topic to master. It is something you can get started with quite rapidly, but mastering it requires some level of experience and understanding the whole picture in order to be able to solve the right problems on the right level using the right tools. Solving something on the frontend has many levels and details baked in it.

Additionally, you’ll need to understand when a problem should be solved on the backend instead of the frontend for various reasons such as performance, usability or maintainability among others.

However, keep in mind that sometimes you don’t need to try to reach for a perfect solution and something that works might be good enough to be shipped to production and to be used by your end users.

Latest comments (120)

Collapse
 
jdnichollsc profile image
J.D Nicholls

In some cases, you have more control with JS, example with animations: github.com/proyecto26/animatable-c...
And if you use that as a web component, it's easier to use for Designers and Developers :)

Collapse
 
aarone4 profile image
Aaron Reese

Not mentioned in 115 comments is the cost of reshaping API data in js. Pulling down more records than are practically required, or more fields, or having to nest related items (e.g. customer.order.item) using .map.filter is computational cost better suited to the server or data store layers. GraphQLcan help but it is often worth re-specifying the API response or implementing partial datasets and a fetch-ahead policy to prevent UX delays on progressing down the list.
An example of this is Jobserve.co.uk where they prefetch the next 20 jobs in the list; if you scroll quickly you can catch it out.

Collapse
 
nicozerpa profile image
Nico Zerpa (he/him)

Great article Olavi! Yeah, JavaScript is fantastic, but if you overuse it, it's worse for the end-user, in terms of performance but also accessibility.

If you reimplement in JavaScript or React something that HTML alone already does, you'll probably break something and the element is no longer accessible. Don't reinvent the wheel.

Collapse
 
kylewcode profile image
Kyle Williams

Awesome advice. I'm in the process of learning React so I've been biased towards using React to solve all the problems in the apps I am creating.

Collapse
 
barelyhuman profile image
Reaper

I realised this last year, got into learning other languages that I could randomly switch to.
Got into Go and have been building simple template based websites while avoiding as much JS as I can just for a change.

A recent project was
commitlog-web
source

I did write a bit on a similar topic but that involves a few controvertial statements but if anyone would like to go through it.

reaper.im/blog/06012020-Getting-be...

Collapse
 
tccodez profile image
Tim Carey

JS sucks I am all for using less of it

Collapse
 
eelstork profile image
Tea

Totally agree there is a big world outside your browser.
Okay okay. Joke : )

Collapse
 
andreidascalu profile image
Andrei Dascalu

"This way of thinking is not about what is easiest for you as a developer" - ok, but this is what makes it a losing way.
All other things being equal with respect to the outcome given business requirements, things should go with what's easiest for a developer.
Easiest for a developer (as long as architecture is respected) translates into quicker time to market and lower development costs. Long term costs should be addressed by architecture and other business constraints (such as hiring market, other costs, etc).
Unless there's a significant impact to the end result for that business requirement, I see no reason to go against a developers toolset.

Collapse
 
olpeh profile image
Olavi Haapala

But you should always consider the cost from the end-user point-of-view. Think about accessibility or browser support for example. It's not fun or easy for you as a developer, but it makes it possible for your (possibly paying) users to use your service!

Collapse
 
andreidascalu profile image
Andrei Dascalu

I disagree. You don't. That's a business decision that depends on how the product was defined to target and support. What you (eg: developer / architect) should do is present the options and constraints to business to make a decision.
Doing in this way means a certain time-to-market and development costs but it may leave out or otherwise impact users.
Doing it the other way may come with extra costs in terms of development but may results in other advantages.
Middle way: we could start one way but there may be extra overhead to design it in a way that allows a reasonable time to change later on.
Then the business decides. It's perfectly reasonable to knowingly limit browser support for example if it's cost effective to market earlier. It's not a development decision.

Collapse
 
jmarshall9120 profile image
jmarshall9120 • Edited

"Client-side JS is the single biggest problem when it comes to web performance" - why do you think this?

Collapse
 
olpeh profile image
Olavi Haapala

Hey, thanks for the question! I in fact forgot to mention where I got this idea from. It's from Steve Souders' keynote at performance.now() conf in 2018.

Direct quote actually is:

JavaScript is the biggest problem for web performance today.

You can watch the talk here:
youtube.com/watch?v=RwSlubTBnew

Collapse
 
russellbateman profile image
Russell Bateman

Terve ! Interesting article and, on the surface, I agree with much you have said though I'm a backend (Java) guy--not a frontend guy and deserve no voice here. However, I have been doing HTML and CSS for a couple of decades, I do almost zero JS.