6

Progressive enhancement as a valuable philosophy in the age of JavaScript

 3 years ago
source link: https://sourcediving.com/progressive-enhancement-as-a-valuable-philosophy-in-the-age-of-javascript-aac2e26364d2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Progressive enhancement as a valuable philosophy in the age of JavaScript

Image for post
Image for post

Not that long ago, browsers disabling JavaScript or simply lacking support was an important concern when developing for the web.

Words like “progressive enhancement” and “graceful degradation” were often heard, even spawning battles and generally heated discussions on the subject.

Today, it can pretty much be assumed that JavaScript will work everywhere.

It is therefore at the risk of reviving a cold case, that we in this post share a few reasons why - in spite of all that - we at Cookpad follow this approach and still believe it to be relevant.

OK, let me turn off JavaScript in my browser real quick

Note that this isn’t advocating a purist approach of “everything must work with JavaScript disabled”.

As Rails developers, we are more than happy to make use of the default toolbox of rails-ujs and turbolinks that makes the framework so powerful.

Instead, we’re concerned with practical benefits of using the philosophy when considering any JavaScript we layer on top of that foundation.

Benefit 1: Drives out good code design

When working from a rich design mockup complete with in-page transitions, animations, and all the client-side bells and whistles, the impetus might be to immediately reach for JavaScript.

Take something like a modal login dialog, that when activated is overlaid on top of the current page content:

Image for post
Image for post

One might be tempted to implement it by f.ex. having some hidden content in the header template that gets revealed using JavaScript when clicking the link:

However, what if we instead, at least as the first version, simply did a full page load showing a blank page with a similar modal-like layout?

Image for post
Image for post

Certainly, the difference in UX is noticeable, but not hugely different?
The implementation could look like something like:

This immediately gives a few design advantages:

  • Everything now sits nicely in a dedicated place: authentication-related HTML can be found in /authentications.
  • We’re not cluttering our header template with markup that’s hidden most of the time.
  • The login page has become linkable, which could come in handy for f.ex. authentication control on other pages.
  • Should we need to add any extra logic such as tracking or exposing more variables to the login form, we now have a natural location for it to live:

We might have struggled with finding a place for this when everything was client-side or been forced to add more JavaScript to make it work.

Applying progressive enhancement

We could then always explore sprinkling on a bit of JavaScript to get the best of both worlds by f.ex. using AJAX to load the content of our newly created endpoint:

This allows us to keep a nice code structure while still having good UX.

We might not have arrived at this solution had we gone instantly to a JavaScript-first implementation!

This is just one example, but in much the same way as f.ex. restricting oneself to the 7 RESTful actions of Rails helps reveal missing models or controllers, applying a constraint like progressive enhancement can often tease out a better design.

Benefit 2: Faster tests

With the advancements of system tests and headless drivers, JavaScript-driven features have now become much easier to test.

Depending on your framework of choice, to test the full stack, including any JavaScript, in a headless browser, it’s usually a matter of adding the following to a system test:

driven_by :selenium

These tests however still come at a substantial cost.
Using our modal example above, here is what a test might look like:

In our app, running this test locally with the default Rack::Test driver results in:

Finished in 3.55 seconds (files took 2.33 seconds to load)1 example, 0 failures

The same spec run with Selenium takes more than 3 times as long to run:

Finished in 11.26 seconds (files took 2.31 seconds to load)1 example, 0 failures

Now imagine also wanting to test a few edge cases, such as failed login, validations, etc. Those slow specs will quickly add up, and we haven’t even touched on the fact that tests involving JavaScript tend to be more prone to random failures.

If we have a version that also runs without additionalJavaScript, we can reserve the slower Selenium test for just the happy path and take advantage of the faster fallback version for everything else.

Benefit 3: Shorter time to release

As seen above, adopting the progressive enhancement mindset often pushes developers to think of a simpler version of a new feature.

Additionally, we don’t have to spend time up front writing and testing JavaScript, so overall we should be able to release the first iteration of the feature more quickly.

Although the first version may not be “flashy”, designers and end users will be able to get their hands on and start using the feature sooner.

This is where at times it turns out that the basic version might just be good enough.

At the very least, it allows the team to have a discussion as to whether it’s worth investing more time in enhancing it further.

Benefit 4: Smaller pull requests

At Cookpad, we care a lot about keeping pull requests small and easy to review.

One approach we use is top-down development combined with shipping in-progress code behind feature toggles.

Progressive enhancement fits very well into that approach!

If a reviewer can first see an implementation using no more than the basic HTTP request & response cycle, they will be a lot less overwhelmed than if they also have to take a bunch of JavaScript into consideration.

Any subsequent pull requests enhancing the UX of the existing feature will then allow reviewers to concentrate on the JavaScript and give more focused feedback.

It’s not unusual to see pull requests like this (note the small diff size):

Image for post
Image for post

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK