Wróć do strony głównej
Angular

O server-side rendering w Angular

Jak rozpocząć pracę z server side rendering (SSR) w Angular? Na co uważać? Na te pytania odpowie nam Tomasz Borowski, trener szkoleń Angular in Spacektórego zaprosiłem do wpisu gościnnego na moim blogu.

Autor Tomasz Borowski
Tomasz Borowski

Tomasz Borowski to frontend developer z 10 letnim doświadczeniem programistycznym, pracujący na co dzień przy implementacji złożonych aplikacji biznesowych w frameworku Angular. Od czasu do czasu występuje także jako prelegent na konferencjach międzynarodowych (w tym ngPoland, Agile Lean Europe) oraz lokalnych meetupach (w tym Angular Tricity, meet.js, dev.js). Od ponad dwóch lat prowadzi także serię warsztatów szkoleniowych Angular in Space.

Powrót do przeszłości?

Wiele lat temu, zanim podejście Single Page Application (SPA) stało się standardem w tworzeniu aplikacji webowych, mieliśmy do czynienia z aplikacjami, które w odpowiedzi na działanie użytkownika wysyłały gotowy do wyrenderowania w przeglądarce markup HTML. Taka forma komunikacji klient-serwer nie pozwalała na ponowne użycie wyświetlonych już fragmentów strony i sprawiała wrażenie wolniejszego działania, bo wymagała pełnego przeładowania strony.

Zastosowanie podejścia SPA pozwoliło na jednokrotne załadowanie do przeglądarki aplikacji webowej, która po uruchomieniu wiedziała “jak ma wyglądać i jak się ma zachowywać”. Dotychczasowa forma  komunikacji klient-serwer została uproszczona do zwykłej wymiany danych, najczęściej w oparciu o obiekty JSON. Aplikacje SPA sprawiały wrażenie szybszych i ładnie oddzielonych od technologii backendowych.

komunikacja klient-serwer

źródło: https://msdn.microsoft.com/en-us/magazine/dn463786.aspx

 

Dlaczego więc w ogóle rozważać renderowanie aplikacji po stronie serwera? Otóż duża ilość danych, jakie muszą zostać pobrane aby uruchomić aplikację SPA, wyrazie opóźnia dostępność aplikacji na wolniejszych urządzeniach lub tych korzystających ze słabego łącza internetowego. Również boty indeksujące strony internetowe mogą mieć problem z poprawnym indeksowaniem skomplikowanych aplikacji SPA.

Czy zatem da się połączyć zalety aplikacji SPA i generowania HTMLa po stronie serwera? Tak, a tworząc aplikację Angular możemy to łatwo zrobić z Angular Universal.

logo angular universal

Jak SSR działa w Angular?

Ideą server-side renderingu (SSR) w Angular jest szybkie zwrócenie przez serwer gotowego do wyrenderowania markupu HTML, podczas gdy aplikacja SPA będzie niezależnie pobierana w tle. Po ukończeniu tego pobierania, aplikacja zastępuje dotychczas wyrenderowany, statyczny HTML, oferując już pełne możliwości aplikacji.

Od strony technicznej będziemy mieli do czynienia z dwoma aplikacjami: nasza dotychczasowa aplikacja w Angular oraz Universal web server, który będzie odpowiedzialny za serwowanie assetów oraz wygenerowanie początkowego markupu HTML.

Diagram różnic Angular a Angular Universalźródło: https://medium.com/capital-one-tech/a-peek-into-the-open-source-technologies-behind-capitalone-com-80bae5ca9279

Jak wdrożyć SSR w aplikacji Angular?

Krok 1: Podążaj za Guide’m

Aby wdrożyć SSR w swojej aplikacji Angular zapoznaj się z oficjalnym Guide’m Angular Universal i wykonaj procedurę setupu krok po kroku. Jednakże jest parę spraw, o których warto dodatkowo pamiętać.

Krok 2: Blokuj warunkowo zapytania HTTP na starcie aplikacji

Kod odpowiedzialny za wywoływanie zapytań HTTP na starcie aplikacji może zostać wykonany dwukrotnie: w trakcie server-side renderingu oraz w przeglądarce podczas uruchamiania aplikacji Angular. Postaraj się wyeliminować to pierwsze wywołanie, gdyż może ono negatywnie wpłynąć na czas renderowania markupu HTML po stronie serwera. W tym celu można przygotować osobną konfigurację zmiennych środowiskowych w Angularze, dzięki której będziemy mogli blokować zapytania HTTP tylko w aplikacji renderowanej po stronie serwera.

Krok 3: Przygotuj się na brak dostępności API przeglądarki

Podczas przygotowywania aplikacji do renderowania po stronie serwera pamiętaj, że nie będzie tam dostępne standardowe API przeglądarki. Jeśli korzystasz w aplikacji z obiektów window, document, localStorage itp. to będziesz musiał je zamockować (wykorzystać sztuczne / uproszczone obiekty). W tym celu możesz wykorzystać bibliotekę mock-browser.

Mierzenie korzyści w praktyce

Warto zaznaczyć, że zalety stosowania SSR są słabo zauważalne na szybkich urządzeniach, dysponujących szybkim łączem internetowym. Aby sprawdzić, jak aplikacja ładuje się w przeglądarce w “nieco trudniejszych warunkach” otwórz Chrome Chrome Dev Tools, a następnie w zakładce network wybierz łącze “Slow 3G” i zaznacz “Disable cache”.

Dev tools - wyłączony cache

Po odświeżeniu okna przeglądarki będziesz mógł zaobserwować jak aplikacja jest ładowana. Zwróć uwagę, że już w odpowiedzi na pierwszy request przeglądarka otrzymuje markup HTML, który może wyrenderować i nie musi czekać na pobranie oraz uruchomienie całej aplikacji Angularowej.

Misja wprowadzenia do angular - preview

Aby zmierzyć korzyści z wdrożenia SSR w naszej aplikacji otwieramy Chrome Dev Tools na zakładce “Audits”. Interesuje nas audyt pod kątem “Performance” na symulowanym łączu “Fast 3G” i przy obniżonych parametrach CPU. Należy przeprowadzić taki sam audyt dla aplikacji korzystającej z SSR oraz dla wersji bez SSR. Dzięki temu będziemy mogli porównać wyniki i zauważyć korzyści server-side renderingu. Dla strony związanej ze szkoleniami Angular in Space audyt wykazał średnie skrócenie czasu pierwszego wyrenderowania zawartości strony z 4.1 sekund na 1.9 sekundy dla urządzeń mobilnych na łączu Fast 3G. Do testowania szybkości naszych web aplikacji możemy także wykorzystać takie narzędzia jak PageSpeed Insights czy Webpagetest.

Dane laboratyjne przy emulowanym połączeniu 3G

Wyniki testu PageSpeed Insights dla aplikacji bez SSR

Dane laboratyjne przy emulowanym połączeniu 3G

Wyniki testu PageSpeed Insights dla aplikacji z SSR

Podsumowanie

Server-side rendering z Angular Universal jest techniką przydatną w sytuacji, gdy chcemy szybciej dostarczyć początkową treść naszej strony na słabszych urządzeniach z wolniejszym dostępem do internetu. Dodatkową zaletą jest lepsza współpraca aplikacji z botami indeksującymi strony internetowe. Jednakże jeśli nie zależy nam na powyższych korzyściach, to SSR zdecydowanie nie jest nam niezbędny do życia 🙂

O autorze

Tomasz Borowski

Tomasz Borowski to frontend developer z 10 letnim doświadczeniem programistycznym, pracujący na co dzień przy implementacji złożonych aplikacji biznesowych w frameworku Angular. Od czasu do czasu występuje także jako prelegent na konferencjach międzynarodowych (w tym ngPoland, Agile Lean Europe) oraz lokalnych meetupach (w tym Angular Tricity, meet.js, dev.js). Od ponad dwóch lat prowadzi także serię warsztatów szkoleniowych Angular in Space.

Zapisz się do naszego newslettera. Bądź na bieżąco z najnowszymi trendami, poradami, meetupami i stań się częścią społeczności Angulara w Polsce. Rynek pracy docenia członków społeczności.

8 komentarzy

  1. Tomek Sochacki

    Wszystko super ale nie do końca zgodzę się z tym blokowaniem http requestów z poziomu serwera. Sam niedawno wdrażałem nieco większy portal właśnie z Angular SSR i SSR zrobiłem właśnie głównie pod google SEO i jednym z kryteriów było otrzymanie w response html wypełnionego zwrotką z API… Zabrakło mi w artykule wzmianki tylko o tym, aby w takich sytuacjach odpowiednio zabezpieczyć się przed ryzykiem rerenderingu tych komponentów client-side i ponownego wysłania requestów, ale to nie jest trudne do ogrania.

    • Tomasz Borowski

      Dobra uwaga, rzeczywiście są przypadki, gdzie będzie nam zależało na wyrenderowaniu danych z API już po stronie serwera. Jednak należy w takich przypadkach pamiętać tylko, by to zapytanie do API było szybkie i nie spowolniło wyrenderowania strony 🙂

  2. Tomasz Borowski

    @wojtrawi SSR w Angularze to taki temat „jednorazowy”, tzn. raz konfigurujesz wg guide’a i potem zapominasz o tym na dłuższy czas – stąd pewnie nie pojawi się na szkoleniu. Lepiej skoncentrować się na rzeczach, z którymi ludzie będą stykać się codziennie 🙂

  3. tomek

    to ja nadal jestem zwolennikiem choćby próby pobrania danych server side, zawsze przeciez można wprowadzić jakiś timeout i przesłać w razie czego dane niepelne do klienta i tam wykonać kolejną probe… logikę timeoutow i retry można przecież zaszczepić inna dla servera i inna client side… moim zdaniem warto ponieść nieco wiekszy wkład pracy w konfig ssr i api bo może to dac wymierne korzyści. A na marginesie to fajny blog, chyba jedyny polski na takim poziomie i czysto techniczny, dzięki za chęci i Twój czas poświęcony na dzielenie się wiedzą.

  4. MMM

    Sądzę, że zamiast blokować requesty do serwera powinno się skorzystać z Route Resolverów, które są stworzone po to właśnie, aby uniknąć renderowania zanim zostanie pobrania zawartość. Pkt. 2, wydaje mi się bezsensowny przy odpowiednio zaprojektowanej aplikacji Angular

  5. Marcin

    Wspomniałeś o mockowaniu API przeglądarki, a co w przypadku sprawdzania czy aplikacja startuje w przeglądarce a nie na serwerze za pomocą funkcji isPlatformBrowser? Czy to nie byłoby lepsze podejście?

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *