fbpx

Posłuchaj nowego odcinka podcastu już teraz 🙂 

<

W pierwszym odcinku podcastu DEVision omówimy temat Single-Page Application. Host podcastu – Nikodem Smalera – będzie rozmawiać z Jakubem Różyckim, Full Stack developerem o takich zagadnieniach jak:
👉 czym jest SPA – Single-Page Application
👉 w jakich sytuacjach użycie SPA jest lepsze od Multi Page Application
👉 jakie wyzwania wiążą się z pracą z Single-Page Application

Zobacz cały wywiad na naszym kanale YouTube:

Nikodem: Ja Cię już trochę znam, ale nasi widzowie jeszcze nie, więc zanim przejdziemy do głównego tematu naszej rozmowy to może byś się przedstawił? Kim jesteś i co robisz na co dzień?
Jakub: Jestem programistą Full Stack – może nie do końca jeszcze wiadomo, co to dokładnie oznacza, ale pod koniec podcastu wiele się rozjaśni. 😉 Pracuję dla niemieckiego start-upu o nazwie “InoVirtue” – należę do zespołu w Krakowie, który stworzyłem wraz z moimi kolegami, wspólnie z którymi zająłem się wyborem technologii, architekturą oraz onboardingiem. W firmie jestem również odpowiedzialny za Front End, który tworzę w Reakcie oraz Back End, który piszę w języku .NET. Zajmuję się też naszą chmurą Azure, ponieważ lubię się poruszać w wielu obszarach aplikacji.

Ile lat doświadczenia masz z tzw. “webówką”?
Webówka była pierwszą rzeczą, jaką się zająłem – przygodę z nią zacząłem już w piątej klasie podstawówki. Wtedy po raz pierwszy doświadczyłem programowania w HTML-u i udało mi się nawet stworzyć stronę, na której znajdowały się wymagane style oraz filmik. Następnie zrobiłem sobie kilka lat przerwy od programowania, by później pójść do liceum o profilu informatycznym, gdzie nauczyłem się tworzyć proste, “wizytówkowe” strony internetowe.

Od razu po skończeniu liceum rozpocząłem staż – wtedy były nieco inne lata, więc chętnych na takie szkolenie nie było zbyt wielu. Ja za to byłem jedną z tych osób, które uważały, że w niedalekiej przyszłości ta branża może okazać się całkiem fajna. 😉 Po ukończeniu stażu w firmie pracowałem w niej jeszcze 2 lata i w tym czasie tworzyłem desktopy oraz mobilki. Około siedem lat temu zająłem się wyłącznie webówką (z niewielkimi przerwami na projekty mobilne) – najpierw w bardzo starych jej technologiach, takich jak Microsoft Web Forms, Razor, czy “czysty” JavaScript, a nawet raz przez przypadek zrobiłem single-page’a przy użyciu jQuery – co prawda był to single-page “na glinianych nogach”, ale działał!
Nieco później zacząłem korzystać z Angulara JavaScriptu oraz Angulara 2, w którym zrobiłem ze trzy projekty, a dopiero od czterech lat używam głównie Reacta i Angulara oraz zdarzyło mi się robić jeden projekt we Vue.js.

Które z tych trzech narzędzi najbardziej przypadło ci do gustu?
Szczerze mówiąc, nie mam zdania. Często jest tak, że jak ktoś lubi Reacta to nie lubi Angulara, bo nieco się od siebie różnią, ale mi pasują oba te rozwiązania. Vue.js nie używałem na tyle dużo, aby się o nim wypowiedzieć, natomiast jego koncept biblioteczny jest bardzo zbliżony do tego, który posiada React, więc Vue.js jest dla mnie dobrą alternatywą.

Z tego co ja słyszałem, to nie do końca jest tak, że osoby, które używają jednej technologii, nie lubią drugiej, lecz raczej chodzi tutaj o tę trudność, która pojawia się w momencie przenoszenia się z Reacta do Angulara – za to w drugą stronę ponoć jest już łatwiej.
Tak – trzeba o tym pamiętać gdy mamy do czynienia z biblioteką, natomiast z pozostałymi konceptami, z których budujemy własny framework, wygląda to nieco inaczej. Wtedy nie są nam z góry narzucone struktury folderów czy konwencja nazewnictwa – o wszystkim decydujemy sami i wówczas zdarza się, że osoby zaczynają obawiać się tego progu wejścia do Angulara – dla przykładu, Angular 2 był domyślnie połączony z TypeScriptem, co miało ułatwić zadanie programistom, którzy posługiwali się językiem C# lub Java. Natomiast, jeśli ktoś zaczął przygodę z programowaniem od JavaScriptu, który jest językiem dynamicznym, i nagle spotkał się innymi elementami składniami języków obiektowych, to wtedy taka osoba może się nieco pogubić.

To teraz chciałbym z tobą porozmawiać trochę więcej na temat single-page application. Ale zanim przejdę do pytań to opowiem ci krótką historię. Wcześniej nie zajmowałem się webówką, ale teraz już tak, więc ten temat jest dla mnie jasny, natomiast gdy dopiero zaczynałem to akurat mój kolega z pracy tworzył jakiś projekt w Reakcie, który mnie zainteresował. Zacząłem szukać w interencie informacji o tym języku i natrafiłem na jakiś artykuł, w którym było napisane, że React tworzy single-page applications, takie jak Facebook. Wtedy właśnie zacząłem się zastanawiać: jak te dwie rzeczy się do siebie mają? To znaczy, z jednej strony single-page application, a z drugiej – wszedłem na stronę i zauważyłem, że przecież mogę wszędzie klikać i przenosi mnie to do innych stron. O co w tym chodzi?
Faktycznie, to określenie jest mylące. Trzeba pamiętać o tym, że cały “ekosystem” JavaScriptu lubi hype. 😉 Czyli twórcy tych bibliotek, frameworków oraz innych buzz-wordów lubią, gdy ludzie dociekają, co się kryje za tymi pojęciami i dlaczego je wprowadzono. Wydaje mi się, że sama definicja “single-page’a” jest bardzo nieprecyzyjna. Po pierwsze, wiele osób myli architekturę – gdyż single-page application to architektura – z konkretnymi bibliotekami bądź frameworkami, więc należy te rzeczy rozróżnić. Po drugie, single-page’a można budować przy użyciu czystego JavaScriptu, nie potrzeba do tego żadnej biblioteki.

Wspomniałeś właśnie, że kiedyś udało ci się tego dokonać. 😉
Tak, udało mi się przez przypadek stworzyć taką architekturę, bo chciałem osiągnąć lepszy user experience – tak też powstawały kolejne biblioteki czy frameworki – ludzie zauważyli, że piszą coraz więcej logiki po stronie klienta, bądź chcą stworzyć przejścia pomiędzy stronami bez potrzeby wywołania żądania na serwerze (również po stronie klienta), więc zaczęli szukać rozwiązań dla tego typu działań. Single-page natomiast z jednej strony posiada podstrony, a z drugiej jest wyłącznie jedną aplikacją, która jest ładowana użytkownikowi, gdy ten za pierwszym wejściem załaduje stronę – pojawia się wtedy aplikacja z jej wszystkimi podstronami, stylami oraz logiką. Jest jednak pewien wyjątek – w trakcie działania całej aplikacji istnieje możliwość dynamicznego doładowania podmodułów, tzn. w celu optymalizacji wydziela się zakładki na stronie do osobnego modułu, a gdy użytkownik wejdzie w jedną z takich zakładek, my (programiści) doładujemy mu tę część aplikacji. To jest jednak bardzo rzadkie działanie, które jest możliwe tylko wtedy, gdy single-page application znacznie się rozrasta.

Po co używa się single-page’y? Jakie są korzyści? Czy wcześniejsze podejścia nie były wystarczająco dobre?
Nie, wcześniejsze podejścia były jak najbardziej poprawne i sporo firm do nich wraca, jednak dzięki single-page osiąga się lepszy user experience. Można go osiągnąć na różne sposoby – na przykład, gdy w aplikacji chcę wyświetlić tabelkę składającą się z dwustu rekordów, które znajdują się w bazie danych, i jednocześnie posiadam serwer, który ma za zadanie te dane przedstawić, to wtedy w przypadku server-side renderingu musielibyśmy te dane, wraz z całym HTML-em, wyrenderować po stronie serwera, i żeby zwrócić ją do użytkownika, cała strona musiałaby zostać przeładowana. Dobrze wtedy byłoby zrobić miejsce na optymalizację, żeby uniknąć przeładowania całej strony, lecz zazwyczaj jednak to przeładowanie następuje. Użytkownik widzi wtedy, że ta strona się przeładowuje. Jednakże, gdy buduję tę tabelę używając single-page’a, mam już dostępny jej szkielet oraz logikę, która po przyjęciu kodu, automatycznie wypełni tę tabelę wymaganymi danymi. Dzieje się to jednak po stronie klienta.

Czytałem niedawno o tym co oferuje SPA i natrafiłem na komentarze, że single-page pozwala przyspieszyć stronę. Z początku brzmi to nieco dziwnie, ale kiedyś przeczytałem na Reddicie komentarz o tym, jak do jednego z programistów, który zajmował się webówką, przyszedł klient i pożalił się, że bardzo wolno ładuje mu się strona. Programista sprawdza, przyznaje rację, ale tłumaczy, że wysyła request i czeka pół minuty na odpowiedź, więc problem musi leżeć po stronie klienta. Klient odpowiada, że na pewno nie i ponownie prosi programistę o przyspieszenie działania strony. Biedny programista siedzi i zastanawia się co zrobić, po czym stwierdził, że napisze loader. Działa to tak, że po wejściu na stronę pojawia się informacja o 5%, następnie co sekundę ładuje się kolejne 5%, po 10 sekundach zmienia się na wolniejsze ładowanie, a na 95% się zatrzymuje i czeka na pełen payload od strony Back Endu, żeby następnie już w pełni się naładować. Klient przychodzi i stwierdza – fantastyczne rozwiązanie, bardzo nam się podoba i o takie przyspieszenie chodziło! 😉
Faktycznie w wielu przypadkach może to pomóc, jednak to o czym przed chwilą opowiedziałeś to zamaskowanie niewydajności aplikacji, które też jest często potrzebne. 😉 Natomiast w tym skrajnym przypadku, gdy wspomniałeś o 30 sekundach, trzeba już spojrzeć nieco szerzej. Warto pamiętać, że cała komunikacja z serwerem jest asynchroniczna – wezmę za przykład wypełnienie formy przez użytkownika, w której zaznaczył on wymagane inputy i zatwierdził wybory. Obsługa tego żądania na serwerze trwa pół minuty i dany użytkownik dopiero po upływie tego czasu dostanie powiadomienie o zakończeniu operacji, lecz wciąż podczas tych 30 sekund może poruszać się w aplikacji, zmieniać zakładki, itp. W przypadku skrajnej niewydajności Back Endu obsługa asynchroniczna może więc okazać się dobrym rozwiązaniem. Jest to całkiem proste gdy mamy do czynienia z operacjami, które modyfikują dane, ale trudniejsze, gdy mamy ten zbiór danych już dużo większy – wtedy dobrze jest pomóc sobie poprzez stworzenie predefiniowanych widoków po stronie Back Endu.

To rozwiązanie asynchroniczne jest całkiem mądre i sprytne, ale ładujący się pasek też był ciekawym podejściem. 😉
No i zdecydowanie szybszym do zbudowania. 😉 W dodatku trzeba pamiętać, że asynchroniczne procesowanie znacznie podnosi koszty produkcji.

To teraz mam do ciebie takie prywatne pytanie. Jakbyś miał teraz stawiać swoją aplikację, to z którego podejścia wolałbyś skorzystać? SPA czy może jednak multi-page?
To zależy od tego, co bym budował. Jeśli user experience w aplikacji nie musiałby być bardzo wysoki, to pewnie zdecydowałbym się na server-side rendering. Mam sporo doświadczenia z różnymi bibliotekami, więc nie ma tu miejsca na czysto egoistyczny wybór – dziś wiele osób wybrałoby single-page’a, ponieważ jest to modne i każdy chce w tym coś zbudować, ale nie zawsze jest taka potrzeba, bo jednak wykorzystując server-side rendering zbudujemy aplikację szybciej (ale niekoniecznie lepiej). Więc jeśli miałbym zbudować na przykład wewnętrzną aplikację, to pewnie optowałbym za server-side renderingiem – oczywiście abstrahując od takich pytań jak “czy zespół go zna?” bądź “czy za pięć lat miałby kto tę aplikację wspierać?”.

W takim razie jakie są wady z podejścia single-page application? Z tego co rozumiem, jedną z takich wad będzie fakt, że taka aplikacja będzie się tworzyć wolniej. Czy jest coś jeszcze?
Według mnie, minusem jest cały ekosystem JavaScriptu, w tym wszystkie biblioteki oraz zależności między nimi. Warto wiedzieć, że korzystając z czystego Reacta w dzisiejszych czasach, używamy również dużej liczby innych bibliotek, na których on się opiera. Już od samego początku tworzenia aplikacji spotykamy w niej wiele zależności, z którymi sam w przeszłości miałem problemy. Tak więc liczba bibliotek jest zdecydowanie większa chociażby od ekosystemu w języku .NET; wiele osób tworzy swoje biblioteki, dlatego jest ich tak dużo, a bibliotek do PDF-a mogą być nawet dziesiątki. Kiedyś zrobiłem głębszy research i wyczytałem, że 99% bibliotek opiera się na tym samym.

Czyli każdy pisze “obudówkę” do tego, co już jest w podstawie?
Tak, taką swoją obudówkę, osobną dla Reacta czy Angulara. Tak więc istnieje tutaj wiele zależności między twórcami, które mogą okazać się problematyczne. Drugim minusem właśnie jest brak standaryzacji ekosystemu JavaScriptu. Niektórzy to lubią, inni mniej – ja należę do tej drugiej grupy, ponieważ zaczynałem z C#, w którym obowiązywały sztywne zasady, których każdy wtedy przestrzegał. W przypadku Front Endu można również wprowadzić jakieś zasady (np. poprzez konfigurację lintera), natomiast nie ma tam standardów dotyczących całego ekosystemu. JavaScript sam w sobie często sprawia problemy i jest językiem nietypowym. Ja mam takie podejście, że nie skupiam się w JavaScripcie na elementach typowych tylko dla tego języka, czyli staram się pisać kod “uniwersalny” – z użyciem składni, która występuje w większości języków, a nie jest typowa tylko dla JavaScriptu. Polecam obejrzeć sobie jakieś filmiki, które w nieco prześmiewczy sposób ukazują operatory, np. JavaScriptu.

Skoro omówiliśmy już minusy SPA, to czy teraz mógłbyś opowiedzieć o minusach multi-page’a?
Głównym minusem jest fakt, że prawie wszystko dzieje się po stronie serwera. Większych minusów tego rozwiązania nie znajdę, jednak przez większość czasu tak właśnie budowało się te strony. Multi-page’a łatwo jest zepsuć głównie przez słabszą wydajność oraz user experience nigdy nie będzie tak wysokie, jak w przypadku single-page’a, ale mimo tych minusów to rozwiązanie jest jak najbardziej w porządku.

Czy mógłbyś podzielić się z nami swoim najtrudniejszym wyzwaniem podczas tworzenia single page applications?
Jasne. Od strony technicznej największym wyzwaniem było dla mnie tworzenie bardzo rozbudowanej ankiety mającej pareset pól, które między sobą posiadały jakieś zależności – w zależności od tego jak odpowiedz na pytanie nr 5, otrzymujesz inne opcje odpowiedzi na pytanie nr 8. Z drugiej strony, jeśli źle odpowiesz na pytanie nr 30, jesteś postrzegany jako potencjalny terrorysta. Czyli był to bardzo rozbudowany formularz z zawiłymi zasadami, nad którym pracowało kilka osób. 

I co było w tym najtrudniejsze? Wymyślenie algorytmu czy współpraca z kolegami? 😉
Algorytm wymyślał biznes, więc my się nie musieliśmy nim przejmować, ale musieliśmy go zaimplementować. Wiele zależności między polami i bardzo duży ruch asynchroniczny przyczyniły się do trudności z wydajnością – ciężko to było tak zaprojektować, żeby to działało po stronie klienta i było wydajne. Obciążenie było ogromne i ciężko było go uniknąć. Początkowo została użyta biblioteka do zarządzania stanem NgRx – bo był to projekt w Angularze – ale niestety nie wydalała. Próbowaliśmy innych bibliotek – z takim samym skutkiem. Finalnie skończyło się na tym, że napisaliśmy własną maszynę stanów. Jako że była to aplikacja wewnętrzna dla pracowników instytucji, to nie mieli oni bardzo wydajnych maszyn, takich jak mają programiści, ale doszliśmy do etapu, na którym ci pracownicy byli w stanie tej maszyny używać – i to już był ogromny sukces. 😉 To była główna aplikacja tej instytucji, przez którą codziennie przechodziło kilka tysięcy wniosków, więc zrozumienie było naprawdę kluczowe dla tej firmy. Warto dodać, że wszystko zrobiliśmy wedle książki – to znaczy, ta biblioteka do zarządzania stanem była dobrze użyta, tylko po prostu nie wydalała, ale później się nam udało.

Mógłbyś nam opowiedzieć o wyzwaniach dla organizacji, która chciałaby wprowadzić rozwiązanie SPA?
Tych wyzwań jest dużo – sam w zeszłym roku uczestniczyłem w czymś takim, gdy praktycznie stawiałem firmę od zera. Na początku trzeba podjąć dużo decyzji. Ja pomimo sporego doświadczenia z single-page’ami i z różnymi bibliotekami oraz frameworkami miałem sporą trudność w podjęciu wielu z tych decyzji. W przypadku organizacji od razu niestety trzeba zdecydować się na jakieś narzędzie – czy to będzie React, czy Angular, czy Vue.js, czy Svelte, które też zyskuje ostatnio popularność – lub może jeszcze jakaś inna biblioteka, która powstała wczoraj i jeszcze o niej nie słyszałem. Także trzeba znaleźć najpierw takiego “kompana”, a następnie zastanowić się nad budową swojego własnego frameworka do tworzenia single-page’y, czyli: jak chcemy pisać testy, jak chcemy je odpalać, czy chcemy używać jakiejś dodatkowej nakładki na JavaScripcie (typu TypeScript, Flow), jak chcemy pisać style – dzisiaj trendem jest pisanie ich w JavaScripcie – czy użyć biblioteki do zarządzania stanem (czy może nie jest nam potrzebna?), jak ogarnąć temat lokalizacji, czyli tłumaczenia naszej aplikacji na różne języki. Tak więc jest dużo wyzwań początkowych, gdzie łatwo jest podjąć złe decyzje. 

Miałeś kiedyś tak, że podjąłeś jakąś decyzję, a potem musiałeś się męczyć z projektem przez kolejny rok i żałowałeś zakupu każdego dnia, gdy przychodziłeś do pracy, powtarzając “kurde, czemu to wybraliśmy”?
Od dłuższego czasu pracuję z architektami, czy to enterprise, czy też na poziomie aplikacji, no i… tam zawsze padają złe decyzje. 😉 To znaczy, z perspektywy czasu możemy pstwierdzić, że wtedy podjęlibyśmy lepszą decyzję. Ja jeszcze nie miałem takiej mega wpadki, żebym podjął jakąś decyzję, od której potem trudno było uciec albo żeby miała ona jakiś duży wpływ na produkt lub firmę, ale jeszcze wiele przede mną, więc na pewno mniejsze bądź większe błędy się zdarzą.

Załóżmy, że jestem studentem i kończę studia albo po prostu chciałbym się przebranżowić. Stworzyłem jedną czy dwie aplikacje w webówce i mówię sobie “podoba mi się to i chciałbym z tym pracować!”. Co byś mi doradził? Czego powinienem się nauczyć i od czego zacząć, żeby znaleźć pracę, albo żeby w ogóle dobrze się czuć w tej technologii?
Zacząłbym od czystego JavaScriptu, czyli bez żadnych Reactów, Angularów, i tak dalej. Nie wpisywałbym pytania “Jak zostać Front End Developerem?” w przeglądarkę, bo tam każda odpowiedź to będzie “Naucz się Reacta, Vue.js, czy czegoś tam…”. 😀 Zacząłbym od trzech filarów: 

  • dobre podstawy JavaScriptu (oraz zagłębienie się w internalsy JavaScriptu, bo są tam ciekawe zawiłości);
  • HTML 5, co jest dosyć proste, bo jeżeli ktoś jest osobą techniczną, to szybko zrobi coś, co będzie działało i będzie widoczne;
  • style CSS – ale może niekoniecznie na początku – na miejscu takiej osoby najpierw tworzyłbym aplikacje, która coś robi, np. jakąś gierkę lub kalkulator, a dopiero potem radziłbym nauczyć się podstaw stylów CSS.

Grunt to nauczyć się programować, a nie dekorować, bo wydaje mi się, że to jest jednak istotniejsze. Później dobrze jest zacząć robić projekty i błędy w tych projektach. Może po jakimś czasie zaświeci się lampka, że warto pisać testy, by uniknąć części z tych błędów.

Po co testować, skoro domyślasz się, że powinno działać?
Ja dopiero niedawno zacząłem doceniać testy – nie można od razu ich doceniać, tak samo jak Solida czy wzorców projektowych, bo to tak nie działa – do niektórych rzeczy trzeba dojść samemu, popełnić błędy, trochę się może za nie powstydzić, a później poszukać rozwiązań, żeby się nie powtórzyły. Jak już dobrniemy do takiego momentu, że jesteśmy w stanie zbudować działającą aplikację, to wtedy warto poszukać jakichś narzędzi – bo tego nie unikniemy. Mam na myśli jakieś biblioteki, można zacząć od Reacta czy Vue.js. Takiej zupełnie nowej osobie nie sugerowałbym zaczynać od Angulara, bo ma najwyższy próg wejścia. Czyli wybrać sobie bibliotekę, poznać jej ekosystem, bo często występują biblioteki typowe dla Reacta lub dla Vue.js. Nie iść ślepo w Reduxa – wiele osób mówi, że Reacta powinno się używać z Reduxem i że warto dowiedzieć się, czym jest state management – nie, na początku nie jest to potrzebne. Jak dojdziesz do momentu, gdy stan twojej aplikacji się rozrasta i masz problem z jego zarządzaniem – wtedy zastanów się nad biblioteką do zarządzania stanem. Rób wszystko krok po kroku i staraj się szukać rozwiązań dla problemów pojawiających się na bieżąco, nie próbuj na siłę ich szukać. O, to było takie bardzo życiowe.

Kuba, bardzo ci dziękuję za to, że nas odwiedziłeś i podzieliłeś się z nami swoją wiedzą oraz doświadczeniem. Było nam bardzo miło cię gościć.

Dziękuję również, było miło. 

🚀 Więcej o naszym gościu dowiesz się tutaj: https://devisionpodcast.pl/goscie-podcastu/

Posłuchaj całej rozmowy: