Logo David Burdelak
Webdevelopment

Overengineering w stronach internetowych

Overengineering

Overengineering, czyli nadmierna inżynieria, to budowanie rozwiązania bardziej złożonego, niż wymaga problem. Kojarzy się z dużymi systemami, ale przy audytach stron firmowych i sklepów spotykam go równie często: kilkadziesiąt wtyczek do prostej wizytówki, framework aplikacyjny do pięciu podstron, trzy rodziny czcionek i kontener tagów, którego nikt nie rozumie. Taka strona zwykle dobrze wygląda w dniu oddania, ale jest wolna, droga w utrzymaniu i trudna do zmiany. W tym wpisie pokazuję, po czym rozpoznaję przesadę, gdzie najczęściej ją znajduję i według jakich pytań decyduję, czy kolejna warstwa jest potrzebna.

Jak rozpoznaję overengineering

Przesadnie złożony projekt rzadko wygląda źle na pierwszy rzut oka. Rozpoznaję go po objawach, które wychodzą dopiero w trakcie utrzymania:

  • prosta zmiana, np. nowa sekcja na stronie głównej, zajmuje dni zamiast godzin,
  • nikt w zespole nie potrafi wyjaśnić, po co jest dana wtyczka, biblioteka albo usługa,
  • aktualizacje są odkładane, bo każda grozi awarią w innym miejscu,
  • strona zbudowana „nowoczesnym stosem” ładuje się wolniej niż prosta strona konkurencji,
  • koszt hostingu, licencji i utrzymania rośnie szybciej niż korzyści z kolejnych funkcji.

Źródło tych objawów najczęściej znajduję w kilkunastu powtarzalnych miejscach. Tabela pokazuje je w skrócie, a w kolejnych sekcjach opisuję każde z nich dokładniej.

ObszarPrzesada, którą widzę najczęściejCo robię zamiast
JavaScriptkażdy element interfejsu oparty na skryptachHTML i CSS tam, gdzie wystarczą, skrypty tylko do realnej logiki
Frameworkipełna aplikacja JavaScript do kilku podstron z treściągotowy HTML z generatora stron albo zoptymalizowany CMS
CSSkilka bibliotek komponentów w jednym projekciezmienne CSS, Grid i Flexbox w małych projektach
Czcionkikilka rodzin we wszystkich grubościach z zewnętrznych serwerówjedna rodzina, kilka grubości, pliki na własnym serwerze
Animacjeanimowany każdy element i przejścia blokujące treśćkrótkie efekty, które pomagają zrozumieć interfejs
CMSpage builder i kilkanaście wtyczek do strony wizytówkiCMS tylko tam, gdzie treść edytują osoby nietechniczne
Wtyczkizdublowane funkcje i skrypty ładowane na każdej podstroniekilka aktualizowanych wtyczek, drobiazgi w motywie potomnym
Własny kodwłasny CMS albo builder do prostej stronygotowe narzędzia i własny kod tam, gdzie daje przewagę
Komponentyosobny komponent i plik stylów dla każdego akapitukomponenty dla elementów, które się powtarzają
CDNzasoby z kilku publicznych CDN na lokalnej stronieCDN przy ruchu z wielu krajów i dużych plikach
Treścisetki generowanych podstron różniących się nazwą miastaosobne podstrony tylko z unikalną treścią
Analitykaśledzenie każdego kliknięcia bez planu analizyzdarzenia odpowiadające na konkretne pytania biznesowe

Front-end, czyli więcej kodu, niż potrzebuje przeglądarka

JavaScript tam, gdzie wystarczy HTML i CSS

Rozwijane sekcje, zakładki czy proste menu da się dziś zbudować w HTML i CSS, np. elementem <details>, który działa bez jednej linii skryptu i jest dostępny dla czytników ekranu. Każdy dodatkowy skrypt to kod do pobrania, wykonania i utrzymania, a do tego potencjalna przyczyna wolnej reakcji na kliknięcie. Zanim dodam JavaScript, sprawdzam, czy przeglądarka nie robi tego sama.

Framework aplikacyjny do strony z treścią

Frameworki do budowy aplikacji, takie jak Next.js czy Nuxt, sprawdzają się przy panelach klienta, konfiguratorach i serwisach z dużą ilością interakcji. Gdy jednak cała strona to kilka podstron z treścią marketingową, a front-end wysyła do przeglądarki pełną aplikację JavaScript, użytkownik płaci za złożoność, której nie potrzebuje. Przy stronach z treścią wybieram rozwiązanie, które generuje gotowy HTML i dodaje JavaScript tylko tam, gdzie jest potrzebny, np. Astro albo dobrze zoptymalizowany WordPress. Wybór modelu renderowania zależy od tego, jak często zmienia się treść, co pokazuje porównanie metod renderowania CSR, SSR, SSG i ISR. Przy większych projektach rozważam też, kiedy warto przejść na headless CMS.

Frameworki CSS a własne style

Tailwind czy Bootstrap przyspieszają pracę, ale przy małej stronie potrafią dodać więcej kodu i zależności niż sama treść. Przesadą jest też łączenie kilku bibliotek komponentów w jednym projekcie, bo ich style zaczynają ze sobą konkurować. Przy niewielkich projektach wystarczają mi zmienne CSS, Grid i Flexbox. Framework wybieram, gdy nad projektem pracuje kilka osób i wspólny system klas oszczędza im czas.

Nadmiar czcionek

Każda czcionka i każda jej grubość to osobny plik do pobrania. Trzy rodziny czcionek po pięć grubości to kilkanaście plików, które opóźniają wyświetlenie tekstu, a przy podmianie czcionki zastępczej na docelową przesuwają układ strony. W większości projektów wystarcza mi jedna rodzina w dwóch lub trzech grubościach, a jeśli czcionka obsługuje warianty w jednym pliku, wybieram tę wersję. Pliki hostuję lokalnie, a resztę załatwia optymalizacja ładowania czcionek.

Animacje i efekty

Animacje nie są ozdobnikiem do usunięcia. Dobrze zaprojektowana animacja pokazuje, skąd pojawił się element, potwierdza kliknięcie i buduje charakter marki. Przesada zaczyna się, gdy efekty opóźniają dostęp do treści, np. pełnoekranowe przejścia przed wyświetleniem strony, gdy każdy element na stronie wjeżdża przy przewijaniu albo gdy animacje są liczone w JavaScripcie i na słabszym telefonie przycinają się przy przewijaniu. Animuję wtedy tylko właściwości, które przeglądarka obsługuje bez przeliczania układu, a pozostałe efekty usuwam. Od tego zależy płynne przewijanie i animacje w JavaScript.

CMS, wtyczki i własne rozwiązania

Za ciężki CMS do prostej strony

Landing page z trzema sekcjami i formularzem nie potrzebuje bazy danych, panelu administracyjnego i kilkunastu wtyczek. Jeśli treść zmienia się kilka razy w roku, a edytuje ją programista, statyczna strona jest szybsza, tańsza i bezpieczniejsza. CMS ma sens tam, gdzie treść regularnie edytują osoby nietechniczne. Dlatego zanim wybiorę CMS do projektu, pytam, kto i jak często będzie zmieniał treść.

Zbyt duża liczba wtyczek

Liczba wtyczek sama w sobie nie jest problemem. Problemem są wtyczki, które ładują swoje skrypty i style na każdej podstronie, dublują funkcje innych wtyczek albo nie są aktualizowane. Przy każdej stronie na WordPressie zadaję o każdą wtyczkę trzy pytania: czy jest używana, czy jej funkcji nie zapewnia już inna wtyczka lub motyw i czy da się ją zastąpić kilkoma liniami kodu. Wtyczka do zmiany koloru przycisku albo wstawienia jednego skryptu to typowy przykład czegoś, co lepiej przenieść do motywu potomnego. Do pozostałych stosuję te same kryteria co przy wyborze przydatnych wtyczek do WordPressa.

Własne rozwiązania a gotowe narzędzia

Własny kod daje pełną kontrolę, ale każda linia to koszt utrzymania. Gdy ktoś pisze własny system zarządzania treścią albo builder do strony z kilkoma podstronami i formularzem, pytam, jaki problem rozwiązuje, którego nie rozwiązują gotowe narzędzia. Jeśli odpowiedzią są ambicje techniczne, a nie potrzeby projektu, to klasyczny overengineering. Z drugiej strony przesadą jest też ciężki page builder do strony, którą da się zbudować z kilku prostych bloków. Granicę wyznacza dla mnie koszt utrzymania przez kolejne lata, a nie czas pierwszego wdrożenia.

Kod i infrastruktura

Przesadna modularność kodu

Podział na komponenty ułatwia rozwój i testowanie, ale komponent na każdy akapit, z osobnym plikiem stylów i testów, sprawia, że prosta zmiana wymaga otwarcia kilkunastu plików. Wydzielam komponent, gdy ten sam fragment powtarza się w kilku miejscach albo ma własną logikę. W pozostałych przypadkach prosty kod w jednym miejscu jest czytelniejszy. To jedna z zasad, dzięki którym kod pozostaje czytelny i zrozumiały.

CDN dla wszystkiego

CDN to dla mnie standard przy ruchu z wielu krajów, dużej liczbie zdjęć i wideo oraz przy potrzebie ochrony przed atakami. Przy lokalnej stronie firmowej z dobrze skonfigurowaną pamięcią podręczną na serwerze zysk bywa niewielki, a każda dodatkowa warstwa to kolejne miejsce, w którym trzeba szukać błędów przy problemach z cache czy przekierowaniami. Przesadą nazywam też ładowanie skryptów i czcionek z kilku różnych publicznych CDN, z których każdy wymaga osobnego połączenia. Gdy CDN faktycznie jest potrzebny, kluczowa jest jego konfiguracja, a nie samo włączenie.

SEO i analityka

Masowo generowane strony

AI przyspiesza pisanie kodu i treści, ale masowe generowanie podstron, np. setki stron „usługa plus miasto” różniących się nazwą miejscowości, to overengineering po stronie SEO. Taka struktura jest trudna w utrzymaniu, nie daje użytkownikowi niczego nowego i może zostać uznana przez Google za skalowane treści niskiej jakości. Osobną podstronę tworzę tylko wtedy, gdy mam dla niej unikalną treść, np. realizacje, opinie czy ofertę z danego miejsca.

Śledzenie każdego zdarzenia w GA4

Śledzenie przewinięcia co 10%, każdego kliknięcia i każdego pola formularza daje dużo danych, ale rzadko daje wnioski. Każde zdarzenie to też kolejny tag w kontenerze i kolejny kod wykonywany w przeglądarce. Zaczynam od listy pytań biznesowych, na które dane mają odpowiedzieć, i śledzę tylko zdarzenia potrzebne do odpowiedzi. Od strony kodu porządkuje to dobrze zaprojektowana warstwa danych w Google Tag Managerze.

Pytania, które zadaję przed dodaniem kolejnej warstwy

  1. Jaki konkretny problem rozwiązuje i czy ten problem już mamy, czy tylko możemy mieć w przyszłości?
  2. Czy przeglądarka, serwer albo obecne narzędzia nie robią już tego samego?
  3. Kto będzie to utrzymywał za dwa lata i czy zrozumie, po co to jest?
  4. Jak wpłynie na szybkość strony i czy zmierzę ten wpływ przed i po wdrożeniu?
  5. Ile kosztuje usunięcie tej warstwy, jeśli okaże się zbędna?

Jeśli na pierwsze pytanie nie ma konkretnej odpowiedzi, nie dodaję warstwy. Każda z nich zostaje w projekcie na lata, a jej koszt rośnie razem z długiem technologicznym. Dlatego przy każdej decyzji pytam nie o to, czy rozwiązanie jest nowoczesne, tylko czy jest potrzebne.