Die Messlatte von Webanwendungen und Webseiten hat sich in den letzten 10 Jahren stark erhöht, was nicht zuletzt dem erhöhten Einsatz von clientseitiger Logik geschuldet ist.
Daraus zu interpretieren JavaScript, Dynamik und Eyecandy hat alles besser gemacht ist allerdings ein falscher Schluss: Über die Funktionalität und Qualität will ich hier keine Aussage machen – es gab auch früher und gibt heute noch sehr viele statische Site-per-Site Anwendungen an denen sich neue Tools eine Scheibe abschneiden können.
Was aber auf der Hand liegt: Wer heute eine erfolgreiche Webanwendung entwickeln will muss sich mit dem Desktop messen (z.T. ist das heute auch schon umgekehrt so). Ein ‘das ist halt im Browser, das geht nicht anders’ frisst heute niemand mehr als Ausrede wenn sich eine Anwendung nicht so anfühlt wie erwartet. Und gleichzeitig ist man als Entwickler wie ein Kind im Süßigkeitenladen: Überall gibt es feine Sachen, will man aber alles auf einmal naschen wird man sich früher oder später übergeben.
Und damit wäre dieser epische Prolog auch schon am Knackpunkt: Wie entscheide ich mich für das ‘richtige’ Architekturmodell für meine Webanwendung?

Was habe ich für eine Anwendung?

Nicht jede Anwendung braucht clientseitige Logik, aber fakt ist: Je komplexer und länger die einzelnen Arbeitsprozesse sind und je mehr sich einzelne Arbeitsschritte gegenseitig beeinflussen, umso stärker bietet sich der Client zur Unterstützung an.
Habe ich z.B. nur ein einfaches Webinterface mit ein paar einfachen Eingabemasken (z.B. Nutzer anlegen) brauche ich nicht unbedingt Dynamik: Zeige Form, sende Form, zeige Fehler oder Erfolg – das geht auch ohne JavaScript.
Wird das Formular aber größer bietet es sich bald an direktes Feedback zu geben. Zum Schluss denkt unser Nutzer noch, er versorgt uns mit sinnvollen Informationen – nur um bitter enttäuscht zu werden nachdem er das 30 Eingabefelder Formular abgeschickt hat (und schon zum zehnten mal sein Passwort neu eingeben musste). Da macht es Sinn, wenn man sofort Feedback geben kann wo der Fehler liegt (ok, bald gibt es HTML5 Form Validation, aber das deckt auch nicht alles ab).
Und natürlich: Es gibt natürlich Anwendungen, die Leben von Dynamik und gehen nicht ohne JavaScript: Google Docs, Pixlr, canvasrider, etc.

Klassische Client/Server Anwendung oder Rich Internet Application?

Webanwendungen brauchen nicht immer JavaScript und können sich in neueren Browsern trotzdem dynamisch anfühlen. Vieles, was früher nur durch Skripte (Animationen) realisierbar ist mit CSS3 und HTML5 Features heute machbar. Ist man konsequent serverseitig muss man aber jeden Prozessschritt einmal zum Server schicken und dann auf eine Antwort warten. 

Der Vorteil ist, dass sowohl Textbasierte Browser als auch Screenreader die wenigsten Probleme mit solchen Seiten haben. Der Nachteil ist dass bei jedem Prozessschritt der komplette Prozesskontext (was habe ich gerade getan? Was habe ich in den letzten 10 Schritten getan?) entweder in der URL oder in der Session gespeichert werden muss. Bei komplexeren Aktionen macht das (mir zumindest) in der Entwicklung keinen Spaß.
In vielen Fällen lohnt sich dieser Aufwand nicht für, vor allem für die wenigen Fälle in denen JavaScript deaktiviert ist. Der gängigste Ansatz ist daher zwar HTML auszuliefern, jedoch wenn es sich anbietet mit clientseitigen Skripten zu arbeiten, bzw. Informationen dynamisch nachzuladen. Wechselt man die Ansicht oder den Prozess (z.B. durch einen Klick im Navigationsmenü) wird ein ganz normaler Request beim Server zum Server gesendet und die Seite neu gerendert. Der Sinn liegt auf der Hand: Ohne Rücksicht auf den Server kann man sich so austoben, Daten z.B. per RaphaelJS als graphisch darstellen, Formulare Schrittweise validieren und darstellen usw.
Die Tücke liegt aber in der Code und Schnittstellenorganisation: Wie organisiere ich meine Schnittstellen? Was macht der Client, was der Server? Was will ich mit direkt per URL aufrufen können und was nicht? Viele machen den Fehler und beginnen mit ‘ein paar Schnipseln’ unorganisierten JavaScript Code, der schnell zum chaotischen Haufen wächst.
Der dritte, radikalere – und ein wenig gehypte – Ansatz der letzten Jahre sind Single-Page Applikationen mit JavaScript (Stichwort Rich Internet Application). Initial wird meist nur rudimentäres HTML geliefert, die komplette Seite (d.h. das Markup) wird clientseitig erstellt. Der Server hingegen ist lose gekoppelt und enthält sehr wenig Logik (oft nur Datenabfrage und Authentifizierung), was das Modell meist zur ersten Wahl macht wenn eine Webanwendung auch Offline funktionieren soll.
Der Charme für Entwickler: Viele Frameworks (Sproutcore, Qooxdoo, ExtJS, uvm.) erlauben es fast ausschliesslich mit bestehenden Komponenten zu arbeiten, nehmen einem damit den Kampf mit HTML und CSS ab (viele Konzepte kommen hier direkt aus der grafischen Desktopentwicklung). Gerade zu Beginn des Projektes kommt man so sehr schnell zu anschaulichen Ergebnissen.
So viele Vorteile das Modell hat, so schwer wiegen hier auch die Nachteile. SEO Optimierung ist ein Graus, Fehlerlogging und -behandlung oft tückischer (die Anwendung steht und keiner hat eine Fehlermeldung) und Barrierefreiheit ist eine eigene Herausforderung (wenn auch möglich mit WIA-ARIA).
Das macht das Modell nicht schlechter, aber meiner Erfahrung nach (noch) nicht so allzwecktauglich wie ein kombiniertes Client-Server Modell.

Und was soll ich jetzt bei meiner Anwendung XY als Architekturmodell nutzen?

‘Die’ Antwort gibt es da leider nicht. Und die will auch auch hier nicht geben. Ich habe zwar subjektiv die Erfahrung gemacht, dass clientseitige Frameworks wie ExtJS, Qooxdoo und AngularJS die Entwicklungszeit bis zum ersten Rollout verkürzen können und dabei schicke Ergebnisse herauskommen. Oft ist es aber auch so, dass manche Anforderungen einem mit dem klassischen Client-Server Ansatz einfach weniger Sorgen machen und durch UI-Frameworks wie Bootstrap mittlerweile auch inital weniger Designlast auf den Schultern des Entwicklers liegt (dafür aber auch Modifizierungen einfacher sind).
Ich kann nur von einem definitiv abraten: Beide Ansätze halbherzig zu vermischen. Wer z.B. eine JavaScript Applikation mit ExtJS anfängt sollte das mit dem Bewusstsein tun, dass dieser Ansatz in seinem Falle der Beste ist (und nicht anfangen, HTML Fragmente von einem PHP Server abzufragen). Und wer eine Grails Anwendung startet sollte nicht anfangen große Teile der Prozesse mit AngularJS vom Server abzukoppeln. Das kann gut gehen, endet aber meist in einem Chaos.
Es gilt die für die Anwendung konkreten Vor- und Nachteile zu Beginn zu identifizieren (ich hoffe ein paar Anhaltspunkte habe ich bereits geliefert, sonst war der Artikel wohl sehr sinnlos) und in die Entscheidung mit aufzunehmen. In der Entwicklung gilt es dann, das Beste aus einem Konzept herausholen und – noch wichtiger – die Nachteile bewusst zu akzeptieren und zu berücksichtigen.