top | item 19367149

A JavaScript-Free Front End

484 points| bibyte | 7 years ago |dev.to | reply

210 comments

order
[+] roebk|7 years ago|reply
It's perfectly possible to do some nifty tricks with CSS alone. The one thing this author has omitted is the impact this has on accessibility. Sure, I can open a modal without the need of JavaScript, but my focus isn't trapped within the modal and with no standard keyboard shortcut (ESC) to dismiss the modal, it provides a sub-standard experience for all users.

Be sensible and use JavaScript when it's appropriate. Please don't think it's cool to create some fancy JS-less widgets and forget about accessibility.

[+] gambler|7 years ago|reply
You can trivially add keyboard shortcuts to this solution after it's implemented - with 0 rework. Moreover, the is absolutely no guarantee that an arbitrary JS library for modal popups will have better usability. And I have yet to see one that will not fail if I block JavaScript, creating horrible user experience for everyone who does so. Funny how usability concerns go out of the window when NoScript/uBlock users are involved.

Personally, I try to avoid modal popups altogether. There is almost always better ways to structure things. The whole concept of "modal" UI doesn't map well to the "document" nature of web elements.

[+] jasonhansel|7 years ago|reply
Also: be sensible about accessibility when writing JavaScript SPAs. If your page consists entirely of nested <div>s without any semantic markup, you're going to have problems (and perhaps risk a lawsuit).
[+] oh_boy|7 years ago|reply
Totally agree on your statement. It's not possible to build modern solutions that are accessible without using some JavaScript. It's always a matter of where you want to go. And it's easy to spare e.g. modals. The question is just if you can solve user experience issues with just HTML and CSS for all use cases.

On the other side, there are more solutions built into HTML and CSS one thinks. In your particular example, you can use the HTML dialog element and get built in keyboard and focus management (still requires a polyfill for many browsers).

[+] lhorie|7 years ago|reply
Just to play devil's advocate: why use a modal in the first place instead of just opening a new page?
[+] onion2k|7 years ago|reply
Since I'm caching and gzipping everything, each subsequent pageview is around 6 KB; far smaller than the SPAs I've seen with equivalent functionality.

That's ace. But my internet connection has a 2 second latency so I still have to wait an annoyingly long time every time I interact with your app. My connection is terrible too, so it drops every 10th request, and now I'm seeing a lot of broken pages. If only you'd written an offline-first PWA and used background-loading and prefetching with some intelligence to retry failed requests in order to deliver content before I actually need it this would have worked so much better.

But hey, the app is perfect for you on your robust wifi, so it must work out there in the real world, right?

Snark aside, there's a good reason to build web software in a variety of different ways. Pick the one that suits your users. Don't assume everything works perfectly and every internet connection is strong, fast wifi. That just means a lot of users (especially poorer ones in rural communities) are going to struggle with what you're selling.

[+] JimDabell|7 years ago|reply
> But my internet connection has a 2 second latency so I still have to wait an annoyingly long time every time I interact with your app. My connection is terrible too, so it drops every 10th request, and now I'm seeing a lot of broken pages.

I often work on a train over a 4G connection, so this describes me too. I much prefer traditional style web applications over SPAs specifically because of this.

You know what happens if a request is taking too long or fails with a traditional web app? I hit reload and it retries.

You know what happens if the same thing happens with most SPAs? It throws away my unsaved data and puts me back on the starting screen.

Sometimes there's a JavaScript-powered retry I can use instead. Sometimes it works, usually it is very unreliable (if something has failed to load, often the JavaScript is having problems too).

Sure, I'm willing to accept the possibility that an SPA can be written in such a manner as to compensate for this hostile environment. It's just: I've used a lot of these apps, and I haven't found one that works reliably over a poor connection yet.

[+] lhorie|7 years ago|reply
> so I still have to wait an annoyingly long time

> it drops every 10th request

If the app saves data to a server, that's gonna happen regardless anyways (and one could argue that techniques like optimistic updates might make the experience even worse)

Also remember that HTML can be streamed and partially rendered even if it's not fully downloaded, and the investment required to enable this is minimal. The same cannot be said about a SPA's data fetching/rendering strategies.

Having worked on bloated apps before, I despise when people throw around the word "prefetching" as if it's some sort of magic spell. At best it eats my battery and bandwidth needlessly, and at worst, it's weasel wording for slowing down time-to-first-pixel :(

[+] timw4mail|7 years ago|reply
I keep hearing offline-first trumpeted, but I have seen no examples of what that means.

Terrible connections exist. But I fail to see how adding more scripting will always help with that. Service workers are definitely promising, but documentation for common use cases is still lacking.

Even with a terrible connection, I would still trust a server-side app to load correctly on a refresh more than a SPA.

If anything, the minimal use of Javascript is as inclusive as a web app can be.

[+] billyhoffman|7 years ago|reply
It’s great that you have an opinion about the benefits of a SPA for slow connections and other people (lower comments on this thread) have opinions about how “easy” it is to implement request retries and caching/service workers.

I have an opinion too. But my opinion and your opinion really are moot.

Because do you know whose opinion is probably backed by the most data and the most expertise? Google’s Gmail team.

And Google, with all its amazing developers, who are arguably at the forefront of javascript standards and general web app innovation, and who have literal billions of visits, they have made the decision to give you a link and tells you to use a basic, server-side rendered web app if you have a “slow connection.” And they do this while attempting to boot up all the PWA/SPA framing of the main app, just in case, I don’t know, all that stuff fails.

So I think I’m going to give Gmails opinion a lot of weight here

[+] prophesi|7 years ago|reply
Did you try using the site with the inspector open with Poor 2G throttling? I was still able to interact with the page within milliseconds. Just had to wait for the font to download before text would appear. Then after that, all of the assets besides the HTML was cached.

I think that's pretty damn good; to solve the 2 second latency, I think the developer is better off using a CDN or Netlify's ADN so that your site is delivered from a server closer to the user.

[+] wwweston|7 years ago|reply
> If only you'd written an offline-first PWA and used background-loading and prefetching with some intelligence to retry failed requests in order to deliver content before I actually need it this would have worked so much better.

This is a unicorn. If it's the real world we're talking about, as far as I can tell client-heavy webapps that are actually engineered this well -- and don't frequently end up in a more inscrutable state than a pageload failure when network issues rear up -- are rare enough in practice that it feels weird to hold that up as the yardstick for criticism.

And if the point is that more applications should get there, well, that's more or less orthogonal to the point of the article, which (in spite of the headline) isn't so much that no one should use JS for anything ever (since the author details the JS he made a thoughtful choice to include), but that a notable range of UI behaviors that are frequently implemented using JS without a second thought don't necessarily have to be, and there are plausible benefits to the alternative. So this isn't exclusive with background loading / prefetching.

[+] jonstaab|7 years ago|reply
Agree that an offline-first PWA is the way to go. Not _no_ javascript, just _as little as possible_. However, I've also not seen such a good example before of how doable this is, so thanks to the author for the show-and-tell. The label/checkbox example is a new one on me, and covers pretty near 80% of my use of javascript. It's interesting how when you strip html of all the DOM api nonsense it starts to look like an exciting new framework. Forms are such a nice, declarative way to get user input.
[+] nicoburns|7 years ago|reply
It's also possible to cache server-rendered pages offline with a service worker. Admittedly not many people do this, but there's no reason why they couldn't, and it would probably be smaller for a lot of sites.
[+] peterbraden|7 years ago|reply
Prefetching is going to waste data in a lot of the world where you pay by the megabyte.

Everything is a tradeoff.

[+] robocat|7 years ago|reply
> it drops every 10th request

Who has good heuristics for retry (or other techniques) to achieve reliable communications for a PWA?

We do retries, with a few different strategies, but we have a poor idea of exactly how effective (or not) our retries are. Also my code for this is ugly and it's a nasty area to test properly...

[+] sametmax|7 years ago|reply
> If only you'd written an offline-first PWA and used background-loading and prefetching with some intelligence to retry failed requests in order to deliver content before I actually need it this would have worked so much better.

Then I would have waited too long to load the page the first time and give up.

[+] ddoolin|7 years ago|reply
These are handy tricks, even in JS at scale, and I'd recommend their usage if you can (big if, business requirements come first for most of us). That said, I don't really buy into the no JS/purism movement for load/execution speed. For bite-sized apps or simple pages, sure. However, it's completely possible and not that hard to develop full-blown web application suites using full JS for everything (structure, style, and function) and not have issues with load or speed. I'm not sure if there's a footgun here, but the issue falls squarely on the developers.
[+] eeeeeeeeeeeee|7 years ago|reply
Seems like once again people just need to pick the right tool for the job. The problem is that people get stuck into one framework and it’s familiar to them so it gets forced into a project it doesn’t make sense for down the road.
[+] smokeyj|7 years ago|reply
The whole thing is a solved problem. You can easily render React apps on the server and send HTML down the wire, then lazy load the rest of the JS. Author could have installed next.js and called it a day.

If you put your app logic in something like Redux it'll work on server-side rendering, client-side rendering, and can be included in react-native down the line.

In the time the author re-wrote his app, I could have gotten the same benefits with SSR and ported it to react native. But yeah, javascript bad REEEE

[+] kabes|7 years ago|reply
> I built the first version of Slimvoice on Angular 1 with a Node.js backend and MongoDB in 2014 (those were all the rage back then). In 2015 I decided to completely revamp the UI and redesigned and rebuilt it in React.

Maybe you should make decisions based on requirements instead of hype. Oh wait:

> Don't follow the hype

But using less javascript is the hype today...

> Plain Old HTML and CSS

This section only shows some very basic UI elements (dropdown, expansion panel, ...). This isn't what libraries like react solve.

> Absolutely nothing is complex about my code

I wouldn't label CSS hacks with invisible checkboxes under "simple and self-explanatory code".

> I found myself wishing for more innovation in the HTML spec

I don't think adding even more bloat to even more web standards than a browser already has to support is the anwser.

[+] pier25|7 years ago|reply
> But using less javascript is the hype today...

I don't know, the hype is usually In React, Vue, etc.

[+] nathan_long|7 years ago|reply
> But using less javascript is the hype today...

Is it? This article on npm weekly (https://medium.com/npm-inc/npm-weekly-133-billions-of-packag...) says 4 billion packages were downloaded in a single week - representing multiple packages per week per human on earth. (Granted, this was Feb 2018, which is 2.8 millennia ago in JavaScript years.)

This site (on which you can't use the back button after choosing a graph) seems to show downloads still growing for popular packages. https://www.npmtrends.com/

[+] MarkMyWordsMan|7 years ago|reply
kabes is to the point! It is fashionable to hate on modern front-end frameworks these days.

Imagine the OP grows their platform/company, hires a bunch of devs, what a nightmare that would be to keep avoiding JS and build on the product.

All so just because using JS is so mainstream, ugh.

[+] hliyan|7 years ago|reply
This is totally true. We've recently started to discover this paradox ourselves: when styling and layout is all done via CSS, and JS + other assets are cached, HTML is just as light weight as JSON over the wire. As ashamed as I am to admit it, our newest innovation appears to be "multi-page apps"!
[+] gambler|7 years ago|reply
I remember there was some ridiculous article here where the author claimed to build world's fastest web app with PReact. It was a hierarchical list of HTML5 features with some tick-boxes. Out of curiosity I converted the giant JSON blob to <ul><li> list. HTML was about 15% smaller than JSON. You could also do most of the "logic" of the app via styling and normal HTML controls.
[+] krapp|7 years ago|reply
>We've recently started to discover this paradox ourselves: when styling and layout is all done via CSS, and JS + other assets are cached, HTML is just as light weight as JSON over the wire.

In other words, when the web is architected as intended, it works fine, even with javascript.

Imagine that. It's like the problem isn't javascript per se, but unnecessary complexity.

[+] combatentropy|7 years ago|reply
Yes, the keys in JSON take up about as many bytes as the tags in HTML.
[+] superkuh|7 years ago|reply
This write-up mostly highlights the loading speed and bandwidth benefits but not requiring javascript is far better than just that. In the age of spectre and with browsers exposing more and more bare metal functionality the idea of running arbitrary code on every random site I go to is absurd. There's dozens of us that simply don't run JS. Sites like these (and, say, the way chicago public media does fallback for no JS) show that there can still be pretty, functional sites without the modern equivalent of opening that .exe attached to a random email.

Thanks and keep up the good fight.

[+] pault|7 years ago|reply
> There's dozens of us that simply don't run JS

Was this intentional? It gave me a bit of a chuckle.

[+] nkrisc|7 years ago|reply
I'm not sure if you meant this or not, but there's text.npr.org. Honestly I'd prefer much of the web this way. I'd be OK with images too.
[+] kaffee|7 years ago|reply
I like the slogan "JavaScript-free"! Finally something to rally around.

I don't mind projects which use a tiny bit of hand-coded, vanilla ES6. Would be nice if there were a slogan that included these.

Looks like it actually does use JavaScript for the "select2" case. This is exactly the case I'd be happy to special case.

edit: added paragraph

[+] didgeoridoo|7 years ago|reply
The term I've usually seen is "JS sprinkles". Not sure where it comes from — maybe DHH in the context of mostly-server-side Rails apps?
[+] tracker1|7 years ago|reply
Honestly, a lot of this comes down to ignorance on a lot of points. You can do a lot with CSS2.x+ selectors, and it's awesome. That said, JS/JSS and component systems aren't bad either. It depends on what you're creating and who your audience is.

Most of this stuff isn't new, it's about a decade+ old at this point. Backend developers often tend to turn up their noses on web front ends, so they don't bother to actually learn anything meaningful, and just sit complaining constantly.

[+] duchenne|7 years ago|reply
How do you guys achieve this in practice?

I made my home page without javascript, and it is blazing fast. But as soon as I try to make something more complicated I bumped into practical problems.

- Components. I want to have the same navbar on all my pages, but I don't want an un-maintainable copy-pasted code on all my pages.

- Data. I need to display some data that is different for each user. How do I embed it in my webpage without ajax calls?

- Dev tools. I need debugging / bundler / source maps.

Some possible solutions could be:

- PHP. It has components through "require". You can embed the data easily. But, I do not know good dev tools: If I debug the javascript in the chrome dev tools, can I edit directly the php script? Can I minify/babel the output of the php code? And I cannot use the same php code on both front-end and back-end.

- Vue-SSR. Nice one-file components. Data can be provided within express. I can re-use the same code on the front-end. I have not tried yet, but it seems very interesting.

- EJS. It has require and data from express. It is very simple too use. But the tooling is lacking: no source map.

[+] _bxg1|7 years ago|reply
"Why can't we have a standard search element that filters a list on the client side (similar to how ng-repeat | filter: worked on Angular 1)?"

It's pretty new, but: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/da...

"Wouldn't a standard HTML element for drag-and-drop sorting be awesome?"

There is a standard drag-and-drop API, but unfortunately (bafflingly) it's imperative/event-based, not declarative. Seems like it would be simple for them to add HTML hooks that use the same underlying code.

[+] gambler|7 years ago|reply
This is pretty much how I develop most of my web stuff. I do use JS, but it comes in afterwards, in discrete packages. It process specific HTML attributes to make the page do extra stuff, or accelerate certain operations, or stich pages together via AJAX. All scripts are stateless, because all state is stored in HTML.

The key is to represent your data and UI state via sane HTML. This article demonstrates this well with the modal popup example. Once you represent popup's state with a checkbox, you can manipulate that checkbox in any way you want and you can style it in any way you want and your styling will not have any dependencies on the methods of manipulation.

[+] RobKohr|7 years ago|reply
I think this ignores one of the main benefits of JS based page rendering.

In the days where I worked on PHP apps, all rendering was done on the server, and that came at a great cost regarding server side processing and the complexities of peak load times, along with some pretty hairy test cases.

With everything rendered in js, you are mostly just transferring static assets, so the browsers are doing the heavy lifting for you. The only things that end up taking up server CPU cycles and system memory were API calls that are easy to test, debug, and optimize. Also, those API calls can be cached, and become static assets for high traffic apis such as ones accessed on the front end.

If you do it all on the backend, you are doing all the rendering work, and it is hard to split off and optimize processing time for things.

Finally, for testing, it is really easy to unit test an API, and for javascript frontend work, there doesn't seem to be the code regression type bugs that are so time consuming, but when you mix the data api stuff with the front end rendering, unit testing becomes a big mess.

Bloat needs to be thought about, especially for limiting bandwidth, but just for curiosity, I checked out my own website which was using React and a bunch of libraries, and it was only 500K. This is about half the size of the banner image on that article. Some libraries are much larger than React, but going JS free and losing the power React gives you doesn't seem like a good trade off.

Of course if you get some happys from being an ultra-purist, then I get that, and that is priceless. From a practical perspective though, this seems misguided.

[+] sbr464|7 years ago|reply
Nice work, I definitely appreciate the focus on simplicity/speed. I just signed up to check it out.

I noticed on the invoice page, on mobile, the number inputs (qty, price, etc) showed the full alpha keyboard on input. I think you can add a few attributes to optimize, without using JS also.

Great work, thanks for sharing.

This link has been helpful for me:

https://developers.google.com/web/fundamentals/design-and-ux...

[+] anthony_doan|7 years ago|reply
There is something like that the Elixir web community is trying to do with Liveview, Texas, Morphling and Whistle. Several competing libraries doing the same thing I believe, I've only seen Texas and Liveview in action.

The whole point, iirc, is to manipulate the DOM on server side and push those changes via a websocket. So the DOM manipulation is on server side and the code is server side language Elixir.

There was a demo for Texas and Liveview which show pretty good performance. I'm not sure if it is good enough performance but it looks promising.

Video for Texas: https://www.youtube.com/watch?v=NWgwUKfR8Xg

Video for LiveView: https://dockyard.com/blog/2018/09/12/liveview-project-at-eli...

[+] Justsignedup|7 years ago|reply
It is hard to argue against using JS. I tried that no-js approach as much as possible in the past, and hated it. Using React for front-end development and keeping bundle sizes small through good build processes is amazing. I genuinely enjoy building web front-ends now because of it, where as before I avoided it like the plague.
[+] roywiggins|7 years ago|reply
A nice way to progressively enhance something like this is to use Intercooler.js when you do want to update only part of the page. You're still just slinging HTML back to the browser but it lets you update only part of a page without using iframes or something, and since you're just adding data-attributes to links and forms, you don't write any javascript.
[+] stcredzero|7 years ago|reply
Slimvoice - A Webapp Without JavaScript is a series where I document how I rebuilt my app, Slimvoice, using as little JavaScript as possible.

Here's a recurring story in the programming field.

A new variation on technology is highly successful. The field starts using it enthusiastically, but doesn't keep track of the costs and cost/benefit. The new tech gets rather overused. Some people come out with optimizations. (Usually involving what amounts to caching.) Other insightful contrarian people take a minimalist approach. Rinse and repeat.

Once aware, one can spot this cycle happening. It is left as an exercise to the reader, how this can be used to profit.

[+] ryanmarsh|7 years ago|reply
While I understand the concern about bloated frontends, I do not understand the throw-the-baby-out-with-the-bathwater mentality of JavaScript-free front-ends.

Furthermore I feel like there's a misplaced sense of pastoralism or nostalgia about the-web-before-JavaScript. The fact is there was a very brief period where the World Wide Web was both widely accessible to the public and JavaScript free. I built my first website without JavaScript in 1995. By 1997 I was building incredibly interactive single page apps in IE4 with JavaScript and DHTML (as it was called at the time). By 1998 my full time job was writing cross-browser JavaScript. That's twenty years ago folks. jQuery didn't hit the scene until 2006. Why was jQuery created? Was it a revolutionary new tool that gave us the ability to create applications that heretofore had never been seen? Or, was it created to tame the horrendous mass of JavaScript that had already accumulated?

We can talk about bloat, but let's be honest about what the web browser is now. Chrome is an application container. The web hasn't been purely hypertext for a long time. Back when it was we complained about the bloat... of images

[+] andrewfromx|7 years ago|reply
100 percent agree. Use as little JS as possible on front end. And then definitely use zero JS on backend.
[+] tracker1|7 years ago|reply
Definitely...only use C on the backend, any other language is just a hack.
[+] 52-6F-62|7 years ago|reply
That seems a bit extreme. IMO that's a bit like saying "use zero Elixir/Erlang on the backend". I think a few people would take more contention with that line—and they're both languages running on VM's with a specific performance target.
[+] brlewis|7 years ago|reply
I like this article, but the title is misleading.

"I did actually use some JavaScript on the new Slimvoice, but only when an interaction could not be replicated in any other way."

Overall, the article does point in a good direction.