wtorek, 3 lipca 2012

Architektura nowoczesnej aplikacji webowej (przykład P&P)

Przykładowa aplikacja Project Silk: Client-Side Web Development for Modern Browsers z witryny Patterns & Practises jest kolejną próbą praktycznego sformalizowania - po przyjęciu pewnych założeń - dość szerokiego terminu “aplikacja HTML5”.

Przykładowa aplikacja po wykonaniu wskazanych kroków oczywiście działa, a dokument ma przeszło 300 stron… Jego lektura po pewnym czasie staje się nieco nużąca, pewne rzeczy są dość oczywiste, pewne rzeczy moim zdaniem dość ogólnie, innym razem sporo szczegółów, co nie zawsze jest koniecznie przydatne do wytworzenia pewnej wizji na całość…, pewne rzeczy się powtarzają w myśl od ogółu do szczegółu, co czasami jednak wydawało się pewnym nadmiarem….  Ale do rzeczy, z tej całości wynotowałem parę sentencji, które prezentuję poniżej:

1. Kolejne upomnienie dla wszystkich tych, którzy myślą, że do otrzymania pełnej nowoczesnej aplikacji HTML5 wystarczy zamienić w dotychczasowych mocno serwerowych  aplikacjach tagi w HTML4 na tagi z HTML5… Super nie będzie, ale w sumie to też byłaby jakaś forma aplikacji w HTML5 (co dowodzi szerokości tego pojęcia).  Natomiast jak chcemy mówić o nowoczesnej aplikacji webowej, to musimy zmienić całościowe podejście, zacząć myśleć o bogatym kliencie, który wymienia się głównie samymi danymi ze stroną serwerową. Często objawia się to niewielką ilością pełnych przeładowań stron (podejście hybrydowe - część widoków przeładowywana lokalnie po stronie klienta zwykle związana z tą samą tematyką/modułem w ramach dużej aplikacji), a nawet mamy oficjalny wzorzec aplikacji jednostronicowej tzw. single-page interface (np. serwisy twitter, hot mail, office live, …). Co nam daje lokalne przeładowywanie widoków? Zyskamy na szybkości zmieniając poprzez wywołania AJAX tylko pewne obszary strony (nie ładujemy od nowa całej strony, przesyłamy zazwyczaj tylko dane zamiast całego HTML), co dodatkowo można zoptymalizować poprzez trzymanie części danych w lokalnym cache po stronie klienta (co jednocześnie odciąży serwer). Po drugie efekty przejścia - animacje i  tranzycje…, które napotkają na ograniczenia przy pełnym przeładowywaniu stron. Hola, hola, to po co jeszcze przyciski “back” i “next” w przeglądarce, po co złożone adresy? Nawigacji lokalnej nie wymyślono sobie od teraz, adresy z # do wskazanych obszarów tej samej strony już istnieją od jakiegoś dłuższego czasu.  Taki sposób adresowania z # został wykorzystany przez Silverlight do wspierania lokalnej nawigacji, która z powodzeniem integruje się z paskiem adresowym i historią przeglądarki, a Silverlight nie był tu pierwszy. API w bibliotekach JavaScript i w samym HTML5 nie jest tutaj gorsze, a nawet daje więcej możliwości…(więcej szczegółów w pkt. 4). Na zakończenie uwaga, że nawet najnowsze ASP.NET MVC można używać w diametralnie różny sposób. Można nadal po stronie serwera wykonywać większość zmian na widokach oraz je przeładowywać, ale można też zastosować nowoczesne, klienckie podejście i kontrolery wykorzystywać jedynie do zwracania samych danych. Nie popadajmy też zawsze w skrajności w skrajność, czasami umiejętne połączenie operacji po stronie serwera i klienta może być w pewnych sytuacjach bardziej optymalne (np. szablony HTML używane po stronie klienta mogą mieć pewne wstawki zmodyfikowane przez stronę serwerową; czasami lepiej jest pobrać z serwera jakiś fragment HTML niż budować go dynamicznie po stronie klienta itp).

2. Modularyzacja kodu po stronie klienckiej. Niewątpliwie jak chcemy zbudować porządną, łatwo zarządzalną i rozszerzalną aplikację, nie obejdziemy się bez tworzenia kodu JavaScript w postaci odseparowanych modułów. Jeśli chodzi o warstwę UI, wizualne elementy, autorzy postawili na tworzenie widgetów w jQuery UI, co jest jakby odpowiednikiem tworzenia kontrolek. Elementy logiczne niezwiązane z UI radzą zrealizować w ramach modularyzacji samego JavaScript. Mi osobiście zabrakło tutaj pokazu praktycznego zastosowania view modeli Knockout z data bindingiem… W Silverlight/WPF udało mi wypracować koncepcję polegającą na umiejętnym łączeniu podejścia MVVM z kontrolkami (czasami także własnymi) bez popadania w ortodoksję w jedną lub drugą stronę… Może i tutaj się mi się uda, ale nie za sprawą tej publikacji. Odnośnie kwestii modularyzacji samego JS autorzy wspominają także o Prototype i script.aculo.us, natomiast jako bardziej całościowe dla aplikacji wymieniają z nazwy takie frameworki jak sproutcore, yui czy dojo toolkit.

image

3. Tak naprawdę autorzy chcieli - przynajmniej w części zagadnień - “być dobrzy” dla jak największej liczby klientów, także dla tych, którzy… w swoich przeglądarkach mają wyłączoną obsługę JavaScript. W przypadku nawigacji przełożyło się to na generowanie linków po stronie serwera do tradycyjnej nawigacji z pełnym przeładowywaniem stron, natomiast po wykryciu obsługi JavaScript w przeglądarce zastępowanie serwerowej struktury lokalną. To zastępowanie dotyczy nie tylko nawigacji, ale też fragmentów HTML, akcji na przyciskach, klas CSS … W trybie z JavaScript oferujemy użytkownikowi animacje, tranzycje między stronami, wywołania AJAX … (tzw. podejście progressive enhancement - dodawanie funkcjonalności w zależności od możliwości przeglądarki). Dla dużych “światowych” witryn podejście z pewnością bardzo pożądane, ale w przypadku mniejszych projektów skierowanych dla określonych grup odbiorców, czy nie oznacza zbyt dużego nakładu pracy?  Wtedy każda wbudowana funkcjonalność w przeglądarkę wiąże się z … dodatkową pracą, bo nie dość, że normalnie coś obsługujemy, to implementujemy także alternatywne rozwiązanie, jakby tej funkcjonalności nie było.

4. W pkt.1 zapowiedziałem więcej szczegółów odnośnie zorganizowania lokalnej nawigacji w HTML5 i JavaScript. Autorzy proponują skorzystanie z plug-inu jQuery o nazwie BBQ, który jest odpowiedzialny za modyfikacje w adresie URL. Przekłada się to na obsługę deep-linking (parsowanie, mergowanie linków podczas ich tworzenia i aktualizowania, możliwość dynamicznej modyfikacji, metody: getState - zwraca obiekt z elementami klucz-wartość i pushState) oraz na integrację z historią przeglądarki. Samo API HTML5 też wspiera lokalną nawigację. Mamy tu m.in zdarzenie hashchange (obsługiwane np. w IE8 i IE9). BBQ wykorzystuje je, a dodatkowo radzi sobie także w przeglądarkach, które go nie obsługują. Przy tematyce samego HTML5 i nawigacji warto uczynić dygresję, że sam HTML5 dostarcza też API do zarządzania historią przeglądarki bez identyfikatora fragmentu (window.history - pushState i replaceState, wspierane np. w IE9)

5. Cachowanie danych autorzy realizują za pomocą swojego obiektu JS zamiast lokalnego storage w HTML5 i innych podobnych API, co pozwala im być bardziej cross-browser (np. obsłużyć IE7). Podobnie jak w pkt.3 swój punkt widzenia dla takiego podejścia uzależniam od rzeczywistej skali projektu.

6. W kwestii layoutu autorzy nie wchodzą bardzo w techniczne szczegóły, bardziej skupiają się na samych koncepcjach. Warto odnotować, że wspominają o dość popularnym 960 Grid System.

7. Walidacja JS po stronie klienta powinna być traktowana w kategorii udogodnienia, a nie zastąpienia walidacji po stronie serwera. Wymagają tego względy bezpieczeństwa.

8. Unit testy. O ile strona serwerowa z ASP.NET MVC wydaje się dość przewidywalna, o tyle warto wspomnieć o testowaniu warstwy klienckiej w JavaScript. Autorzy proponują skorzystanie z frameworka QUnit używanego przez samą bibliotekę jQuery.

Brak komentarzy: