Single-page application kontra klasyczne podejście
Pierwotnie renderowanie HTML całkowicie po stronie serwera było standardem, ale wraz z dynamicznym rozwojem JavaScriptu, sytuacja się zmieniła. Dzisiaj podejście SPA stało się dla wielu firm nowym rozwiązaniem domyślnym. Warto jednak zastanowić się, z jakimi korzyściami i kosztami wiąże się implementowanie MPA (multi-page application) i SPA (single-page application). Wspólnie z Piotrem Szeligą i Mikołajem Jeziornym z RC Cloud porównamy oba podejścia.
Na wstępie: podstawy
MPA to klasyczne rozwiązanie, w którym dynamiczna treść HTML jest generowana po stronie serwerowej. Każde przejście między stronami to żądanie nowej strony HTML. Sieć działa tak od wielu lat, a wszystkie przeglądarki są do tego modelu doskonale zaadoptowane. Takie podejście nie oznacza wcale, że „przerzucamy całą robotę” na serwer. Klient nadal musi parsować HTML, aplikować CSS i wykonywać skrypty JS, których nawet w tym podejściu nie brakuje.
SPA to podejście intensywnie rozwijane w ostatnich kilkunastu latach. Idea jest taka, by raz załadować cały front-end, który będzie ubierał w HTML dane, które przyjdą z serwera. Dzięki temu kolejne akcje nawigacji odbywają się bez przeładowania całej strony, a jedynie części drzewa DOM.
Wydajność
Powszechnie uważa się, że nawigacja w MPA jest dużo wolniejsza niż w SPA, natomiast pierwsze załadowanie strony w SPA będzie wolniejsze niż w MPA. I ogólnie to prawda, jednak obydwa podejścia mają do dyspozycji sporo narzędzi sprawiających, że mogą mieć podobną wydajność.
W ładowaniu kolejnych stron MPA najbardziej pomaga cache przeglądarki. Dzięki niemu - oprócz HTML i obrazków - rzadko trzeba będzie ładować coś więcej przy przejściu między stronami. Faktem jest, że trzeba przeładować pełne drzewo DOM i powtórnie zainicjalizować style oraz skrypty. Jeżeli tych zasobów jest dużo mamy problem, który w SPA byłby mniej odczuwalny po załadowaniu aplikacji.
Przy pierwszym ładowaniu SPA kłopot pojawia się, gdy najpierw ładowana jest pełna aplikacja, a dopiero potem dane. Właśnie to najmocniej wydłuża odczuwalny czas ładowania strony, a niestety takie podejście jest często spotykane. Współcześnie na wielu stronach występuje jednak ładowanie progresywne - czyli np. pre-renderowanie pewnej porcji danych już na back-endzie. Dzięki temu od razu można pokazać znaczące informacje.
Współcześnie mamy w arsenale wiele narzędzi, które pomagają w walce z powolną inicjalizacją. HTTP/2 i Server Push (zobacz, jak w narzędziach deweloperskich ładuje się strona https://angular.io), Service Workery, leniwe ładowanie, wskazówki ładowania zasobów. Gdy właściwie się ich użyje, strona będzie w pełni interaktywna, w naprawdę krótkim czasie. To bardzo pomaga zarówno aplikacjom SPA, jak i MPA.
Warto pamiętać, że przejście na kolejną stronę w SPA wiąże zarówno z kosztami, jak i korzyściami. Więcej powie o tym Mikołaj.
Pod względem wydajności SPA w dużej mierze przerzuca zapotrzebowanie na zasoby na klienta/użytkownika tego rozwiązania. Ładowanie głównej części strony, a następnie zmiana jej zawartości wedle potrzeb ,,na żywo'' jest rozwiązaniem, które umożliwia wprowadzanie znacznie bardziej rozbudowanej logiki. Nie musimy martwić się wtedy o użytkownika oczekującego na ładowanie strony.
Pewnym problemem dużych aplikacji SPA jest zarządzanie pamięcią - musi być sprawne, by uniknąć jej zaśmiecenia. Piotr podkreśla:
Trzeba spojrzeć jednak na potrzeby użytkownika. Jeżeli logika pojedynczego zadania jest bardzo rozbudowana, może okazać się, że lepszym rozwiązaniem będzie przekazanie takiego zadania do serwera i przeładowanie strony w celu zwolnienia zasobów zarezerwowanych wcześniej. W ten sposób udaje nam się odciążyć komputer użytkownika.
Skomplikowanie aplikacji
Samo rozdzielenie prezentacji od reszty logiki poprzez API daje spore korzyści. Przede wszystkim wprowadza loose coupling między logiką backendową, a frontendową. Nikt nie zagwarantuje natomiast, że front i aplikacja serwerowa automatycznie staną się lepsze. Nadal w podejściu SPA można stworzyć apkę niemożliwą do rozwoju i utrzymania. Jednak jest parę bonusów, które po prostu łatwiej uzyskać:
SPA pozwala na zbudowanie strony modularnie - z front-endem niezależnym od back-endu, powiązanym tylko przez API. Działa to na zasadzie mikroserwisów generujących poszczególne zagadnienia logiki aplikacji. Łatwo wyobrazić sobie wtedy, że każdy taki mikroserwis może być nawet w niezależnej infrastrukturze, dając możliwość współbieżności na poziomie fizycznym.
To oczywiście nie znaczy, że to samo jest nieosiągalne w MPA. Zarówno zmniejszenie zależności, jak i oddzielenie infrastruktury jest możliwe, jednak wymaga dokładnego przemyślenia. Jak mówi Mikołaj:
Aplikacje klasyczne również mogą posiadać taką strukturę, która będzie jednak znacznie bardziej uzależniona od usług sieciowych oraz administracji. Temat jest w zasadzie tak samo skomplikowany, używa się bardzo podobnych narzędzi, a zmienia się jedynie sposób myślenia. Można wyobrazić sobie sytuację, w której mamy aplikację webową. Logika jej front-endu składa widok z kilku źródeł danych, z których każde jest osobnym mikroserwisem – aplikacją back-endową, tworzoną przez osobne zespoły developerów.
Ciekawą zaletą SPA jest to, że cały front-end to statyczne pliki, które można łatwo porozmieszczać na CDN. Ba, nie trzeba nawet mieć wtedy serwera typu nginx czy apache do hostowania plików związanych z frontendem.
Jeżeli mowa o samym skomplikowaniu rozwiązania, w większości przypadków MPA będzie prostsze. Wsparcie frameworków MVC dla tego typu stron jest bardzo dobre i w zasadzie każdy oferuje renderowanie HTML. To bardzo stabilna technologia, która nie zmieniła się na przestrzeni ostatnich lat - w przeciwieństwie do tego, co dzieje się w świecie JS:
Natomiast to, że backend wystawia API w SPA, będzie dużą zaletą, o ile w grę wchodzi aplikacja mobilna - co też warto podkreślić.
SEO
Tu narosło sporo mitów i czas je wyprostować. SEO w SPA może być tak dobre, jak w MPA. Wymaga co prawda dobrego przemyślenia i na pewno nie będzie to tak łatwe, jak w przypadku wielu stron generowanych na backendzie, jednak jest jak najbardziej możliwe. Piotr Szeliga zauważa:
Google w swoich zaleceniach promuje dziś technologię SPA. Mówimy o coraz lepszym odczytywaniu skryptów na stronach przez roboty indeksujące, mamy też strony mobilne w technologii AMP.
Jak widać, wszystko idzie w kierunku coraz bardziej dynamicznych stron i w ciągu ostatnich kilku lat widzieliśmy duży postęp, jeżeli chodzi o wsparcie dla takich aplikacji. Google potwierdziło kilka lat temu, że ich robot jest w stanie czytać i wykonywać CSS i JS. Podobne umiejętności mają inne wyszukiwarki.
Znacznie większym problemem jest poprawne używanie metatagów oraz stosowanie tzw. progressive enchancements, zalecanych przez Google. Obydwie kwestie są łatwiejsze do zaimplementowania w przypadku MPA.
Sytuacja z SEO wynika w dużej mierze z historii - SPA były najczęściej używane jako aplikacje biznesowe:
W przypadku, kiedy tworzymy aplikację narzędziową dla wybranej grupy użytkowników segmentu B2B, względy SEO nie mają praktycznie znaczenia. Aplikacja sama w sobie nie sprzedaje się przez Internet.
- podkreśla Piotr. Stąd dobre praktyki potrzebowały nieco czasu, by dotrzeć do świata frontu.
Do dzisiaj firmy zachowują się bardzo zachowawczo.
Ponieważ reguły SEO nie są przeważnie jednoznaczne to trudno wskazać przykłady firm, dla których Internet jest głównym źródłem dochodów i zaryzykowałyby pełne podejście typu SPA. W tej branży funkcjonuje wiele mitów, które można obalać lub nie, jednak najczęściej spotykamy się z rozwiązaniem, gdzie strony generują się klasycznie (główna część strony), a niektóre bloki, widgety, narzędzia doładowują się np. asynchronicznie.
Co wymaga więcej pracy?
Mikołaj tłumaczy, że tempo tworzenia SPA i MPA będzie podobne:
Na dzień dzisiejszy posiadamy gotowe rozwiązania pokroju Angular, React i Vue.js, zapewniające tworzenie strony SPA w zasadzie od ręki. W przypadku MPA wygląda to podobnie, bo mamy wiele gotowych silników/frameworków typu: Django, Symfony, Yii.
W dużym skrócie: ilość pracy byłaby podobna, ale rozłożona w różnym stopniu pomiędzy back-end, a front-end.
Wydaje się więc, że wybór podejścia zależy też od kompetencji teamu tworzącego oprogramowanie oraz obszaru zastosowania tworzonego oprogramowania. Dwóch full-stack devów może rozwijać aplikację MPA tak samo szybko, jak para front-end i back-end dev aplikację SPA.
Kiedy SPA, a kiedy MPA?
Ciężko czasem stwierdzić jednoznacznie, na które podejście się zdecydować. Możemy jednak wyróżnić pewne modelowe przypadki zastosowania obydwu typów stron, o czym więcej powie Mikołaj:
Idealny scenariusz dla SPA:
Aplikacja (typowo B2B) gdzie każda operacja wymaga wielu interakcji z użytkownikiem.Idealny scenariusz dla MPA:
Serwis treściowy, na którym interakcja użytkownika jest niewielka, a istotna jest unikalność treści oraz pozycjonowanie w wyszukiwarkach.
Im więcej przeładowywania, doładowywania i prezentowania na różnych zmieniających się dynamicznie widgetach, tym bardziej będzie się sprawdzać podejście SPA - do tego zostały stworzone rozwiązania dostępne na rynku. Natomiast gdy króluje treść i struktura może być ciężko wykorzystać w pełni możliwości współczesnych frameworków. Wtedy MPA będzie z jednej strony szybsze do zaimplementowania, a z drugiej będzie bezpieczniejsze ze względu na SEO.
Coraz częściej aplikacje webowe stają się hybrydami, których pewne elementy są renderowane na back-endzie, a inne na front-endzie. To rozwiązanie pozwala na wydobycie największych korzyści z obydwu rozwiązań, jednak zmusza programistów do radzenia sobie z problemami odziedziczonymi z obydwu podejść. Wydaje się, że - pomimo najlepszego w historii dostępu do narzędzi - nadal bardzo dużo wysiłku kosztuje wykorzystanie wszystkich możliwości i ominięcie pułape k.
Piotr z RC Cloud podsumowuje:
Jak zawsze, wszystko zależy od tego, do czego dana strona/aplikacja będzie wykorzystywana. Oba rozwiązania posiadają duże zaplecze od strony technologicznej, są skomplikowane i wymagają dużego nakładu pracy, by wykorzystać je dobrze. Różnią się głównie zastosowaniami i odczuciami przy ich użytkowaniu. Dziś świat idzie w kierunku rozwiązań aplikacyjnych i ograniczenia ilości przeładowań. Trudno jednak wskazać przykład znaczącego serwisu treściowego, dla którego najważniejsze jest pozyskanie ruchu z wyszukiwarek i opartego w całości na rozwiązaniach SPA.