Wpadki i wypadki #19

Oto i kolejny odcinek Wpadek i wypadków! Dzisiaj pokrótce przyjrzymy się obsłudze niedziałającego JS-a.

Na wielu stronach znaleźć można następujący kod:

<noscript>You need to enable JavaScript to run this app.</noscript>

Został on spopularyzowany przez takie rozwiązania, jak Create React App (CRA). I choć co prawda jest ono już obecnie uważane za przestarzałe i zachęca się osoby pracujące z Reactem do używania zamiast niego np. Nexta, to wciąż jest to popularne narzędzie, mające ponad 132 tysiące pobrań tygodniowo. Niemniej jego wiek widać między innymi w powyższej linijce kodu. Są z nią dwa zasadnicze problemy:

  1. Jeśli ktoś wyłączył JS w przeglądarce, to jedyne, co dostanie, to komunikat, że musi go włączyć. A w zdecydowanej większości przypadków takie osoby wyłączyły go w pełni świadomie z konkretnych powodów. Zamiast go włączyć, po prostu poszukają strony, która pokaże im coś więcej, niż mało przyjazny komunikat błędu.
  2. Osoby, którym JS nie zadziała z innego powodu, nie dostaną nawet tego komunikatu. Wystarczy, że będą przeglądać stronę na telefonie w pociągu i pociąg właśnie wjedzie do tunelu. Niestabilne połączenie to też niestabilny JS.

W idealnym świecie wszystkie strony działałyby bez JS-a. Ale w takowym nie żyjemy. Możemy natomiast zaoferować osobom bez JS-a (i to niezależnie od przyczyny tego braku) doświadczenie bardziej przyjazne niż chłodny komunikat „Włącz se JS”.

I tutaj na ratunek przychodzi podejście Progressive Enhancement (Stopniowe Ulepszanie). Jego podstawowym założeniem jest: zapewnijmy podstawowe doświadczenie przy pomocy najprostszej możliwej technologii, a potem to ulepszajmy. W przypadku wielu (zaryzykowałbym nawet, że zdecydowanej większości) stron podstawowym doświadczeniem jest dostanie się do jakiejś treści. Przykładowo: ten blog jest wręcz książkowym przykładem strony, na którą się wchodzi, żeby coś przeczytać. Jedynym faktycznie interaktywnym elementem tego doświadczenia jest możliwość zostawienia komentarza. Jaka jest najprostsza technologia, dzięki której możemy to zaoferować? HTML. Dzięki niemu jesteśmy w stanie pokazać treść osobie odwiedzającej oraz obsłużyć dodanie przez nią komentarza przy pomocy formularzy. I z tego miejsca możemy myśleć o udogodnieniach, takich jak ciekawy, przyciągający oczy design czy podkręcenie interaktywności (np. komentarze, które uaktualniają się w czasie rzeczywistym). CRA również jest często wykorzystywane do tworzenia stron nastawionych na konsumpcję treści (jak choćby portfolio webdeveloperskie) – więc stron, które nadają się idealnie do zastosowania Stopniowego Ulepszania. I nowsze rozwiązania przeznaczone do tworzenia aplikacji w Reakcie to umożliwiają. Weźmy taki pakiet Create Next App, tworzący aplikację w Nexcie. Nie generuje on już strony, która zawiera jedynie komunikat błędu. Zamiast tego generuje stronę z całą treścią i używa techniki hydracji, żeby strona mogła korzystać z możliwości Reacta. Początkowa treść generowana jest po stronie serwera. To rozwiązuje obydwa wspomniane wyżej problemy z wykorzystaniem noscript. Dodatkowo poprawia wydajność. Bez generowania po stronie serwera przeglądarka musi najpierw ściągnąć kod JS, a dopiero potem może zacząć cokolwiek generować. Jeśli treść już przychodzi z serwera, wystarczy ją wyświetlić. Ba, takie podejście można rozwinąć nawet bardziej i tworzyć strony, które są niemal w całości statyczne, a mają jedynie wyspy interaktywności. Tak po prawdzie mało stron bezwzględnie potrzebuje JS-a do działania i renderowania treści. Większość z nich mogłoby z powodzeniem generować sporą część treści na serwerze, a po stronie przeglądarki jedynie dokładać interaktywność tam, gdzie to konieczne.

I zanim powiesz, że „Ale moja strona to naprawdę potrzebuje JS-a” – jeśli sklep Amazona nie potrzebuje, to jest duża szansa, że Twoja strona również. Tworzysz bloga? Jak już wspominałem – sam HTML wystarczy do dostarczenia całego doświadczenia osobie czytającej. Portfolio? Linki do podglądu projektów na żywo to wciąż sam HTML, tak samo jak Twój biogram. Lista to-do? Rzekłbym nawet, że można by zaplusować, pokazując taką z obsługą formularza po stronie serwera. Google Docs? No ok, tutaj… A nie, w sumie też można.

Nie będę jednak za wszelką cenę udowadniał, że nie istnieją aplikacje, które bez JS-a nie mają po prostu sensu albo zrobienie ich bez niego jest nieopłacalne. I takich przykładów na pewno trochę by się znalazło. Zatem co z nimi? Na pewno warto przygotować przyjaźniejszy komunikat. Oprócz informacji, że wymagany jest JS, wypada też dodać, jak go włączyć. Albo zasugerować odświeżenie strony – wbrew pozorom to rozwiązuje bardzo dużo problemów. Wypada też odejść od noscript na rzecz rozwiązania, które pozwoli wykryć także inne przypadki niedziałania JS-a. Tutaj można posłużyć się np. klasą .no-js. Nakłada się ją na element html, a następnie usuwa, gdy JS się wczyta. Dzięki temu obsłużymy zarówno przypadek wyłączenia JS-a, jak i sytuację, w której JS się wyglebił. Warto też rozważyć bardziej „lokalne” podejście. Jeśli na naszej stronie tylko konkretne regiony potrzebują JS, być może warto problemy z nim obsługiwać bezpośrednio w tych regionach. Tutaj na pomoc mogą przyjść HTML Web Components – komponenty, które ulepszają HTML, zamiast próbować go zastąpić. Przykładem może być komponent do zamieszczania zewnętrznej treści na moim blogu:

<embed- src="https://codepen.io/Comandeer/pen/qBGzJQm"
  ><p class="embed-fallback">
    <a href="https://codepen.io/Comandeer/pen/qBGzJQm" rel="noreferrer noopener"
      >Przejdź bezpośrednio do osadzonej treści na CodePenie.</a
    >
  </p></embed->

Jeśli wszystko zadziała, powyższy komponent podmieni samego siebie na ramkę z wybranym przykładem z CodePena. Jeśli jednak JS z jakiegoś powodu nie zadziała, wówczas osoba czytająca bloga będzie mogła skorzystać z linka bezpośrednio do przykładu:

Komponent do osadzania treści w sytuacji, gdy JS nie zadziałał, wyświetla komunikat: Przejdź bezpośrednio do osadzonej treści na CodePenie.

Jasne, nie jest to dokładnie takie samo doświadczenie, jak dla osoby, której JS zadziałał. Ale jak dla mnie jest to zdecydowanie lepsze podejście, niż zostawienie takiej osoby bez niczego.

Zatem następnym razem, zanim skorzystasz z noscript, pomyśl, czy nie jesteś w stanie niskim kosztem polepszyć doświadczenia osób, którym JS nie działa – i to niezależnie z jakiego powodu. Wbrew pozorom bardzo często można zrobić naprawdę dużo. A przy okazji poprawić dostępność aplikacji dla wszystkich. Bo JS może nie działać każdemu.

3 komentarze do “Wpadki i wypadki #19”

  1. Jeżeli dobrze rozumiem, to jednym z powodów (lub jedną z zalet) aplikacji rysowanych client-side jest brak konieczności posiadania backendu rysującego UI. Aplikacja pełniąca funkcje backendowe może być na zupełnie oddzielnych serwerach, zarządzana zupełnie oddzielnie; zaś aplikacja pełniąca rule frontendowe może być hostowana nawet ze statycznego hostingu plików, bez żadnych możliwości backendowych. W takim wypadku prerenderowanie treści server-side jest niemożliwe, a jej wymuszenie skutkuje utratą jednej z zalet utrzymaniowych SPA.

    Większości ludzi takie przypadki brzegowe jak opisane w artykule nie obchodzą. Obchodzi za to, żeby było łatwo i przyjemnie, a w szczególności tanio. Coś mi się nie wydaje, żeby używanie starego rozwiązania było samo w sobie pomyłką, może być celowe. Po co poznawać nowe i komplikować sobie, skoro stare działa.

    1. Lata temu Nicholas Zakas ukuł pojęcie tzw. new frontend (później przyjęła się bardziej nazwa middleend). Więc tak naprawdę client-side rendering jest rozwiązaniem nowszym.

      Aczkolwiek najnowsze rozwiązania, np. architektura wyspowa, bardzo fajnie działa właśnie z w pełni statycznymi backendami. Cała strona może być prerenderowana jako HTML, a jedynie wyspy byłyby dynamicznie uaktualniane.

  2. Trochę nie na temat, bo w sprawie samego create-react-app.
    Aplikacje SPA nadal mają swoje zastosowania, a teraz dokumentacja Reacta udaje, że takie nie istnieją. Do SPA zostają „third-party” rozwiązania, czyli kolejne rzeczy które trzeba konfigurować i liczyć że nie zostaną „legacy”. CRA przynajmniej wydała Meta.
    Przyczynami są vendor lock na produkty Vercela oraz „hype train” na frontendzie. W Reactowym ekosystemie opieka nad kilkuletnimi projektami jest ciężka.

    https://www.reddit.com/r/reactjs/comments/11u1r3w/new_react_docs_pretend_spas_dont_exist_anymore/

Dodaj komentarz

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

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.