I've been reading some very interesting articles about the whole client vs. server rendering lately.
http://www.onebigfluke.com/2015/01/experimentally-verified-why-client-side.html
http://www.quirksmode.org/blog/archives/2015/01/angular_and_tem.html
http://tomdale.net/2015/02/youre-missing-the-point-of-server-side-rendered-javascript-apps/
Now I've been a bit of a fan boy when it comes to client side but after I read these articles some points started to show up in favor of the server side rendering, to my surprise... The main points were:
1) You can upgrade your server, but not your users device - This means, well, yes... you are in control of the server, so if it's under performing you may opt to upgrade/scale. You can't force users to upgrade their devices.
2) First paint vs. last paint - Now on the experimentally verified... link above it shows when the users first see the page (first paint) and when the users may use the page 100% (last paint). Now from what I can think of when the user sees the page, it takes their brain some time to process the signals from the visual cortex to the frontal cortex and then to the premoter cortex where the user actually starts clicking his/her finger, that is of course if the html is rendered first so the brain has something to process while loading is happening in the background (js files, binding etc.).
What really got me was the bit were twitter reported people of having up to 10 seconds of loading time for client side rendering, no one should ever experience that! It's kind of saying, "Well if you don't have a good enough device, sorry, you'll just have to wait.".
I've been thinking, isn't there a good way of using both client-side and server-side templating engines and which both client and server use the same template engine and code. In that case it's only to figure out if it's benefactor to supply the client with the rendered page or let the client render it themselves.
In any case, share your thoughts on my sayings and the articles if you want. I'm all ears!
UPD: do it only if you really need it
(4 years and 2 isomorphic enterprise apps later)
If you're required to do SSR, fine. If you can go with a simple SPA - go with it.
Why so? SPAs are easier to develop, easier to debug and cheaper and easier to run.
The development and debugging complications are evident. What do I mean by "cheaper and easier to run", though? Well, guess what, if 10K users try to open your app at the same time your static HTML website (i.e. a built SPA) you won't even feel it. If you're running an isomorphic webapp though, the TTFB will go up, RAM usage will go up and eventually you'll have to run a cluster of those.
So, unless you are required to show some super-low TTFB times (which will likely come through aggressive caching), don't overcomplicate your life.
Original answer from 2015:
Basically you're looking for an isomorphic web app that shares the same code for frontend and backend.
Isomorphic JavaScript
JavaScript applications which run both client-side and server-side. Isomorphic JavaScript frameworks are the next step in the evolution of JavaScript frameworks. These new libraries and frameworks are solving the problems associated with traditional JavaScript frameworks.
I bet this guy explains that much better that me.
So, when a user comes to the page, the server renders the full page with contents. So it loads faster and requires no extra ajax requests to load data, etc. Then, when a user navigates to another page, the usual techniques for single page applications are used.
So, WHY WOULD I CARE?
Old browsers / Weak devices / Disabled Javascript
SEO
Some page load improvements
Old browsers / Weak devices / Disabled Javascript
For example, IE9 does not support History API. So, for old browsers (and if user disables javascript too), they would just navigate through pages just like they did it it in good old days.
SEO
Google says it supports SPA's but SPA's aren't likely to appear in the top results of google search, are they?
Page speed
As it was stated, the first page loads with one HTTP request, and that's all.
OK, so
There are lots of articles on that:
http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/
http://www.sitepoint.com/isomorphic-javascript-applications/
https://www.lullabot.com/articles/what-is-an-isomorphic-application
But SHOULD I CARE?
It's up to you, of course.
Yeah, that's cool, but it takes much work to rewrite/adapt the existing app. And if your backend is in PHP/Ruby/Python/Java/Whatever, I've got bad news for you (it's not necessarily impossible, but close to that).
It depends on the website, you can try to collect some stats and if the percentage of users with old devices is small, it's not worth the trouble, so why not...
LET THEM SUFFER
If you care only about users with old devices, then c'mon, it 2015, and it's your user's problem if he's using IE8 of browsing websites with a iPod Touch 2. For example, Angular dropped IE8 support in 1.3 approximately a year ago, so why wouldn't you just alert the users that they need to upgrade ;)
Cheers!
All of the conversations on this topic miss one point. Bytes sent to the client. Pages rendered as HTML on the server are a lot smaller. Less bytes transmitted is better for everyone, both server and client. I've seen the bandwidth costs on cloud sites and even a 10% reduction can be a huge saving. Client side JS pages are always fat.
Related
I want to implement an online document editing and correction platform. This works as an interactive single-page web application. Think of google docs, but with more complex widgets inside.
I have done this app in React (JS) + Node.js + Postgres, which took some months of work, but I am not liking the JS experience that much, specially when things get more complicated handling this very complex state and the solutions presented in this frameworks are very restrictive, and changing a bit of code somewhere has "high" maintenance.
I've never done any Common Lisp web app but I've read a lot about the available tools, and although there are many solutions for a web server (hunchentoot, clack, wookie, woo, fastcgi, ...), web application frameworks (caveman, ningle, radiance, lucerne, ...), html-generation libs (cl-who, spinneret, ...) and even javascript "transpiling" (parenscript), my main limitaion here is the heavy focus on the single-web-page app that must do most operations exclusively on the client side.
Architecture:
Back-end server handles all permanent document storing/retrieval and user logins
Front-end does all document manipulation client-side (including intermediate document state changes, without needing to communicate each change to the back-end)
Core needs:
Completely dynamic single-page web application interface (content is mostly the document you're editing)
Negligible interaction latency
Scale to many users with as low load on the main server as possible
All interaction with the document should happen on the client side (including managing intermediate changes)
Back-end server should only be contacted for login, pull document, pushing a new final document state, or requesting special operations like automated processing of the document information.
Modern browser experience, namely HTML5 with support for drag-and-drop operations in the document editing
Library requirements (I don't want to use libraries that turn out to be a dead end project):
Solid libraries (e.g.: hunchentoot, clack, parenscript)
Definitely not:
Libraries that someone did and then there are open bugs for 3 years and the last commit was 5 years ago
Bad documentation (which means one can't figure out how to do things without spending hours or reading the library code)
I've also seen there are projects like slurm-cl, panic, weblocks, but the first 2 don't seem to be mantained anymore or lack some documentation, whilst the new weblocks seems nice, but from what I understand runs server-side, not client-side, which is a limitation for me.
Million dollar Question
Sorry for the long post but can you tell me if Common Lisp has any library for this use case - client-side scripting? Is it possible? Would Parenscript fit the bill? (I assume if I go with that one I'd have to write most things from zero - which is not my goal either).
Also, if I went with Parenscript I'm assuming it does not do DOM management either.
Or should I not use Common Lisp at all for this?
I've done some web-based projects, and most of the difficulties I've met with (questions, confusions) could be figured out with help. But I still have an important question, even after asking some experienced developers: When functionality can be implemented with both server-side code and client-side scripting (JavaScript), which one should be preferred?
A simple example:
To render a dynamic html page, I can format the page in server-side code (PHP, python) and use Ajax to fetch the formatted page and render it directly (more logic on server-side, less on client-side).
I can also use Ajax to fetch the data (not formatted, JSON) and use client-side scripting to format the page and render it with more processing (the server gets the data from a DB or other source, and returns it to the client with JSON or XML. More logic on client-side and less on server).
So how can I decide which one is better? Which one offers better performance? Why? Which one is more user-friendly?
With browsers' JS engines evolving, JS can be interpreted in less time, so should I prefer client-side scripting?
On the other hand, with hardware evolving, server performance is growing and the cost of sever-side logic will decrease, so should I prefer server-side scripting?
EDIT:
With the answers, I want to give a brief summary.
Pros of client-side logic:
Better user experience (faster).
Less network bandwidth (lower cost).
Increased scalability (reduced server load).
Pros of server-side logic:
Security issues.
Better availability and accessibility (mobile devices and old browsers).
Better SEO.
Easily expandable (can add more servers, but can't make the browser faster).
It seems that we need to balance these two approaches when facing a specific scenario. But how? What's the best practice?
I will use client-side logic except in the following conditions:
Security critical.
Special groups (JavaScript disabled, mobile devices, and others).
In many cases, I'm afraid the best answer is both.
As Ricebowl stated, never trust the client. However, I feel that it's almost always a problem if you do trust the client. If your application is worth writing, it's worth properly securing. If anyone can break it by writing their own client and passing data you don't expect, that's a bad thing. For that reason, you need to validate on the server.
Unfortunately if you validate everything on the server, that often leaves the user with a poor user experience. They may fill out a form only to find that a number of things they entered are incorrect. This may have worked for "Internet 1.0", but people's expectations are higher on today's Internet.
This potentially leaves you writing quite a bit of redundant code, and maintaining it in two or more places (some of the definitions such as maximum lengths also need to be maintained in the data tier). For reasonably large applications, I tend to solve this issue using code generation. Personally I use a UML modeling tool (Sparx System's Enterprise Architect) to model the "input rules" of the system, then make use of partial classes (I'm usually working in .NET) to code generate the validation logic. You can achieve a similar thing by coding your rules in a format such as XML and deriving a number of checks from that XML file (input length, input mask, etc.) on both the client and server tier.
Probably not what you wanted to hear, but if you want to do it right, you need to enforce rules on both tiers.
I tend to prefer server-side logic. My reasons are fairly simple:
I don't trust the client; this may or not be a true problem, but it's habitual
Server-side reduces the volume per transaction (though it does increase the number of transactions)
Server-side means that I can be fairly sure about what logic is taking place (I don't have to worry about the Javascript engine available to the client's browser)
There are probably more -and better- reasons, but these are the ones at the top of my mind right now. If I think of more I'll add them, or up-vote those that come up with them before I do.
Edited, valya comments that using client-side logic (using Ajax/JSON) allows for the (easier) creation of an API. This may well be true, but I can only half-agree (which is why I've not up-voted that answer yet).
My notion of server-side logic is to that which retrieves the data, and organises it; if I've got this right the logic is the 'controller' (C in MVC). And this is then passed to the 'view.' I tend to use the controller to get the data, and then the 'view' deals with presenting it to the user/client. So I don't see that client/server distinctions are necessarily relevant to the argument of creating an API, basically: horses for courses. :)
...also, as a hobbyist, I recognise that I may have a slightly twisted usage of MVC, so I'm willing to stand corrected on that point. But I still keep the presentation separate from the logic. And that separation is the plus point so far as APIs go.
I generally implement as much as reasonable client-side. The only exceptions that would make me go server-side would be to resolve the following:
Trust issues
Anyone is capable of debugging JavaScript and reading password's, etc. No-brainer here.
Performance issues
JavaScript engines are evolving fast so this is becoming less of an issue, but we're still in an IE-dominated world, so things will slow down when you deal with large sets of data.
Language issues
JavaScript is weakly-typed language and it makes a lot of assumptions of your code. This can cause you to employ spooky workarounds in order to get things working the way they should on certain browsers. I avoid this type of thing like the plague.
From your question, it sounds like you're simply trying to load values into a form. Barring any of the issues above, you have 3 options:
Pure client-side
The disadvantage is that your users' loading time would double (one load for the blank form, another load for the data). However, subsequent updates to the form would not require a refresh of the page. Users will like this if there will be a lot of data fetching from the server loading into the same form.
Pure server-side
The advantage is that your page would load with the data. However, subsequent updates to the data would require refreshes to all/significant portions of the page.
Server-client hybrid
You would have the best of both worlds, however you would need to create two data extraction points, causing your code to bloat slightly.
There are trade-offs with each option so you will have to weigh them and decide which one offers you the most benefit.
One consideration I have not heard mentioned was network bandwidth. To give a specific example, an app I was involved with was all done server-side and resulted in 200Mb web page being sent to the client (it was impossible to do less without major major re-design of a bunch of apps); resulting in 2-5 minute page load time.
When we re-implemented this by sending the JSON-encoded data from the server and have local JS generate the page, the main benefit was that the data sent shrunk to 20Mb, resulting in:
HTTP response size: 200Mb+ => 20Mb+ (with corresponding bandwidth savings!)
Time to load the page: 2-5mins => 20 secs (10-15 of which are taken up by DB query that was optimized to hell an further).
IE process size: 200MB+ => 80MB+
Mind you, the last 2 points were mainly due to the fact that server side had to use crappy tables-within-tables tree implementation, whereas going to client side allowed us to redesign the view layer to use much more lightweight page. But my main point was network bandwidth savings.
I'd like to give my two cents on this subject.
I'm generally in favor of the server-side approach, and here is why.
More SEO friendly. Google cannot execute Javascript, therefor all that content will be invisible to search engines
Performance is more controllable. User experience is always variable with SOA due to the fact that you're relying almost entirely on the users browser and machine to render things. Even though your server might be performing well, a user with a slow machine will think your site is the culprit.
Arguably, the server-side approach is more easily maintained and readable.
I've written several systems using both approaches, and in my experience, server-side is the way. However, that's not to say I don't use AJAX. All of the modern systems I've built incorporate both components.
Hope this helps.
I built a RESTful web application where all CRUD functionalities are available in the absence of JavaScript, in other words, all AJAX effects are strictly progressive enhancements.
I believe with enough dedication, most web applications can be designed this way, thus eroding many of the server logic vs client logic "differences", such as security, expandability, raised in your question because in both cases, the request is routed to the same controller, of which the business logic is all the same until the last mile, where JSON/XML, instead of the full page HTML, is returned for those XHR.
Only in few cases where the AJAXified application is so vastly more advanced than its static counterpart, GMail being the best example coming to my mind, then one needs to create two versions and separate them completely (Kudos to Google!).
I know this post is old, but I wanted to comment.
In my experience, the best approach is using a combination of client-side and server-side. Yes, Angular JS and similar frameworks are popular now and they've made it easier to develop web applications that are light weight, have improved performance, and work on most web servers. BUT, the major requirement in enterprise applications is displaying report data which can encompass 500+ records on one page. With pages that return large lists of data, Users often want functionality that will make this huge list easy to filter, search, and perform other interactive features. Because IE 11 and earlier IE browsers are are the "browser of choice"at most companies, you have to be aware that these browsers still have compatibility issues using modern JavaScript, HTML5, and CSS3. Often, the requirement is to make a site or application compatible on all browsers. This requires adding shivs or using prototypes which, with the code included to create a client-side application, adds to page load on the browser.
All of this will reduce performance and can cause the dreaded IE error "A script on this page is causing Internet Explorer to run slowly" forcing the User to choose if they want to continue running the script or not...creating bad User experiences.
Determine the complexity of the application and what the user wants now and could want in the future based on their preferences in their existing applications. If this is a simple site or app with little-to-medium data, use JavaScript Framework. But, if they want to incorporate accessibility; SEO; or need to display large amounts of data, use server-side code to render data and client-side code sparingly. In both cases, use a tool like Fiddler or Chrome Developer tools to check page load and response times and use best practices to optimize code.
Checkout MVC apps developed with ASP.NET Core.
At this stage the client side technology is leading the way, with the advent of many client side libraries like Backbone, Knockout, Spine and then with addition of client side templates like JSrender , mustache etc, client side development has become much easy.
so, If my requirement is to go for interactive app, I will surely go for client side.
In case you have more static html content then yes go for server side.
I did some experiments using both, I must say Server side is comparatively easier to implement then client side.
As far as performance is concerned. Read this you will understand server side performance scores.
http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html
I think the second variant is better. For example, If you implement something like 'skins' later, you will thank yourself for not formatting html on server :)
It also keeps a difference between view and controller. Ajax data is often produced by controller, so let it just return data, not html.
If you're going to create an API later, you'll need to make a very few changes in your code
Also, 'Naked' data is more cachable than HTML, i think. For example, if you add some style to links, you'll need to reformat all html.. or add one line to your js. And it isn't as big as html (in bytes).
But If many heavy scripts are needed to format data, It isn't to cool ask users' browsers to format it.
As long as you don't need to send a lot of data to the client to allow it to do the work, client side will give you a more scalable system, as you are distrubuting the load to the clients rather than hammering your server to do everything.
On the flip side, if you need to process a lot of data to produce a tiny amount of html to send to the client, or if optimisations can be made to use the server's work to support many clients at once (e.g. process the data once and send the resulting html to all the clients), then it may be more efficient use of resources to do the work on ther server.
If you do it in Ajax :
You'll have to consider accessibility issues (search about web accessibility in google) for disabled people, but also for old browsers, those who doesn't have JavaScript, bots (like google bot), etc.
You'll have to flirt with "progressive enhancement" wich is not simple to do if you never worked a lot with JavaScript. In short, you'll have to make your app work with old browsers and those that doesn't have JavaScript (some mobile for example) or if it's disable.
But if time and money is not an issue, I'd go with progressive enhancement.
But also consider the "Back button". I hate it when I'm browsing a 100% AJAX website that renders your back button useless.
Good luck!
2018 answer, with the existence of Node.js
Since Node.js allows you to deploy Javascript logic on the server, you can now re-use the validation on both server and client side.
Make sure you setup or restructure the data so that you can re-use the validation without changing any code.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I've read about SPA and it advantages. I find most of them unconvincing. There are 3 advantages that arouse my doubts.
Question: Can you act as advocate of SPA and prove that I am wrong about first three statements?
=== ADVANTAGES ===
1. SPA is extremely good for very responsive sites:
Server-side rendering is hard to implement for all the intermediate
states - small view states do not map well to URLs.
Single page apps are distinguished by their ability to redraw any part
of the UI without requiring a server roundtrip to retrieve HTML. This
is achieved by separating the data from the presentation of data by
having a model layer that handles data and a view layer that reads
from the models.
What is wrong with holding a model layer for non-SPA? Does SPA the only compatible architecture with MVC on client side?
2. With SPA we don't need to use extra queries to the server to download pages.
Hah, and how many pages user can download during visiting your site? Two, three? Instead there appear another security problems and you need to separate your login page, admin page etc into separate pages. In turn it conflicts with SPA architecture.
3.May be any other advantages? Don't hear about any else..
=== DISADVANTAGES ===
Client must enable javascript.
Only one entry point to the site.
Security.
P.S. I've worked on SPA and non-SPA projects. And I'm asking those questions because I need to deepen my understanding. No mean to harm SPA supporters. Don't ask me to read a bit more about SPA. I just want to hear your considerations about that.
Let's look at one of the most popular SPA sites, GMail.
1. SPA is extremely good for very responsive sites:
Server-side rendering is not as hard as it used to be with simple techniques like keeping a #hash in the URL, or more recently HTML5 pushState. With this approach the exact state of the web app is embedded in the page URL. As in GMail every time you open a mail a special hash tag is added to the URL. If copied and pasted to other browser window can open the exact same mail (provided they can authenticate). This approach maps directly to a more traditional query string, the difference is merely in the execution. With HTML5 pushState() you can eliminate the #hash and use completely classic URLs which can resolve on the server on the first request and then load via ajax on subsequent requests.
2. With SPA we don't need to use extra queries to the server to download pages.
The number of pages user downloads during visit to my web site?? really how many mails some reads when he/she opens his/her mail account. I read >50 at one go. now the structure of the mails is almost the same. if you will use a server side rendering scheme the server would then render it on every request(typical case).
- security concern - you should/ should not keep separate pages for the admins/login that entirely depends upon the structure of you site take paytm.com for example also making a web site SPA does not mean that you open all the endpoints for all the users I mean I use forms auth with my spa web site.
- in the probably most used SPA framework Angular JS the dev can load the entire html temple from the web site so that can be done depending on the users authentication level. pre loading html for all the auth types isn't SPA.
3. May be any other advantages? Don't hear about any else..
these days you can safely assume the client will have javascript enabled browsers.
only one entry point of the site. As I mentioned earlier maintenance of state is possible you can have any number of entry points as you want but you should have one for sure.
even in an SPA user only see to what he has proper rights. you don't have to inject every thing at once. loading diff html templates and javascript async is also a valid part of SPA.
Advantages that I can think of are:
rendering html obviously takes some resources now every user visiting you site is doing this. also not only rendering major logics are now done client side instead of server side.
date time issues - I just give the client UTC time is a pre set format and don't even care about the time zones I let javascript handle it. this is great advantage to where I had to guess time zones based on location derived from users IP.
to me state is more nicely maintained in an SPA because once you have set a variable you know it will be there. this gives a feel of developing an app rather than a web page. this helps a lot typically in making sites like foodpanda, flipkart, amazon. because if you are not using client side state you are using expensive sessions.
websites surely are extremely responsive - I'll take an extreme example for this try making a calculator in a non SPA website(I know its weird).
Updates from Comments
It doesn't seem like anyone mentioned about sockets and long-polling.
If you log out from another client say mobile app, then your browser
should also log out. If you don't use SPA, you have to re-create the
socket connection every time there is a redirect. This should also
work with any updates in data like notifications, profile update etc
An alternate perspective: Aside from your website, will your project
involve a native mobile app? If yes, you are most likely going to be
feeding raw data to that native app from a server (ie JSON) and doing
client-side processing to render it, correct? So with this assertion,
you're ALREADY doing a client-side rendering model. Now the question
becomes, why shouldn't you use the same model for the website-version
of your project? Kind of a no-brainer. Then the question becomes
whether you want to render server-side pages only for SEO benefits and
convenience of shareable/bookmarkable URLs
I am a pragmatist, so I will try to look at this in terms of costs and benefits.
Note that for any disadvantage I give, I recognize that they are solvable. That's why I don't look at anything as black and white, but rather, costs and benefits.
Advantages
Easier state tracking - no need to use cookies, form submission, local storage, session storage, etc. to remember state between 2 page loads.
Boiler plate content that is on every page (header, footer, logo, copyright banner, etc.) only loads once per typical browser session.
No overhead latency on switching "pages".
Disadvantages
Performance monitoring - hands tied: Most browser-level performance monitoring solutions I have seen focus exclusively on page load time only, like time to first byte, time to build DOM, network round trip for the HTML, onload event, etc. Updating the page post-load via AJAX would not be measured. There are solutions which let you instrument your code to record explicit measures, like when clicking a link, start a timer, then end a timer after rendering the AJAX results, and send that feedback. New Relic, for example, supports this functionality. By using a SPA, you have tied yourself to only a few possible tools.
Security / penetration testing - hands tied: Automated security scans can have difficulty discovering links when your entire page is built dynamically by a SPA framework. There are probably solutions to this, but again, you've limited yourself.
Bundling: It is easy to get into a situation when you are downloading all of the code needed for the entire web site on the initial page load, which can perform terribly for low-bandwidth connections. You can bundle your JavaScript and CSS files to try to load in more natural chunks as you go, but now you need to maintain that mapping and watch for unintended files to get pulled in via unrealized dependencies (just happened to me). Again, solvable, but with a cost.
Big bang refactoring: If you want to make a major architectural change, like say, switch from one framework to another, to minimize risk, it's desirable to make incremental changes. That is, start using the new, migrate on some basis, like per-page, per-feature, etc., then drop the old after. With traditional multi-page app, you could switch one page from Angular to React, then switch another page in the next sprint. With a SPA, it's all or nothing. If you want to change, you have to change the entire application in one go.
Complexity of navigation: Tooling exists to help maintain navigational context in SPA's, like history.js, Angular 2, most of which rely on either the URL framework (#) or the newer history API. If every page was a separate page, you don't need any of that.
Complexity of figuring out code: We naturally think of web sites as pages. A multi-page app usually partitions code by page, which aids maintainability.
Again, I recognize that every one of these problems is solvable, at some cost.
But there comes a point where you are spending all your time solving problems which you could have just avoided in the first place. It comes back to the benefits and how important they are to you.
Disadvantages
1. Client must enable javascript. Yes, this is a clear disadvantage of SPA. In my case I know that I can expect my users to have JavaScript enabled. If you can't then you can't do a SPA, period. That's like trying to deploy a .NET app to a machine without the .NET Framework installed.
2. Only one entry point to the site. I solve this problem using SammyJS. 2-3 days of work to get your routing properly set up, and people will be able to create deep-link bookmarks into your app that work correctly. Your server will only need to expose one endpoint - the "give me the HTML + CSS + JS for this app" endpoint (think of it as a download/update location for a precompiled application) - and the client-side JavaScript you write will handle the actual entry into the application.
3. Security. This issue is not unique to SPAs, you have to deal with security in exactly the same way when you have an "old-school" client-server app (the HATEOAS model of using Hypertext to link between pages). It's just that the user is making the requests rather than your JavaScript, and that the results are in HTML rather than JSON or some data format. In a non-SPA app you have to secure the individual pages on the server, whereas in a SPA app you have to secure the data endpoints. (And, if you don't want your client to have access to all the code, then you have to split apart the downloadable JavaScript into separate areas as well. I simply tie that into my SammyJS-based routing system so the browser only requests things that the client knows it should have access to, based on an initial load of the user's roles, and then that becomes a non-issue.)
Advantages
A major architectural advantage of a SPA (that rarely gets mentioned) in many cases is the huge reduction in the "chattiness" of your app. If you design it properly to handle most processing on the client (the whole point, after all), then the number of requests to the server (read "possibilities for 503 errors that wreck your user experience") is dramatically reduced. In fact, a SPA makes it possible to do entirely offline processing, which is huge in some situations.
Performance is certainly better with client-side rendering if you do it right, but this is not the most compelling reason to build a SPA. (Network speeds are improving, after all.) Don't make the case for SPA on this basis alone.
Flexibility in your UI design is perhaps the other major advantage that I have found. Once I defined my API (with an SDK in JavaScript), I was able to completely rewrite my front-end with zero impact on the server aside from some static resource files. Try doing that with a traditional MVC app! :) (This becomes valuable when you have live deployments and version consistency of your API to worry about.)
So, bottom line: If you need offline processing (or at least want your clients to be able to survive occasional server outages) - dramatically reducing your own hardware costs - and you can assume JavaScript & modern browsers, then you need a SPA. In other cases it's more of a tradeoff.
One major disadvantage of SPA - SEO. Only recently Google and Bing started indexing Ajax-based pages by executing JavaScript during crawling, and still in many cases pages are being indexed incorrectly.
While developing SPA, you will be forced to handle SEO issues, probably by post-rendering all your site and creating static html snapshots for crawler's use. This will require a solid investment in a proper infrastructures.
Update 19.06.16:
Since writing this answer a while ago, I gain much more experience with Single Page Apps (namely, AngularJS 1.x) - so I have more info to share.
In my opinion, the main disadvantage of SPA applications is SEO, making them limited to kind of "dashboard" apps only. In addition, you are going to have a much harder times with caching, compared to classic solutions. For example, in ASP.NET caching is extreamly easy - just turn on OutputCaching and you are good: the whole HTML page will be cached according to URL (or any other parameters). However, in SPA you will need to handle caching yourself (by using some solutions like second level cache, template caching, etc..).
I would like to make the case for SPA being best for Data Driven Applications. gmail, of course is all about data and thus a good candidate for a SPA.
But if your page is mostly for display, for example, a terms of service page, then a SPA is completely overkill.
I think the sweet spot is having a site with a mixture of both SPA and static/MVC style pages, depending on the particular page.
For example, on one site I am building, the user lands on a standard MVC index page. But then when they go to the actual application, then it calls up the SPA. Another advantage to this is that the load-time of the SPA is not on the home page, but on the app page. The load time being on the home page could be a distraction to first time site users.
This scenario is a little bit like using Flash. After a few years of experience, the number of Flash only sites dropped to near zero due to the load factor. But as a page component, it is still in use.
For such companies as google, amazon etc, whose servers are running at max capacity in 24/7-mode, reducing traffic means real money - less hardware, less energy, less maintenance. Shifting CPU-usage from server to client pays off, and SPAs shine. The advantages overweight disadvantages by far.
So, SPA or not SPA depends much on the use case.
Just for mentioning another, probably not so obvious (for Web-developers) use case for SPAs:
I'm currently looking for a way to implement GUIs in embedded systems and browser-based architecture seems appealing to me. Traditionally there were not many possibilities for UIs in embedded systems - Java, Qt, wx, etc or propriety commercial frameworks. Some years ago Adobe tried to enter the market with flash but seems to be not so successful.
Nowadays, as "embedded systems" are as powerful as mainframes some years ago, a browser-based UI connected to the control unit via REST is a possible solution. The advantage is, the huge palette of tools for UI for no cost. (e.g. Qt require 20-30$ per sold unit on royalty fees plus 3000-4000$ per developer)
For such architecture SPA offers many advantages - e.g. more familiar development-approach for desktop-app developers, reduced server access (often in car-industry the UI and system muddles are separate hardware, where the system-part has an RT OS).
As the only client is the built-in browser, the mentioned disadvantages like JS-availability, server-side logging, security don't count any more.
2. With SPA we don't need to use extra queries to the server to download pages.
I still have to learn a lot but since I started learn about SPA, I love them.
This particular point may make a huge difference.
In many web apps that are not SPA, you will see that they will still retrieve and add content to the pages making ajax requests. So I think that SPA goes beyond by considering: what if the content that is going to be retrieved and displayed using ajax is the whole page? and not just a small portion of a page?
Let me present an scenario. Consider that you have 2 pages:
a page with list of products
a page to view the details of a specific product
Consider that you are at the list page. Then you click on a product to view the details. The client side app will trigger 2 ajax requests:
a request to get a json object with the product details
a request to get an html template where the product details will be inserted
Then, the client side app will insert the data into the html template and display it.
Then you go back to the list (no request is done for this!) and you open another product. This time, there will be only an ajax request to get the details of the product. The html template is going to be the same so you don't need to download again.
You may say that in a non SPA, when you open the product details, you make only 1 request and in this scenario we did 2. Yes. But you get the gain from an overall perspective, when you navigate across of many pages, the number of requests is going to be lower. And the data that is transferred between the client side and the server is going to be lower too because the html templates are going to be reused. Also, you don't need to download in every requests all those css, images, javascript files that are present in all the pages.
Also, let's consider that you server side language is Java. If you analyze the 2 requests that I mentioned, 1 downloads data (you don't need to load any view file and call the view rendering engine) and the other downloads and static html template so you can have an HTTP web server that can retrieve it directly without having to call the Java application server, no computation is done!
Finally, the big companies are using SPA: Facebook, GMail, Amazon. They don't play, they have the greatest engineers studying all this. So if you don't see the advantages you can initially trust them and hope to discover them down the road.
But is important to use good SPA design patterns. You may use a framework like AngularJS. Don't try to implement an SPA without using good design patterns because you may end up having a mess.
Disadvantages:
Technically, design and initial development of SPA is complex and can be avoided. Other reasons for not using this SPA can be:
a) Security: Single Page Application is less secure as compared to traditional pages due to cross site scripting(XSS).
b) Memory Leak: Memory leak in JavaScript can even cause powerful Computer to slow down. As traditional websites encourage to navigate among pages, thus any memory leak caused by previous page is almost cleansed leaving less residue behind.
c) Client must enable JavaScript to run SPA, but in multi-page application JavaScript can be completely avoided.
d) SPA grows to optimal size, cause long waiting time. Eg: Working on Gmail with slower connection.
Apart from above, other architectural limitations are Navigational Data loss, No log of Navigational History in browser and difficulty in Automated Functional Testing with selenium.
This link explain Single Page Application's Advantages and Disadvantages.
Try not to consider using a SPA without first defining how you will address security and API stability on the server side. Then you will see some of the true advantages to using a SPA. Specifically, if you use a RESTful server that implements OAUTH 2.0 for security, you will achieve two fundamental separation of concerns that can lower your development and maintenance costs.
This will move the session (and it's security) onto the SPA and relieve your server from all of that overhead.
Your API's become both stable and easily extensible.
Hinted to earlier, but not made explicit; If your goal is to deploy Android & Apple applications, writing a JavaScript SPA that is wrapped by a native call to host the screen in a browser (Android or Apple) eliminates the need to maintain both an Apple code base and an Android code base.
I understand this is an older question, but I would like to add another disadvantage of Single Page Applications:
If you build an API that returns results in a data language (such as XML or JSON) rather than a formatting language (like HTML), you are enabling greater application interoperability, for example, in business-to-business (B2B) applications. Such interoperability has great benefits but does allow people to write software to "mine" (or steal) your data. This particular disadvantage is common to all APIs that use a data language, and not to SPAs in general (indeed, an SPA that asks the server for pre-rendered HTML avoids this, but at the expense of poor model/view separation). This risk exposed by this disadvantage can be mitigated by various means, such as request limiting and connection blocking, etc.
In my development I found two distinct advantages for using an SPA. That is not to say that the following can not be achieved in a traditional web app just that I see incremental benefit without introducing additional disadvantages.
Potential for less server request as rendering new content isn’t always or even ever an http server request for a new html page. But I say potential because new content could easily require an Ajax call to pull in data but that data could be incrementally lighter than the itself plus markup providing a net benefit.
The ability to maintain “State”. In its simplest terms, set a variable on entry to the app and it will be available to other components throughout the user’s experience without passing it around or setting it to a local storage pattern. Intelligently managing this ability however is key to keep the top level scope uncluttered.
Other than requiring JS (which is not a crazy thing to require of web apps) other noted disadvantages are in my opinion either not specific to SPA or can be mitigated through good habits and development patterns.
A friend of mine is programming a web page. Instead of writing any HTML in the .html file, he is outputting the entire website with javascript. Excluding SEO, or the fact that it will be a pain to debug, what are the downsides to this? Also, if there is an upside, what would an upside be?
As you are already aware, SEO is a big deal. SEO is usually the elephant in the room (e.g. the big deal) for javascript-based web-sites and you either forgo SEO or have to somehow design an alternate path that the search engines can index you via and that doesn't run afoul of their rules about serving different content to search engines.
Some potential downsides:
Accessibility - access via screen readers and other tools that may be geared to the page HTML.
Mobile - Sometimes rendering the page will require larger downloads, more javascript code and more data and more CPU to build the page than a simpler server-rendered page. This may cause compromises on small devices without a lot of bandwidth or horsepower.
Performance - The initial page display time may be slower as you can't render anything until all data and code has been downloaded and run. Subsequent page times might be faster or slower depending upon how the app is written. Sometimes you save server trips by doing client-side rendering (which could be faster), but sometimes it's slower to do things on the client.
Security - Somethings simply can't be secured client-side the way they can server-side.
Code secrecy - Code in browsers is open to the world to see. Code on servers can be kept secret.
Same-origin limitations - Browsers are much more limited in who they can contact than servers are because of the same-origin limitation.
Memory - Lots of code and lots of data can consume a lot more memory for your app than a server-generated HTML page. This probably isn't meaningful on a desktop, but could be on a smaller device.
Some of the upsides:
The content can be dynamically rendered with lots of smarts based on the type of user, the screen size, the capabilities of the device, etc... and this local rendering can generally be done more effectively than trying to do it on the server.
You can often do lots of the functions of the app without ever reloading the page, just fetching data from the server or issuing commands to the server with ajax and never reloading the page.
One big downside may be mobile.
Depending on the functionality, a javascript-only page may be slow for those on mobile devices.
The pages may be resource heavy, if you are using one or more libraries and / or accessing lots of information. This could also cost a fair amount for those on mobile devices.
Another downside could be accessibility. Not sure how enabling software for low/no vision users would work with a js only site.
My opinion that such kind of coding is more appropriate for members only areas, that of course are not reachable by search engines.
Provided that you use a good library, that is able to do the layout for you, such as ExtJS, it's an interesting coding. You can build web applications that look similar to desktop applications. Browser differences are smoothed out by the library and expect to have very few problems, if any.
For public websites, in general the SEO argument is a pretty big one. If nobody can find you...
I've been developing in the .NET stack for the past five years and with the latest release of MVC3 and .NET 4.0 I feel like the direction I thought things were headed in were further confirmed.
With the innovative steps the client community has in such a short period of time, it seems like the best in class apps have a UX controlled by a majority of client events. For example, facebook.com, stackoverflow.com, google, www.ponched.com :), etc. When I say client events I am not talking about a server side control wrapped in an UpdatePanel to mask the postback. I am talking about doing all events and screen transitions on the client and use full postbacks only when really necessary. That's not to say things like .NET aren't essential tools to help control security, initial page load, routing, middle tier, etc.
I understand when working on a simple application or under aggressive time constraints using the controls and functionality provided by default by .NET (or other web dev frameworks) isn't practical if the project calls for it but it seems like the developers that can set themselves apart are the ones you can get into the trenches of Javascript/jQuery and provide seamless applications that have limited involvement from the (web) server. As developers we may not think our users are getting more sophisticated because of the big name web applications they are using on the reg but I am inclined to think they are.
I am curious if anyone shares this view or if they have another take on this? Some post lunch thoughts I figured I'd fire out there and see what I got back.
I share this view. We've ironically moving away from thin client and back to thick client, although this time around everything on the client is distributed on-demand via the server so obviously the maintenance overhead is nothing like it used to be.
Rich client-side functionality not only gives you fluid, responsive, interactive apps, but has the significant advantage for large scale sites and applications of being able to palm off a large chunk of processing resources to client browsers rather than having to process everything at their end. Where tens or hundreds of millions of users are involved, this amounts to a very large saving.
I could say more on the matter but time is short. I'm sure there will be other views (assuming the question isn't closed for being subjective).
The point about the developers who set themselves apart is definitely on target. Developers who understand the underlying technologies and can produce customized solutions for their clients are indeed set apart from developers who can drag and drop framework tools and wire up something that works well enough.
Focusing on web development in this discussion, it's vitally important that developers understand the key technologies in play. I can't count how many times I've encountered "web developers" (primarily in the Microsoft stack, since that's where I primarily work) who patently refuse to learn JavaScript/HTML/CSS simply because they feel that the tooling available to them in Visual Studio does the job just fine.
In many cases it does, but not in all cases. And being able to address the cases where it doesn't is what puts a developer above the rest. Something as simple as exposing a small RESTful JSON API and using AJAX calls to fetch just the necessary data instead of POSTing an entire page and re-processing the entire response means a lot to the overall user experience. Both get the job done, but one is considerably more impressive to the users than the other.
Frameworks are great when what you want to do is fully encapsulated in the feature set of the framework. But when you need to grow beyond the framework, it ends up being limiting. That's where a deeper understanding of the underlying technologies would allow a developer to grow outside of the framework tooling and produce a complete solution to the client.
You are right in saying that modern web development involves technologies like jQuery (or similar libraries) and JavaScript in general.
Full page reloads are old fashion and Ajax approach is the way to go, just don't think that the web server is less used or involved than before, it still responds to the ajax calls simply it does it asynchronously :)
MVC does not support any post back actually, because there are no web forms and there is not the same model of page life cycle.