Why we abandoned server generated web pages

1. You’re constantly transporting state back and forth between client and server (and often neglecting to do so).

The next time you’re in GMail, notice something interesting about selecting emails. If you check several emails for a mass operation and then realize you’re not altogether sure about one email, so you click to read it, then you come back out to the list, the same emails are still checked. Now do the same test in an app written in any of the classic Java, PHP, Python, etc. frameworks. In those, when the user clicks on the email to view it:

  1. In all likelihood it was just a link so all of the client-side state (the checked and unchecked checkboxes) is immediately discarded by the browser.

  2. Some “clever” frameworks make that link not really a link, instead, they generate JavaScript client side which invokes a POST (as if a form was submitted), the checkboxes do get submitted to the server, stored somewhere in the user’s session, and then hopefully sent back down with the next request for the page that had the original list of checkboxes. Our links aren’t really links, there’s lots of JavaScript magic going on behind the scenes that most people you work with don’t even begin to understand and, trust me, trust me when I say this… It breaks. And it breaks badly.

2. It’s slow, slow, and did I mention slow?

  1. The development cycle itself is slower. I can throw up a temporary API using a variety of tools (or mock it client side using something like $httpBackend) and start work on the UI immediately. As I make each change I just have to refresh the browser to see my change in place. In fact, if I use tools like the Grunt server the browser refresh is automatically triggered when I save a changed file so I can just glance over at it and evaluate the results without leaving my code.

    Most server side frameworks involve a compilation step of some type (for example, Java’s JSPs are translated to servlets and then those are compiled to a byte code for the VM). Thus I have a longer wait to view each change I make.

  2. If my UI is built client-side with HTML, CSS, and JavaScript then it’s way more efficient because the only data which is being transported back and forth is that sent via the API calls to the server. I don’t have to ship all a complete list of all the products wrapped in HTML layout one minute, and then minutes later what is effectively the exact same list (minus one or two and plus one or two) again wrapped in a bunch of HTML formatting. Note: Some of this can carry over to content delivery networks as well because an all static files front-end works really well around the world.

  3. User’s get tired of every thing they click upon meaning another trip to the server. If they just looked at that data a minute ago, it may well be in memory locally so showing it again is free. But if I have to go to the server again to get it re-rendered for re-display, I can get really old fast. I think we can all point to a site where we are frequently frustrated by the slow performance.

  4. And why is it slow? Well, because it’s not just persisting data and performing queries on it, it’s also combining that data with HTML templates of some flavor to generate full pages and doing so over and over and over again. More work for the server means more servers needed, more time spent on performance tuning, etc.

3. It’s a more complicated programming model.

  1. If you do a lot of web applications where the pages don’t use any JavaScript to pull data on the fly, validate user’s forms in real time, etc. then that’s great. But if you are then you’ve got a wonderful hybrid going where sometimes you work in one language server side but you also use JavaScript client-side and you’ve got two different models just for one UI.

  2. For many frameworks, lots of middle tier complexity can leak into the pages, making them way more complicated than HTML and thus much harder for designers (and programmers) to work on. I’ve seen this most often in frameworks where designers are expected not to use standard HTML. Instead they’re supposed to use perfect XML where every tag perfectly matches a closing tag and not a bracket is out of place, or they can’t use the <a>, <form>, <input>, etc. tags, instead each has some replacement which is supposed to be used which typically functions about 70% or so the same as the regular tag.

  3. I loved this recent quote about JSF, a technology that I rejected at a previous employer because it was very clear that it was designed by committee and not extracted from real projects (like say Ruby on Rails):

4. Debugging is much more complicated.

Something as simple as how some HTML is rendering may require me to setup a debugger on a server on a remote machine because it is being generated from an intermediate file and data on the server.

With AngularJS or similar JavaScript frameworks, I can first look to see if the data came to the browser without problems. That involves just looking at the JSON I received from my API calls. If that’s good then I can set breakpoints in the JavaScript in the browser to see how the JavaScript code flow is going awry. On data flowing from client to server I can usually just consult the browser to see what was sent and I again know whether I’m looking at a client or server problem.

Software Rants

Mine is not a real software rant, I wrote it tongue-in-cheek after reading one just this week which spun up a bunch of people. Like most of the others, I skipped gracefully past some problems:

  • I still have non-API uses for servers. If I need a CSV or XLS file for download, it’s still way easier to have that generated on the server than to try and craft it client side with JavaScript.
  • I glossed over areas where the server generated web pages have advantages (for example, if your users are developmentally disabled and insist on staying on IE 7 or keeping JavaScript turned off).
  • I also skipped over the fact that there are browsers like older versions of IE where the debuggers are very poor and debugging can be just as painful client-side as it is for server-side.

Every framework that has achieved some level of popularity or notoriety has had its share of famous rants (Rails is a Ghetto, Node.js is stupid, and if you use it, so are you!, Why we left AngularJS which has since been renamed to 5 surprisingly painful things about client-side JS). Somebody doesn’t like the language, the framework, the community which goes with it and in frustration they vent. Sometimes they’re right about their complaints and sometimes they’re wrong, often it’s somewhere in between. Just relax and try to read it with an eye to whether the points being made are good ones and ignore the vitriol.

About these ads

10 thoughts on “Why we abandoned server generated web pages

    1. Omkar (@omtalk)

      Don’t think SEO is much of a problem. Can be easily handled by wise utilization of the History API. Facebook pretty much does the same with. Most calls do not reload the page, just update the content along with the URL. Precisely covering-up where SEO would matter.

      Reply
  1. John Munsch Post author

    Some months back I added Prerender.io to the MEAN stack just to see how hard it was and whether it worked. I felt it was probably good enough to try it out for a project so I’ve got one in the works right now (the graph paper generator I mentioned in a past post).

    Since the site will probably only make money from ads, it’ll be important that it works and I’ll get to see how well.

    Edit: I should point out that the large AngularJS project I work on for a living, as well as the large Backbone.js project I did before that are all commercial apps and not exposed to the Internet. So the technology produced a much better UI than previous iterations of those apps did, but we didn’t have to deal with SEO issues at all.

    Reply
    1. John Munsch Post author

      That link is at the bottom of my post where I talk about a history of software rants. That’s just one of the latest ones and why I decided to write my own. Partially it was an attempt to be tongue-in-cheek and part of it was to remind people why so many have abandoned the old way of doing things (there were reasons for that as well).

      Reply
  2. John Flack

    Yes, server side frameworks need links to send some data, so they often use a little Javascript to change a GET to a POST. You say it breaks badly, but offer no evidence or examples. I’ve never seen it break if done right. And heck, client side frameworks use a LOT more Javascript than that.
    In my work with JSF I often make changes and do a quick refresh to see them. There may be some compile delay, but it is so fast, I don’t notice, and it has never slowed me down.
    Modern Ajax frameworks use partial page refreshes and rarely send the entire page for a few small changes. Sure, there is some data moving between the client and the server, but not much, so I don’t see a huge performance problem.
    I agree about the multiple language problem – Javascript on the client side, and something else, like Java, Ruby, Groovy or PHP on the server side. But what are your JSON APIs written in? After all, you DO have a server side if you need to persist data. My JSF-based framework tries to make sure that components provide their own pre-written, well tested Javascript, so I don’t usually have to write my own Javascript. So I can stick mostly with Java.
    Here’s the thing about abstraction – yes, it is imprecise sometimes, yes, it is imperfect, but it can greatly simplify a tough problem. And I don’t have to re-invent the wheel – I can build on someone else’s well-tested wheel.
    Actually, my point is not “my framework is better than your framework”. My point is that all frameworks have good and bad points – it is what works best for you and for the project you are doing that counts.

    Reply
  3. Omkar (@omtalk)

    There is an unbeatable plus side for this move on mobile devices. The task of loading a new DOM and managing bulky requests isn’t appealing; updating page by context creates a lighter and faster user experience.

    Reply
    1. John Munsch Post author

      This is an excellent point and one I should have made myself. I’ll point out another mobile benefit from a past project.

      At my previous employer the mobile UI was separate from the desktop UI. It ran on the very small touchscreens on barcode scanning guns. Both UIs used the same server API behind the scenes and both used the same technology on the front-end (HTML, CSS, JavaScript, Backbone.js, Handlebars, etc.) but the gun version had big buttons for easy touch targets and had only the basic functions which were needed on the devices.

      Any thought that the old JSF interface was going to run nicely in the limited memory and on the limited CPUs of the devices was out the window as soon as we tried it early in the project. The new, very light UIs we built however handled it with aplomb.

      Reply
  4. bchesley

    Reblogged this on CFMeta and commented:
    Excellent analysis of some of the major architectural challenges one is faced with in partitioning an application into client and server side capabilities. Thanks.

    Reply
  5. Pingback: Cómo se carga una página en mi uso de AngularJS, Play, Slick… (I – cliente) | juanignaciosl

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s