kontakt
Software house
>
Casestudies
>
Produkt Boring Owl (Headless CMS + TypeScript + React.js + Next.js) - komentarz techniczny

Produkt Boring Owl (Headless CMS + TypeScript + React.js + Next.js) - komentarz techniczny

Data wpisu
Mateusz Kuba
Autor
Mateusz Kuba
boring owl software house case study

Tworząc produkt zoptymalizowanej witryny pod SEO, wykorzystaliśmy nasze doświadczenie w tworzeniu aplikacji frontendowych. Ważne dla nas było by witryna od strony technicznej była składowana w repozytorium Github oraz miała oddzielny moduł do zarządzania treścią.

Założenie było takie, aby tworzenie projektu nie absorbowało nas od strony devopsowej. Nie zależało nam na tym by utrzymywać w chmurze AWS serwery EC2 i postawić na nich CMS, czy też by postawić statycznie stronę na AWS.

Dlaczego wybraliśmy NextJS oraz Netlify ?

Wiedzieliśmy, że istnieją rozwiązania rynkowe oparte o CDN AWS, a także o usługę AWS S3, które zapewniają dodatkowe funkcjonalności takie jak optymalizacja zdjęć realtime czy pluginy do obsługi formularzy i wbudowane narzędzia do automatyzacji. Wahaliśmy się pomiędzy wyborem usługi SSR, a statycznym hostingiem. Statyczny hosting zawsze minimalnie będzie szybszy od SSR ze względu na od razu prerendowaną treść HTML, a przy naszej liczbie 100 artykułów, które nawet jeżeli wzrosną do liczby 1000 nie rodzi problemów wydajnościowych podczas budowania strony. Zostawiliśmy jednak furtkę do zmiany hostingu na przyszłość i zdecydowaliśmy się na framework NextJS, który posiada funkcjonalność exportu do strony statycznej, a tkaże typowy SSR.

Jako hosting wybraliśmy Netlify, ze względu na prosty deployment, podgląd branchy typu pull request, a także zarządzanie deploymentem poprzez plik netlify.toml. Umożliwia on ustawienie haseł na branchach podglądowych, ustawienie routowania stron z błędem 400, czy też uruchomienie testów przed wypuszczeniem strony na produkcję. Dzięki branchom podglądowym wykonujemy manualne testy e2e, dzięki pluginom netlify monitorujemy, czy jakaś zmiana drastycznie nie wpływa na performance googlowego page insight.

Bardzo ważnym elementem naszej higieny wypuszczania nowych wersji stały się testy automatyczne e2e wykonywane na cypress. Dzięki netlify pozbyliśmy się narzędzi takich jak circleci czy też github actions. Całość wykonywana jako krok prebuild w momencie wypuszczenia nowej wersji na Github. Uzyskujemy pewność, że każda podstrona działa poprawnie, strona nie powoduje błędów w przeglądarce, a także że wymagania SEO zostały utrzymane.

Podstawowe założenia

Tworząc obecne rozwiązanie skupiliśmy się na implementacji nowoczesnego rozwiązania, które nie dodałoby zbyt dużej ilości dodatkowych kb do strony, a w zamian za to, dało nowoczesne funkcjonalności takie jak:

  • minifikacja JS oraz HTML
  • optymalizacja zdjęć zanim zostaną wrzucone na CDN
  • lazy loading dowolnego elementu na stronie i opóźnienie jego ładowania
  • prefetch pozostałych podstron zanim zostaną otwarte ( intersection observer dla podstron, które są ładowane w postaci treści JSON, a dogrywane są tylko niektóre chunki .js - powoduje to błyskawiczne ładowanie się podstron www )
  • pełna kontrola nad treścią w <head>
  • pełna kontrola nad JS
  • bezpieczeństwo w dokonywaniu zmian - testowanie obecności nagłówków SEO podczas fazy CI/CD w celu uniknięcia błędów podczas developmentu
  • strona w pełni statyczna, bez elementów zapytań wykonywanych do zewnętrznych API, a przy tym posiadająca funkcjonalności JS
  • możliwość stworzenia dynamicznej animacji wykorzystując nowoczesne biblioteki do animacji napisane w ReactJS
  • wykorzystanie automatyzacji formularzy przez zewnętrznego dostawcę

Optymalizacja nagłówków SEO

Każda strona posiada odpowiednią strukturę nagłówków SEO. Sprawdzamy poprzez testy pisane w Jest obecność nagłówków H1 oraz H2 na stronach, a także inne szczególne znaczniki SEO. Dzięki temu nie ma możliwości by zmieniając kluczowe treści na stronie został wprowadzony błąd. Dodatkowo, skrypty ładowane w HEAD wykorzystują znacznik <Script /> od NextJS która daje możliwość ustawiania różnych strategii ładowania skryptów zewnętrznych.

Automatyzacja

Ważnych czynnikiem podczas budowy naszej strony było wykorzystanie narzędzi do automatyzacji, dlatego formularze nie są obsługiwane przez nasz backend lecz przez Netlify, podobnie jak Newsletter jest obsługiwany przez MailChimp. Dodatkowo formularze mają podpięte zdarzenia, takie jak automatyczna wysyłka powiadomień na slack, hubspot czy autoresponder na zgłoszenia.

Wykorzystanie TypeScript oraz NextJS

Wykorzystując Typescript uzyskaliśmy statyczne typowanie dla kodu pisanego dla naszej strony. Jest to szczególnie ważne tam, gdzie pobiera się i renderuje skomplikowane struktury danych, a taką jest treść i nagłówki oraz parametry SEO pozyskiwane poprzez zapytania API do Headless CMS. Unikamy błędów literówek, niepoprawnie załadowanych tytułów do znacznika head i wielu innych błędów. Dostajemy podpowiadanie w większości IDE co znacznie przyspiesza i usprawnia proces ładowania się treści.

Typescript Code



Tworząc aplikacje z NextJS uzyskuje się szereg bardzo ciekawych funkcjonalności. Jedną z nich jest Link, który pobiera inne podstrony zanim zostaną otwarte. Będąc rozwiązaniem SSR, pobiera treści z bloga i renderuje je w formacie znajomym botom google. My poszliśmy o krok do przodu i wykorzystaliśmy Next export do wersji statycznej. Obecnie nie posiadamy żadnych zapytań do naszego Headless CMS wykonywanego przez użytkowników. Całość jest serwowana przez CDN, co dodatkowo ogranicza koszta, ale też poprawia user experience.


NextJS Chunking

NextJS wykorzystuje chunkowie plików JS, które jest dość popularną metodą optymalizacji wielkości pobieranych plików JS. Dzięki temu najważniejsze skrypty i te, które uruchamiane są na każdej podstronie lądują do main-.js app-.js oraz framework-.js, a pozostałe są podzielone na inne pliki. Dzięki temu strona potrafi załadować się i być interaktywna bardzo szybko.

JS Chunk NextJS

Kodowanie makiet

Cały proces tworzenia strony był oparty o makiety. Nasze makiety były tworzone w Figma. Istnieją dwa podejścia do kodowania makiet.

1. Pixel Perfect

2. Nie Pixel Perfect

Zależało nam na tym by projekt strony nie przeciągnął się w wielomiesięczną batalię o pixele, dlatego wybraliśmy rozwiązanie Nie Pixel Perfect, które ma swoje minusy, ale przy dobrze przygotowanej makiecie pozwala na znacznie szybsza iterację.

Oba podejścia różnią się pomiędzy sobą czasem kodowania i dokładnością. Inspirowaliśmy się konceptami z Material Design dotyczącymi odległości pomiędzy elementami. I tak większość odległości na naszej stronie jest mnożnikiem liczby 4. Dodatkowo dodaliśmy Dark/Light mode.

Z podobnej inspiracji mnożników liczby 4 czerpie TailWind, dając tez DarkMode w postaci klasy css. Mając poprzednie doświadczenie w Tailwind wybór był oczywisty.

Dlaczego posiadając dobrą makietę koduje się szybko i dobrze wykorzystując Nie Pixel Perfect ?

Patrząc na makietę developer wystarczy, że podzieli widoczną liczbę pixeli przez 16 i uzyska odpowiednią klasę w Tailwind. To wszystko, potem wystarczy stworzyć komponenty które by utrzymywały w środku sekcje, poszczególne moduły i korzystając z nich uzyskujemy w całym projekcie takie same odległości. Wizualnie wygląda to bardzo dobrze. Co więcej później jeżeli programista chciałby jeszcze szybciej prototypować, zapamiętując jakie były wcześniej odległości wykorzystywane może patrząc tylko na makietę bez dokładnych pomiarów "zgadywać" klasy. Mogą się one finalnie różnić od tych na makiecie, ale nadal zachowują symetrię wynikającą z liczby 4. Kluczowe elementy typografii posiadają swoje klasy, to samo dotyczy stylistyki projektu.

Developer właściwie nic nie musi kopiować z makiety, a jedynie zapamiętuje klasy. Samo tworzenie klas z wykorzystaniem Tailwind jest szybkie i przyjemne przy wykorzystaniu @Apply

tailwind apply

Animacje

W aplikacji wykorzystaliśmy integrację z ReactSpring do tworzenia animacji. Było to nasze pierwsze podejście do tej biblioteki oferującej płynne animacje oparte w pełni na Javascripcie. Nie wykorzystujemy praktycznie w ogóle CSS KeyFrames które w swojej naturze jest linearne i mocno nienaturalne. Animacja zachodzącego słońca czy pojawiających się obiektów wydaje się przyjemna dla oka i mam nadzieję, że podobać się będzie użytkownikom.

Bot na deser

Tworząc witrynę pozwoliliśmy naszych programistom również na zaproponowanie i wdrożenie elementów, które oni uważaliby za ważne i atrakcyjne dla użytkownika. Wdrożyliśmy bota naszej własnej produkcji wykorzystującego API google, a także usługę DialogFlow. Nauczyliśmy bota odpowiadać na pytania z FAQ, a także parę innych. Docelowo chcemy by bot w kolejnej wersji był w stanie zamówić darmową konsultację w kalendarzu, a także prezentował więcej treści graficznych. Pojawiły się już pierwsze pytania do Bota na której nie znał odpowiedzi i pozwoliło, nam to lepiej zrozumieć naszego potencjalnego klienta i dorzucić do niego odpowiedzi.

Bot DialogFlow Google

Podsumowanie

Projekt zmiany witryny będący częścią rebrandingu okazał się doskonałym sposobem na wypuszczenie dopracowanego produktu zoptymalizowanej witryny pod SEO szerszej widowni. Obecny stack nadaje się również do pisania zoptymalizowanego frontendu pod witryny headless ecommerce, a także inne aplikacje frontendowej wymagającego zaawansowanej logiki. Struktura aplikacji jest przygotowana pod znacznie większą ilość kodu zorganizowana w przejrzyste moduły i serwisy z wydzieloną przestrzenią na typowanie i css. Wskaźniki SEO w google page speed index bez skryptów śledzących uzyskały wyniki zbliżone do 100.
Tworząc plik package.json staraliśmy się nie dorzucać dodatkowych zależności, maksymalnie uszczuplić aplikację i wykorzystywane narzędzia by nie mieć problemów z aktualizacjami. Produkt ten jest dobrym przykładem tego co można zrobić za pomocą nowoczesnego stacku frontendowego.

Inne Case Study