Progressive Enhancement Is Dead
tomdale.net
tomdale.net
This statement needs a huge, HUGE caveat that you should only be building 100% JavaScript apps in situations where doing so makes sense. For example, I find the new Blogger "web app" infuriating. I shouldn't have to stare at a loading screen to read a half-dozen paragraphs of text, that's just stupid. Just serve the HTML. No one is going to "fall in love" with your app if your app shouldn't exist in the first place because the old-school solution provided a superior experience.
(This is, of course, a generalization; specific use cases may vary.)
Take a look at discuss.emberjs.com, which uses Discourse (which is powered by Ember... INCEPTION):
On the front page, every navigation, including the links on top and the links to individual forum posts, are <a> tags with an href. When you navigate to a forum post, the buttons to reply, flag, favorite, etc. are all <button> elements.
You definitely want to be (1) using a framework that encourages the use of HTML for the view layer, and (2) using a framework that makes URL-based navigation easy. There's nothing about JavaScript-based applications that make semantic markup and URLs impossible, and today's screen readers don't care whether your HTML was rendered using JavaScript or from the server.
I think you're jaded because the previous generation of frameworks (SproutCore, Capuccino, Ext.js) shunned HTML in favor of all-JavaScript UI toolkits, but that framework style has fallen out of favor. HTML is here to stay.
1) <button {{action "removeTodo"}} class="destroy"> (a button) 2) <button id="clear-completed" {{action "clearCompleted"}} {{bind-attr class="buttonClass:hidden"}}> (a button) 3) <label {{action "editTodo" on="doubleClick"}}>{{title}}</label> - not a button, but a requirement of TodoMVC. It would be nice if TodoMVC had a <button> marked edit that achieved the same goal.
There is also a subclass of <input>, which:
1) Automatically focuses on insertion (native focuses are properly handled by screen readers) 2) Clears out the Todo if the text becomes empty and the user hits return (somewhat screen-reader friendly, and a requirement of TodoMVC)
What am I missing?
My belief is that if you were able to produce good markup, it would have been accessible from the very beginning, because accessible markup tends to be well-formed and semantically correct.
This would probably rule knowledge of WAI-ARIA out from everyone who fit parent's case.
i understand your newly found js excitement with your full ember.js app, but do'nt forget the lessons from java the browser plugin and flash.
1. ok you re real time, but don't assume i m watching your site like a tv
2. dont consume my precious cpu power.. otherwise app throttling will come to browser tabs..
3. dont end up in lots of clientside errors due to various problems, including local storage.. twitter mobile client is an abysmal example where tweets are lost on screen and inc mobile is another with empty ehite pages
However I don't think citing the problems with Flash and Java Applets is applicable. JavaScript maturity is explicitly the long-awaited remedy to the problems of those bolted-on runtimes. It's true that bloated over-the-top CPU-hogging monstrosities will be done with JS as with prior technologies, but there's no technology that is immune to that.
FWIW, Ember is pretty performance-oriented and lets you get a lot done with a very low code / performance / byte overhead.
Being able to CURL any page on your site and parse it using standardized, agreed upon tag names is a feature.
But the vast majority of my users don't even know what cURL is, so why should I worry about this? And in any case, I believe that if I wanted to extract content programmatically, consuming the same API that the Javascript uses to fetch content would be much easier than extracting it from HTML.
Tell me, why should you be lazy just because you think the vast majority of your audience are fools and won't notice?
Airbnb's recently released Rendr library (https://github.com/airbnb/rendr) is a great attempt to make this easy for complex web apps to do.
Oh, and I get to test two code paths, and all of the wonderful ways they might interact!
- If you have a website that people will come to then spend a bit of time in different views (like gmail, facebook, or an analytics dashboard), it will usually pay off to dock the initial load time a bit in exchange for much faster loads of subsequent views. This is the base tradeoff made by switching to client-side rendering.
- If you have a website where most people will come check out one page then bounce (like a news site, a blog, a page with directions or info, anything where an article will be linked to rather than something that's used like an app), you won't want to make that same trade, since the extra blow to load time initially is going to hit most people and they won't see the benefits of the reduced load time for slowly adds up as you hit more views on the page, because they will read the info then leave.
Any page can be built as a single page app, and many people will do this automatically since it's the new hotness. But the question we should be asking ourselves is whether what you are building actually will be used as an app or not. I'll close out with an interesting example:
If you are building a news site, you should not build as a single page app because it's likely that you'll have a lot of single page views and a high bounce rate. Those single pages should be rendered as quickly as humanly possible. However, if you are building something like a feed reader, the situation would be the opposite. People will likely spend a bit of time in your interface reading a variety of articles, so the additional load time at the beginning will quickly pay itself off in faster renders for each item they read.
EDIT: An interesting approach for a news site would be to render single article views straight from the server or have them compiled, but render their homepage as a single page app. Tailor different parts of your website to the way that they are viewed. Has anyone written about this? Maybe I should write about it...
Bustle is an example used by Tom Dale, and their js app is what? Not even 150kb? your headers alone are probably slowing you much more than this.
Locking the UI is bad, but it's not all JS apps that lock up the page as the browser puts it all together. You just need to know how the browser reads your styles and scripts and put them in the right place.
Blogger is sadly a dog and has been for the longest time. Profiling it just now, some of the blocking JS dependencies take > 800ms to load. Frankly there are many things wrong with it, but it should not serve as an example of a well designed JS web app.
If I click on a link on your page and you have a faster way to get me there than a full page refresh then great, let's do that. On the first page load, though, there is no good excuse to make me request the site template and the content sequentially and smoosh them together myself. Do that on your end.
Speaking as somebody who's been in that case, no.
1. The app manifest doesn't need "JS-based apps", they're indepedendents
2. Assets caching doesn't need the app manifest either
3. Stop breaking stuff which works. HTML works, your shitty application does not.
I quote 10ms as client side code to produce the new HTML and browser painting events can take time, but if you used a canvas or similar you could cut down even further on that render time.
If you are doing something that requires Turing-completeness, you're doing something that can't be done on real computers, because any collection of digital hardware can be represented as a (flippin' ginormous) finite state machine.
Of course, there will always be cases where server-rendered HTML will be more appropriate. But that’s for you to decide by analyzing what percentage of your users have JavaScript disabled and what kind of user experience you want to deliver.
Seems like a pretty big caveat to me.
If your 'app' is just a web page — use a web page!
Performance is paramount. On many smartphone browser tabbing out while I wait for your slow-assed page to load and render isn't an option like it would be on the desktop. I feel the pain of every lazy-loaded image, every sluggish layout script, etc. Many "responsive" pages are actually the worst culprits.
Yes, I need a new phone. But older smartphone browsers aren't exactly a rare use-case.
Edit: Here is another example from the past few days that's unusable on mobile: https://news.ycombinator.com/item?id=6302825
This is a common problem with media sites. I dread trying to load quartz, usa today, gawker, etc since every thick-client media site is intermittently a bad citizen on mobile browsers (for example, gawker in Chrome on iOS currently perpetually reloads the page). Even when these kinds of sites work, there's often a multi-second delay where where the user has to sit and watch elements fly around as the page is built.
Edit again: just to be clear, if you are a non-technical product manager or CEO type, my comment should not be interpreted in any way as an implication that the web or JavaScript is somehow inherently bad and therefore your developers must build a "native app." My comment's intended audience is developers with a deep, working understanding of these technologies.
Not just mobile browsers. They are horrible everywhere that isn't chrome or firefox.
The problem is pages that require javascript to display static content. There are very few good reasons for an article, or an image gallery, or a homepage that could have been displayed just fine a decade ago to now need javascript so it can do some stupid flashy thing that breaks the expected interface behaviour. And frankly, that's most of what I'm seeing in "Sigh, Javascript."
Sure, you could add, say, auto-loading for new comments when you reach the bottom of the page, or setting the message icon to orange when you get a reply, but that hardly requires a full-blown web app, it's a simple addon to a static site.
If the core of the content is or should be text, then there's no need for countless silly layers around it.
99.99% of the people visiting my site have JS enabled and I'm happy to support them just fine without worrying about the really long tail.
And this is only an issue for pages where you actually want to expose your content to search engines.
_escaped_fragment_ is a stupid hack that requires hardest bit of work needed for progressive enhancement, but provides none of the benefit.
Asking Timmy to "step up his game" is heartless, and it'd be unnecessary if we were better citizens.
I've never seen an example where Google crawled a page and included content that was loaded via ajax or an external javascript file. I have seen Google index content that is loaded from a script tag included in the html page.
However, from working with customers of BromBone, I know this. People have javascript powered webpages that were not getting indexed by Google. Google would crawl the page, and see no content. The pages were not in Google. After creating prerendered snapshots and serving them when the _escaped_fragment_ parameter was present, the pages showed up in Google.
And if you use html5 pushstate you could even serve the HTML captures to any bots. Eventually you also could easily add graceful degradation to your site serving snapshots for non js users. As of PoC for SEO4Ajax (http://www.seo4ajax.com), I built this application (http://www.appscharts.me) illustrating this purpose.
You are right about one thing, it is a pain to setup. Much harder than it sounds at first. After doing it a few times, I finally got sick of it and built http://www.BromBone.com. It's a service that takes generates the html snapshots for site owners and keeps them up to date. I hope it will let site owner keep all the positives and eliminate most of the new negatives.
I make this assumption because most of us don’t actually know how Google works, acting as a user’s proxy is in Google’s interest, and it is certainly within their technological capability. (Let me emphasize assume, again.)
This would require that the crawler actually renders sites, indexes the resulting DOM, and clicks what can be clicked. A headless Chrome, perhaps.
"Use a text browser such as Lynx to examine your site, because most search engine spiders see your site much as Lynx would. If fancy features such as JavaScript, cookies, session IDs, frames, DHTML, or Flash keep you from seeing all of your site in a text browser, then search engine spiders may have trouble crawling your site."
With regard to Google, however, they are explicit in their support for JavaScript rendered sites:
https://developers.google.com/webmasters/ajax-crawling/docs/...
Amongst many other links.
Do you know that for a FACT, or are you just guessing?
If you don't have javascript enabled...
You don't get to define what the baseline correct thing is for a business, profit does that. Progressive enhancement is more work than simply presuming JavaScript is always available; that's just a simple undeniable fact.
That's what I am using.
>Progressive enhancement is more work than simply presuming JavaScript is always available; that's just a simple undeniable fact.
I am denying it right now, that is the whole point. Server side templates with simple javascript enhancement has been much faster for us, and much easier to maintain.
I simply don't believe you. It's a fact that it's more work to support both AJAX interactions and work with js disabled than it is to support just AJAX alone. There is no arguing this, it's more work to support 2 modes of interaction than it is to support only 1. You may find it a comfortable workflow for you, to start with vanilla HTML and then progressively enhance it, but regardless of how much you like the style, it is more effort and does have more long term maintenance costs to forever support 2 modes of interaction. No one who isn't completely full of shit would argue that progressive enhancement is less work.
That is not a fact. It may well be your experience from the way your applications were written, but it is not a fact. You clearly do need a lecture, or you wouldn't be posting garbage.
That's certainly not how I calculate revenue...
The fact that the JS frequently results in lower usability is biggest on my list. I've encountered Blogger themes which are so fucking piss-poor I literally cannot read them, even with JS enabled.
If the primary goal of your site is content, stick with vanilla HTML. You're vastly better off for it.
It doesn't look like it is too difficult to add search indexing support.
http://eviltrout.com/2013/06/19/adding-support-for-search-en...
We all want wonderful experiences as users. The crux is almost a question of "how we want things to be" and "how we want to get there".
For me, the 100% JS MV movement is wonderful for a specific genre of app: An app that is:
* Behind an intranet
* Behind a paywall
* Behind a login-wall
* Prototypes / Demos / PoCs / etc.
But for the open web -- wikipedia, blogs, discussion forums, journalism (etc.) this movement detracts from the web as a whole, in that it excuses developers from having to worry about degraded and/or non-human consumption of their websites' data.
We have to ask ourselves what we, as humanity, want from the web. Do we really want a web of 100% bespoke JavaScript MV web-apps with no publicly consumable APIs nor semantic representations? If that is the intent and desire of the developers, designers and otherwise educated-concerned web-goers, then fine, let's do that and hope it works out okay...
But there is an alternative that has its roots already planted deep in the web -- the idea and virtue of a web where you can:
* Request an HTTP resource and get back a meaningful and semantically enriched representation
* Access and mash-up each-others' data, so as to better further understanding & enlightenment
* Equally access data and insight via any medium, the latest Chrome or the oldest Nokia
So, please, go ahead and create a 100% JS front-end but, if you are creating something for the open web, consider exposing alternative representations for degraded/non-human consumption. It doesn't have to be progressively enhanced.
Imagine for a moment if Wikipedia was one massive Ember App... And no, Wikipedia is not an exception from the norm -- it is the embodiment of the open web.
Seriously, open up any Ember.js app and look at the network traffic. You'll see a series of requests, usually using very RESTful URLs, that requests the document.
The only difference is that, instead of HTML, where you are conflating the markup and the content, you get a nice, easily-consumable version of the document in JSON form.
There is literally no change to the web here, other than the UIs are faster and better, and it's easier for me to consume JSON documents than trying to scrape HTML.
How would you reconcile the need for an open-semantic-web with arbitrary JSON structures with no governing semantic standard?
EDIT: An example of a potential problem: Please take a look at how the Bustle app you referenced brings its article content to the front-end:
E.g. http://www.bustle.com/articles/4470-why-we-should-root-for-l...
View source. It's not a public REST API (not visibly so); it's awkwardly embedded as literal JS in the HTML document itself... That'd be hell to publicly consume through any kind of automation.
Is the HTML of any popular website publicly documented? Is there any guarantee that an XPath to a particular value won't change? Is there any guarantee the data I need is marked up with semantically accurate class names? No.
HTML is intended for public consumption—by a human, at a particular time. It is not a data interchange format.
Contrast that with things like Twitter or GitHub, which provide a versioned JSON API that is guaranteed not to change. Your web site becomes just another consumer of that API.
JSON contains all of the data you need, but in a way designed to be consumed by computers, and you don't have to do all of that awful HTML scraping.
And as for Bustle not having a public JSON API, well, here you go:
curl -H "Accept: application/json" http://www.bustle.com/api/v1/sections/home.json
A versioned JSON API that is guaranteed not to change. Can any public site on the internet guarantee that about its HTML?
Regardless of this entire PE debate, we would still have a problem, on the web, of data being out of reach due to walled apps that only serve rubbish HTML.
The problem of open + semantic data is very relevant to this discussion but we're pretending that one "side" has all the answers. I want a better web -- more open -- more semantic -- and maybe some shimmer of a truly semantic web[1] will emerge in the next 20 years.
So, yes, a 100% JS App is 100% awesome if, IMHO, it has:
* A publicly documented and consumable REST API
* Semantically enriched data through that API
* Some kind of degraded state NOT just for search-engines but for older devices and restrictive access (e.g. behind national/corporate firewalls)
I am not interested in being one side or another regarding this PE feud, and I am sure you're not either. I am trying to question what is best for the web and humanity as a whole. I don't think we have a silver-bullet answer. I do think it's necessary to dichotomize walled web-apps and open websites, and the latter deserve additional thought regarding usability, accessibility and semantics.
Bustle.pageData.article.title
couldn't have been extracted from <article itemscope itemtype="/article">
<h1 itemprop="title">Why We Should Root for Lamar Odom</h1>
...
</article>Should I mark my concrete item as flingy where some elements are thingies or should that be a thingy with some subelements as flingies?
I just did my best and called it a day. Then spend a lot of time debugging it in the microdata analyzer tool.
<article itemscope itemtype="/article">
<h1 itemprop="title">My Title</h1>
<div class="related-thing" itemscope itemtype="/author" itemprop="author">
<h1>
<span itemprop="firstName">John</span>
<span itemprop="lastName">Smith</span>
</h1>
</div>
<aside class="incidental-unrelated-thing" itemscope itemtype="/sausage">
<span itemprop="type">Cumberland</span>
<span itemprop="ingredients">Mystery Meat</span>
</aside>
</article>
in the example above, we define an article that has a related author property, that author property is its own scope so has firstName and lastName properties of its own. We also define an unrelated itemscope (unrelated because it has no itemprop) that happens to be nested in the same element, so this would parse to: [
{
"type": "/article",
"properties": {
"title": ["My Title"],
"author": [{
"type": "/author",
"properties": {
"firstName": ["John"],
"lastName": ["Smith"]
}
}]
}
},
{
"type": "/sausage",
"properties": {
"type": ["Cumberland"],
"ingredients": ["Mystery Meat"]
}
}
]HTML is not perfect, but at least you can usually pick out which bit is the title and which bit is the article content through some heuristics.
That's an interesting definition of "public JSON API" you are using.
* Where is the public documentation for this endpoint?
* Given an ember app, how do you arrive at that URL? (Previously you mentioned watching network requests from a browser to discover the URL endpoint, I think that's particularly unsuitable way of discovering a public JSON API)
* Where's the schema definition of that JSON blob?
That's as much a public JSON API as "curl http://en.wikipedia.org/wiki/Louis_Boullogne" is a public HTML API. And at least with the wikipedia one, there is some defined structure and implied meaning to the data coming back (i.e. standardised HTML elements).
"A versioned JSON API that is guaranteed not to change."
How is that guarantee enforced? What prevents a developer from changing the nature or structure of the response at that URL?
It aggrevates me when a site that I try to open because of its textual content takes 30 seconds to render since there's too much Javascript going on. Then I'm typically sitting there thinking: "how hard can it be to display a piece of text?" Because of this, when I see my CPU spike as I try to open a website in a new tab, I very often decide to simply close the tab again and do without the information I originally came there to see. This happens a lot for me with online magazines, such as wired or techcrunch. One trick is to invoke the "Readability" bookmarklet if I can get to it fast enough, i.e., before the JavaScript has frozen my browser completely.
Of course I understand that I am part of a tiny minority. And probably I'm not part of your target group anyway. And the web is so much more in 2013 than pages with text on them.
If you do, however, want someone like me to come to your site, you better remember to keep it dinosaur-friendly.
Besides we're all minorities in one way or another. I'm sure I could find some dimension by which you're a minority and you'd be pretty cheesed off if you weren't catered for for some trivial reason.
How about we say it's fine replacing text with images? We could always use alt tags for accessibility. The number of people who ever actually select/copy text from your website will be <1%, so why not just do away with it and get the text in any font we like, with any rendering style & layout we like?
Not to mention that any decent screen reader should surely be decent enough to extract text from an already rendered page (I mean christ, we have testing frameworks that can basically do this already).
If building apps using purely JavaScript breaks screen-readers, we need to fix screen readers. If our applications aren't working for people who insist on browsing with lynx or whatever, well, for shame.
Honestly though, another factor of "JavaScript only" things is that it means that some sort API is exposed to the client, so if it's really such a massive problem, just pull the JSON and parse that into something readable.
The idea that it is actively shameful to use Lynx is strange and antithetical to the way the web was originally designed - the user agent is SUPPOSED to be in control of presentation, the markup is SUPPOSED to be semantic.
I absolutely think there's a place for a text-based browser still, however, one that is designed with modern considerations.
Of course it is, but it's clearly an admitted strawman.
What's wrong with people these days? You can't rhetorically explore someone's views without everyone jumping in and shouting "strawman" as if it's their new favourite word.
A strawman -- which, as you admit, this was -- is very different from "rhetorically exploring someone's views". Its "rhetorically exploring something distinct from the views of your opponent, and using it to impugn the views of your opponent."
Which, you know, makes people upset.
No, it isn't. You are making the mistake of conflating a strawman with an argument built on a strawman as a logical fallacy.
> No, it isn't.
Yes, it is.
> You are making the mistake of conflating a strawman with an argument built on a strawman as a logical fallacy.
No, I'm not. If you are exploring their views rather than yourself constructing something new and distinct from their views, you aren't making a strawman, whether or not you also, implicitly or explicitly, are arguing against their position using whatever you are exploring, which would be the strawman fallacy in the case where you were constructing a strawman.
No, it really can't. Using something meaningfully distinct to "explore" their views is the exact same logical fallacy as using something meaningfully distinct to "argue against" their views. What you are dealing with is something distinctly different than their views, whether you are "arguing against" it or merely "exploring" it.
And, even if it could, it still wouldn't be equivalent to exploring their views, so being called out for using a strawman when using a strawman -- for whatever purpose -- woudl still not be being called out for using a strawman whenever you rhetorically explore someone's views.
1. People who are part of a minority by choice. For instance, they choose to use an old computer, old OS, old web browser, etc. even though it is within their means to upgrade. Or they have current software but intentionally restrict it with add-ons like NoScript. You might be justified in not catering to these minorities, because it's just not profitable and you have no moral obligation to do so. Maybe the GP falls in that category; I don't know.
2. People who are in a minority through no choice of their own, and have no power to change their circumstance. One example would be a poor student or job-seeker who's stuck with an old computer and can't do anything about it. People with disabilities also fall in this latter category. I know someone who once lost a job because he is blind and some inaccessible software barred him from doing that job. He described how that felt in this blog post:
http://blindaccessjournal.com/2006/02/torn-from-the-collecti...
All that to say that your comment is quite insensitive. Those are real people in that small minority, and depending on why they're in that minority, we developers might have an obligation to accommodate them.
EDIT: Yes, I know that JavaScript apps can be accessible.
I fully understand making a site accessible for those who need it, but I don't understand the NoScript people.
Also, if you don't have an unlimited Internet plan, not having to download 5MB of trackers, "analytics" scripts and Flash ads can be a pretty significant advantage.
Are you sure about your numbers? How do you know that people with javascript disabled are a minority? Or, more specifically, how do you measure that without requiring javascript?
I'm all for making web applications that need javascript. But let's do it for the right reasons, not because "everybody has javascript installed".
The author does very little to support his claims. The Boston Globe page also has lot of scripts to support advertising and the advertising itself. As well, entirely different engineering teams and probably cultures. There's not even any research into The Boston Globe's use of progressive JS; it makes ZERO sense why the two homepages could not have the same JS footprint, with The Boston Globe continuing to work and Bustle continuing to not work, while JS is disabled.
I'm all for not supporting progressive JS; Bustle is certainly within their right to not work without JS; the author is just caught in a confirmation-bias bubble. His conclusions don't make sense; our intuitions are right; it doesn't take [much] more JS to progressively enhance a site.
This is the key bit.
It's a pretty popular attitude on HN to dismiss supporting IE, or IE7, or even IE8 or IE9 -- despite having significant user bases. But there's still a strong vocal contingent which argues for webpages to still work fine with without JavaScript, despite it being a miniscule user base. They both seem to come from philosophical standpoints, rather than anything practical. (Granted, SEO is a valid consideration, but that's fundamentally a different conversation.)
In general turning documents into programs deprives users of those documents of a kind flexibility that they enjoyed when documents were just data.
And does it not bother you that web-browser development has gotten so complicated and labor-intensive that there are exactly five organizations with the resources to maintain a web browser?
What hope do operating systems with very small userbases like Plan 9 have of ever running a web browser capable of displaying correctly the majority of web site?
Browser complexity closes off certain opportunities: e.g., about 15 years ago, a blind programmer named Karl Dahlke wrote a "command-line web browser" called "edbrowse" that has a command language similar to the line editor ed. Is it OK with you that the fraction of web pages browsable with edbrowse keeps going down?
Another way that making the web a richer application-delivery platform reduces the options available to users: approximately nobody bothers to maintain a local copy of the web pages they have browsed (which would be among other things a useful insurance against web pages disappearing from the web) because it is so complicated to do.
And then there is the loss of consistency useful to readers. For example, when you click on a link, then hit the Back button, the browser used to always put you back at the same place in the web page that you were when you clicked the link. Not anymore: for example, if you click a search result on hnsearch.com, then hit Back, you are taken to the start of the web page containing the search results with the result that you have to scroll through results you've already sifted through just to get back to the state of progress you were in when you clicked the link.
A possible reply to that is that the maintainer of hnsearch.com should fix his web site. But the number and variety of "losses" or "regressions" like that one is so large -- and increasing so fast -- as to make me doubt that webmasters will ever get around to fixing most of them, particularly since webmasters on average are less technically knowledgeable than, e.g., programmers are.
Selecting an extent of text in preparation for copying it is another thing that has become less consistent and controllable over time: sometimes when I just want to select a few words, slight movement of the cursor while dragging will cause an entire adjacent column of text to be selected or de-selected according to rules that are essentially unknowable to the reader.
In the past, for about 15 years, the space key consistently meant "scroll down a screenful" (provided the page as a whole has the focus -- as opposed to, e.g., a TEXTAREA in the page). The desire to turn the web into an applications-delivery platform caused the web site to gain the discretion to map the space key to something else, which is a gain for authors of web apps, but a loss for readers who used to be able to depend on consistent behavior from the space key.
In summary, although I am happy that many thousands of applications developers are now able to make good livings without becoming a "tenant" or a "captive" of a platform owned by a single corporation, I am sad about how complicated, tedious and mystifying it has become to use the web to consume static content -- and how expensive (in programmer time and effort) it has become to put static web content to uses not foreseen and provided for by the author of the content.
Increasingly, site design does little but piss me off. I use a set of tools, Readability and Stylebot included (484 styles and counting, several of those applying to multiple sites) to address the more severe annoyances (H/N is one of my restyled sites). What's particularly annoying are content-heavy sites (blogs, online periodicals) which break Readability and/or aren't restylable with Stylebot (I recenty encountered a Blogger template which navigated to a different page when I tried editing CSS in the Stylebot editor).
In the original article, Tom notes:
At some point recently, the browser transformed from being an awesome interactive document viewer into being the world’s most advanced, widely-distributed application runtime.
That's pretty much the conclusion I'd reached, though my preference is that tools which are useful for presenting and managing content would be developed: https://plus.google.com/104092656004159577193/posts/LR7jubsX...
Readability is useful, but addresses only a subset of the features I'd like. I've been collecting a large set of literature through it and using Calibre. In particular I want bibliographic capabilities and indexing, as well as much larger tag lists (I ran into Readability's 500 tags per user limit within 3-4 days).
The other problem with JS is that I'm increasingly running into single Web apps which consume, literally, a gigabyte or more of memory (Google+ is perhaps the worst of these).
Which means: I could run a lightweight desktop application which provides a basic set of functionality ... or I can run a browser with perhaps a handful of tabs open, and absolutely pig out my system.
The browser is a decent rapid-development and rapid-deployment environment, but it's still seriously wanting for real productivity.
Why does it matter in practice? Well, there's more than one reason, but consider that not every user agent is a browser with a person sitting in front of it. Your website also should be interpretable by content indexers like search engines, accessibility devices like screen readers, and so on.
Some services don't fit this model and really are better off being designed like desktop applications written in HTML and JS. But in my experience, most services can be modelled more like websites without making the design any more difficult to reason about, and almost all users' experiences are bettered by it.
http://words.steveklabnik.com/emberjs-and-accessibility
Okay, thank you for letting me get that off my chest.
Second, one nice thing about "embracing 100% JavaScript" that I talk about in the post is that it requires you to implement a really solid JSON API, because your web site is now a true client that consumes an API. This makes it really easy to integrate with third-party services that consume your content. I agree that putting content behind JavaScript sucks; I'm just advocating that the content be JSON (or some other normalized format), not HTML.
Ah, so don't put it "behind JavaScript", but put it in a format that a browser can't natively handle in a sane way. And use a grab-bag general object format instead of one that has built-in semantic definitions that are be useful in a document context, like, idunno, <strong> <em> <p> <a> ?
It needs run through a pretty-iffier, of course, but seems straightforward to me.
Unless, of course, my client wants a 100% working no-script webapp/site. Then I'll happily charge for the extra time building it.
If it takes more time, the final product costs more. The client should be aware of that and make the decision. Why should he/she always pay for something that will only be useful for a very small % of his/hers clients?
Regardless, there is no right or wrong answer in general, there is only the right or wrong answer for your particular website/market. If a significant number of the users you want to support have JS disabled, then by all means, build a site that runs without JS. But it's a cost-benefit analysis. For most sites I've worked on, the cost of lost business due to users without JS is (massively) dwarfed by the added development cost of building a full-featured app that doesn't require JS. If that means I lose you as a customer, I'm not losing sleep over it.
If just I look at my logs, more than 90% of the access are from Firefox and don't run Javascript.
Similarly, I won't be testing my websites in Soguo or Yandex until more than a vanishingly low percentage of people are using them on those sites.
If I have a blog or similar media site, and require javascript, I might offer a 15/month option to allow access to a text only interface and an RSS feed. No graphics, no pictures, a very simple link and text interface.
And the moment I start seeing subscriptions coming in, I'll believe in progressive enhancement again.
(Progressive enhancement doesn't affect me as an application developer in the web space. But if it did...)
If it were a site I frequent, I'd probably be willing to pay $3-4/month for a simple, clean, static html version (no need to remove the pictures though -- I can choose whether to load those client-side). Something like this, say: [http://mnmlist.com/unknown/] I'd only pay 15-20/month if I could get the entire web like that :)
Most likely, at 15/month I'd just not visit your site.
EDIT: PLEASE don't use the navigation from that site though. It's ... way too vertical.
This is the key sentence in the article and this is why I was motivated to become a web developer. Recently someone asked me if I felt like I was missing out by doing most of my programming on the web since desktop apps are "real programming" and I said no because the web is the best environment for writing apps today. I don't have to choose whether I want to write for Mac OS which I use myself, or Windows which most consumers use or Linux which hardcore techies use. I don't have to choose if my mobile app is iOS or Android first. Sure there are still tradeoffs, and sometimes a desktop or native mobile app is still going to be a good choice. But the browser today is an amazing environment that everyone on the web has access to and it's only getting better. And we should be excited about leveraging everything modern browsers can do to make great software.
Why? Search Engine accessibility.
It used to be that Googlebot wouldn't find content loaded asynchronously, or links that rely on Javascript. Now it's different - You can confirm that Googlebot discovers a lot of Javascript links using Webmaster Tools: https://www.google.com/webmasters/tools/home?hl=en
BUT - There's still no way to break from the "Page Paradigm" - Google needs URLs to send searchers to. They don't yet send people to specific states of a page. That's why I still use Progressive Enhancement, it forces me to ensure each piece of content has a URL that points to it.
Granted, people who disable javascript are obviously vastly outnumbered, but just saying "fuck you" to security conscious (and most likely tech-savvy) users seems like a mistake.
According to developer.yahoo.com[1],
> After crunching the numbers, we found a consistent rate of JavaScript-disabled requests hovering around 1% of the actual visitor traffic[...].
I work for a medium sized company that version tests almost every change we make, and in the end the version that wins is the feature with the higher conversion rate.
[1] http://developer.yahoo.com/blogs/ydn/many-users-javascript-d...
Conversion rate is a limited metric. It misses the entire concept of word-of-mouth. Conversion rate can't measure people who don't show up in the first place.
I expect NoScript users to be more sophisticated "power users" - the kind of users that regular users go to for advice. If they aren't using your site then they will never recommend it to their more naive and more easily converted friends.
1. Turn it on for that site. (But this can be problematic if there are 15 different domains to turn it on for, only 12 of which are about showing me ads.)
2. Use IEtab in Firefox (not working as well recently).
3. Paste the URL into a different browser. I use IE mainly for my several least favorite sites and services -- Facebook, WebEx, etc. So I'm unlike to mess things up too badly by viewing some JavaScript-heavy page in there.
4. Live without the site that demands all the JavaScript.
Now, one might hypothesize that a security-conscious, ad-hating web surfer as myself isn't a bit loss for most consumer websites. So perhaps it all works out in the end. But there also are a few companies that would pay a lot of money to have me look at their websites -- a fact that I infer from them paying PR people to attempt to get my attention -- and miss out solely because it's too hard to beat the Javascript requirement.
Don't expect your users to have a mouse. The share of web users on their mobile phone has grown from 6,5 % to 17,25 % since June 2011. Any bets on what the share will be in a year or two from now? (http://en.wikipedia.org/wiki/Usage_share_of_web_browsers#Sta...)
There's no reasons sites like tumblr *should work without javascript*. Period.
Why why!You say people like me. I'm more agnostic here.. just interested to understand the arguments of both side. I just think that a post saying "This is black. Period" doesn't add much to the discussion.
---------------- HTML static content way:
1. The new content will be fetched using ajax. Already some problems. From the server-side rendering, it needs to fetch it from the DB, then load it in the template. Using django, for instance, the view will fetch it and we'd show it using {{variables}}.
However, to fetch the data using ajax, it's not just the view making a query, it needs to have an API standpoint, i.e. /api/fetch-new-data/. So, already, the code is duplicated. Yes, the server-side could use the same API, but there's always the problem of returning JSON vs django-ORM-queries, etc.
2. Once the data is fetched (say in json), it needs to be rendered. How? Do you simply do a
$.get('/api/whatever', function(data) {
$('.some-div').append('<p>' + data + '</p>');
});
It's fine if it's just a <p>. But usually we'd have a more complex html and thus we'd be using client-side template. So, the server-side templates need to be duplicated. There are various ways to do it, varying from complexity, but there is clearly some duplication here. And, bear with me, it's usually not a simple .append, more javascript needs to be done which can alter the data, etc.------------------------- Javascript way
1. Load pure html. 2. Fetch initial data and render it using client-side template. (It can also be bootstrapped since it's in the same JSON format). 3. On scroll, fetch more data, and render it using the exact same code / client-side template. ----------------------
Lastly, bear with me that it's just a simple example. It's rarely 100% static content only. I.e. there would be forms with error validation, etc. If you want to do it the no-javascript way, you need to have it submit, reload the view with validation error, etc. Only then, you can add some javascript to enhance it. Contrast that to simply validate on javascript submit. Yes, obviously, the server needs to validate it, but that's part of the api, nothing needs to be re-rendered.
All in all, if you agree that the same code would do the pre-loading and the dynamic real-time stuff, you usually save yourself lots of headache and complexity.
I believe blogger had that problem as they show different views for the same content. When you switch between views, it dynamically updates it in javascript, rather than doing a page reload. Could it be made better by having a html/css content for no-js browser, sure thing. Would that duplicate the code? Sure thing. And again, there are different varying of complexity. Maybe that example wouldn't be too complex, but it's more code to maintain, to test, etc.
It's a bit late here, but hopefully you understand what I mean. And by the way, I'm still not 100% certain about what's the best approach. I know that I used to be pro html static first for backward compatibility and no-js users, and only javascript to enhance the page. But recently, I've tested it by doing it in javascript on the client and it's seriously so much faster and cleaner.
And yes, there are some good frameworks to deal with the duplication, but it adds lots of complexity. For instance, see airbnb Rendr which try to solve that exact problem that I'm talking about. I.e. being able to load backbone.js on the server during the pre-rendering stuff.
If only that were actually true. In reality, we're designing the interfaces for these applications using a presentation language made basically for desktop publishing. For interactivity, we essentially have one more or less shite language (http://bonsaiden.github.io/JavaScript-Garden/) to choose from. We're still arguing over the very basics on whether we should use callbacks, promises, generators, etc. for simple sequential operations. Hell, we're still trying to figure out how to get a reasonable call stack record to debug when working with any of these options. And God help you if you want to use a modern language that compiles to Javascript and have your debugger too.
But to address the author's original point, I think progressive enhancement is alive and well. While the majority of browsing is done on the desktop, I just think it makes way more sense to think first about presenting your basic content and then enhancing it than how you're going to strip out all the bells and whistles to get your design across on less capable platforms. In the long run, the former will probably save you more time and QA effort. It's just more natural to think about using capabilities when present then working around their absence.
And no one says your baseline should to a screen reader for all possible web apps. Just pick a the baseline that makes sense for what your doing, and enhance from there. At some point, it may make more sense to fork your platform and have separate implementations for different pieces of your interface. It doesn't have to be one monolithic project that magically enhances from mobile phone screen reader all the way up to VR cave.
JS has many potential UI/UX benefits which should be used for the users' benefit: although they can also be used to users' disadvantage.
If your (static?) website shows blank with no-JS, I find it unlikely that you've considered UI/UX at all. I therefore assume that you are more likely to fall on the disadvantageous side.
I'm sure you could make a dynamic page that has a negligibly different loading time compared to a static page that both display similar (static) content, but it's the way that you do it that matters. Loading a page, that loads a library, that pulls in another library once the page is loaded, that then displays spinning gears while pulling in a bunch of static content is of course the wrong way to do it for a lot of things. But that's a design problem.
I find the answer is not one or the other it's both. If a certain page requires interactivity then embrace Javascript and do the interactivity with Angular or Ember. You end up writing less Javascript. If you do it as decorating html using jQuery then you will end up with more javascript. Most pages in web apps don't require this much interactivity on every page though. There may be a few pages here and there. Most of it is just document viewing. In that case just send down cached html. Sure Bustle.com is fast, but so is Basecamp, both take entirely different approaches to display pages.
When I first got into Knockout a few years ago, I was a kid in a candy store. I wanted to do everything with Javascript and Knockout. Soon I grew up and realized you just don't need all that crap to display an f'in table. It's just a table for God's sake. We have been displaying tables since the dawn of web browser. In fact you will pay client CPU cost trying to display a table in Angular when you could just send it over in HTML.
Now if that table requires heavy editing(not filtering, or sorting, that stuff is easy as decoration), then sure bring in Angular.
On the other hand if I need drag and drop, validation, on complex forms, I'll definitely bring in Angular.
Choose the right tool.
How your site will be used is often a high level indicator of which approach will provide a better experience for your users. Gmail for example, no public part of the site, not uncommon for users to leave it open in a tab all day. Often great for all Javascript approach.
Twitter on the opposite end. Lots of public facing pages, performance was worse when they required Javascript just to render 140 characters on the screen. This style of site is generally better off with a progressive enhancement approach.
I was already looking at a gallery of thumbnails... how hard can it be to make each thumbnail a link to the image in question, and at runtime attach a javascript handler to open the image in a pop-up or whatever?
A HTML/CSS page + progressive enhancement tends to involve much less shooting-oneself-in-the-foot.
If you've got the talent, time and budget to do it well (note that is 'AND' not 'OR'. Gawker being a case of 2 out of 3 not being enough) then please go ahead.
However - if you have any doubts about your ability to see the whole thing through to perfection then a half-assed website is much less awful for your audience than a half-assed app.
I'll be the first to advocate requiring JavaScript when doing so significantly increases value, but for content sites please at least include the main content directly in the HTML.
The advantage of using Ember.js for Bustle is that it's really, really, ridiculously fast. Seriously, try it. Go to bustle.com and click around.
They could make it work without JavaScript, but they're a new company with a long list of technical challenges to solve. They ran the numbers and the percentage of users with JS disabled is so microscopic it just doesn't make sense to spend time on it.
What value dose using PhantomJS offer above what progressive enhancement gives you for free?
This feels like a contradiction. Avoiding progressive enhancement, and then bolting on a hack for search spiders in a way that is less robust than the technique you're avoiding.
"The advantage of using Ember.js for Bustle is that it's really, really, ridiculously fast. Seriously, try it. Go to bustle.com and click around."
The initial load is horribly slow. For example: http://www.bustle.com/articles/4549-pew-poll-american-people... took 10 seconds. That's very slow for a one page article.
That's gonna hurt people following links to the page. That's exactly the reason why Twitter walked away from it's JavaScript driven content and went for progressive enhancement. A substantial portion of new visitors will have a cold cache, and have this annoying wait for what is effectively a one page article. (cf. http://statichtml.com/2011/google-ajax-libraries-caching.htm... )
"They could make it work without JavaScript, but they're a new company with a long list of technical challenges to solve. They ran the numbers and the percentage of users with JS disabled is so microscopic it just doesn't make sense to spend time on it."
Another contradiction. Progressive enhancement isn't a technical challenge, it is so brain dead simple.
So they figured out the number of users with JavaScript disabled is too small to warrant supporting. Interesting, except, progressive enhancement isn't solely about people with JavaScript disabled, right? cf: http://isolani.co.uk/blog/javascript/DisablingJavaScriptAski...
Also, so they ran the numbers of these, under the incorrect assertion that progressive enhancement only impacts people with JavaScript disabled. But did they run those same numbers that determined the number of search spiders wasn't microscopic, to justify the PhantomJS bodge you initially mentioned? Are you really implicitly asserting that there are far more search spider visitors to bustle.com than visitors with JavaScript disabled? (I'd love to understand the logic that lead to that determination).
So, what justification was there to spend time on building a PhantomJS site scraper to provide static content to search engine spiders, and yet fail to appreciate that progressive enhancement would have served that spider audience, as well as the JavaScript audience, as well as the variety of issues that progressive enhancement helps alleviate?
But, if bustle.com were a content site, then progressive enhancement is the way to go, right? But this is an ember app, so it is not a content site (clearly). Except when search spiders visit, then there's a need for a static version of each page. It's very confusion. is bustle.com an app or a website?
Also, how does bustle.com / ember, guarantee perfect delivery of assets other than HTML to a visitor's browser? How does it guarantee robustness?
For example, when using a CDN, how does it manage when this happens: http://www.theregister.co.uk/2012/01/05/google_opendns_clash...
How does bustle.com / ember protect your JavaScript so that when a third-party chunk of JavaScript (like Google Analytics, Disqus, Facebook, ChartBeat, Quantcase, WebTrends) does something funky, or hiccups and causes a JavaScript error?
1) Static resources can be cached on a CDN and composited on the client instead of an overloaded app server
2) You can load data instead of heavy and repetitive HTML over the wire
3) You can cache the data in the client and re-use it later, making for snappier interfaces
That said, you have to watch out for URLs. Just because you can write everything with javascript doesn't mean you should break URLs. And of course, crawlers other than google's crawler will probably not be able to execute your JS.
3/ Because you cant cache html pages client side ?
1. The browser requests CDN resources directly and Javascript is used to combine those static files into something that the user sees. Since the code is executing on the client, the app server is not overloaded.
2. Suppose you have a list of 20 items. You could either output HTML with all the tags already rendered for each of the 20 items, or you could output a JSON array with 20 objects, which is much less on the wire.
3. If you are rendering stuff on the client and only fetching data for it (which is what modern Javascript MVC frameworks let you do) then you can cache that data and re-use it. Caching entire HTML pages is at a much lower level of granularity that caching each piece of data you get from the server, and reassembling it in different ways.
2. It's not that much of a difference, after gzipping, which you surely already do.
3. See number 1.
Moreover, in the end, you'll get a less heavy document to be processed by the browser. I swear my all bells and whistles i7 X1 Carbon still struggles on some javascript-heavy sites.
Some documents, especially those using Ajax for loading content or multiple pages, make this difficult. I hate them. (Hacker News, oddly, does it too - when a discussion is archived, it becomes paged, which makes it more complicated to store.)
I wish there would be a standard way to store page offline, including all the JS changes made to its looks, all the external content etc.
How about: If it's profitable for your site to offer a non-JS fallback, do it. If it isn't, don't.
If you don't pay that tax, you're personally contributing to a future when simple documents become full-fledged programs, and everyone lose abilities to easily manipulate and interact with them in any but author-defined ways.
There are cases where you can be exempt from that tax - if your site is not about documents, but their transformations, i.e. it's more of a process, not data. (Then you should call it app, not site). But vast majority of sites isn't.
I ask because I've recently discovered that Google has massively failed in this department with some of their products, at least as far as speech recognition is concerned. Google Docs is a great example of what I'm talking about. If you try to use it with Dragon NaturallySpeaking, buttons and menu items are often not recognized, text entry is only reliable by using the separate (and inconvenient) Dragon "dictation box", editing is a nightmare, and review comments can only be placed by actually copying from a separate program. Your best bet if you need to collaborate is honestly to just use Microsoft Word, and then either upload and convert, or copy and paste, and then accept the fact that a lot of collaboration tools won't be usable by you or any of your collaborators.
I can't imagine how frustrating it must be to try to use modern web apps as someone who can't type effectively or read a screen, and it seems like the problem is only going to get worse as people rely more on canvas without taking accessibility into consideration.
Business logic on the server, HTML generated on the server, conventional mvc-architecture, use ajax and push state to make it highly interactive.
Fine - you can assume JS being available, but from that it simply does not follow that you have to throw away the traditional (rails style) dev model of the web.
Best of both worlds.
PS: All this crazy talk stems from the fact Javascript created an apartheid on the web. We need to make a clear distinction between the HTTP-web and the Javascript-enabled-web. The fact the same software (browser) serves this dual purpose adds to the confusion and allows bad architecture decisions, interwinding content and rich interfaces inside the same hypertext mudball.
For my clients it's usually the case that being found well in Google is a major part of their business case. PE makes sure that a basic crawlable version of your website exists with proper titles and tags.
Then your site does not require client-side JS support.
The point is not about what technologies you use to produce documents, the point is what data you [can] serve.
Take a look at Discourse or Bustle. They're pure Javascript apps that are still SEO-friendly.
And the Phantom.js approach mentioned below seems more like a workaround to me than a solution
Their site is 100% in JS. And if you google for anything even remotely close to what this site sells you simply cannot find them.
Unless you are a members only app site would I say progressive enhancement is dead. Well that is unless you care about the millions of users on slower mobile connections with crappy smart phones.
It’s a myth that if you use a client side MVC framework
that your application’s content cannot be indexed by
search engines. In fact, Discourse forums were indexable
by Google the day we launched.
http://eviltrout.com/2013/06/19/adding-support-for-search-en...They are probably a good case to follow, if you want to see what people's experiences with SEO for JS-based services are.
1. Stop preventing middle and right clicks on JavaScript enabled links. For left clicks, sure ... control the flow.
2. Respect the fact that this is NOT a desktop environment, therefore my view of your program's "screens" should be on a per URL basis. I actually might want to view a list you generated in my own separate "window" or "screen" with the URL visible, usable, and savable in the browser.
Inspecting the Bustle app with the new Chrome Ember Inspector is very cool.
Has Bustle open sourced any of their components or written on how they developed the app?
[1] http://www.reddit.com/r/webdev/comments/1kf84d/bustlecoms_sp...
What annoys me is the tendency of Javascript guys to rebuild every damn application there is as a webapp, and rave about it like it's the best thing ever. Javascript has become their hammer, and the whole world looks like it needs a good pounding.
Just because you can doesn't mean you should.
- Accessibility - Spiderability by search engines
If you want to say PE is dead please explain how these don't matter to most websites.
People that consider app should be usable entirely without javascript certainly miss the point. So do people that consider progressive enhancement is only about supporting people that deactivated javascript.
As author mentioned, the browser is now more an execution environment rather than a document viewer. You know what it means ? It means that developers have no control over the execution environment. With server side, if it works for you, it works for everyone. With client side, you'll never know. You don't know what extensions your user use. You don't know how stable his system is. You don't know how stable his connection is. And you can't ask your users to have a such carefully crafted environment as your servers.
What this should make us concludes is that the most heavily your app rely on javascript, the better it should be at error handling.
How do you handle error in javascript ? If an error occurs in a callback function, clicking that <a href="#"> again and again will simply do nothing, and your user will get frustrated and yell : "it does not work !".
With progressive enhancement and graceful degradation, it suddenly becomes simple. Your link has a real href. You can deactivate all event handlers using the event "window.onerror". That way, clicking a link after a crash will follow it.
You even don't have to implement the feature totally on server side. If your client side feature can be emulated on server side, do it (and your user won't even realize something went wrong) ; if it can't, simply warn your user about it. Anyway, javascript runtime will have been reinitialized.
So, for all of this to work and make sense, we just have to use modern definitions :
* progressive enhancement is ensuring no link / button / whatever would "freeze" if javascript crash
* graceful degradation is ensuring interface get reversed back to an useful state when an error occurs (like, showing again submit button for what was ajax forms). This can easily be done if your page is composed of objects that respond to some kind of destructor method.
If you think client side errors do not happen that much, just put something like that in your code :
window.onerror = function( error, url, lineno ){
$.post( my_exception_url, error: { error, url: url, lineno: lineno, page_url: window.location.href );
}
This will post all exceptions to a server side url, where you can relay it to your exception management system (I simply raise a system exception using the passed parameters) or store them. You'll be surprised.Nobody would've made a Flash-only site but for some reason JS-only sites that shut out anyone with slow computers, old computers, mobile browsers that aren't Safari, etc. are totally okay.