Trasy renderowania z wyprzedzeniem z przyspieszeniem reakcji

Nie korzystasz z renderowania po stronie serwera, ale i tak chcesz przyspieszyć działanie witryny opartej na React? Wypróbuj renderowanie wstępne.

react-snap to zewnętrzna biblioteka, która wstępnie renderuje strony w Twojej witrynie do statycznych plików HTML. Może to poprawić czasy pierwszego wyrenderowania w aplikacji.

Oto porównanie tej samej aplikacji z wykorzystaniem prerenderowania i bez niego na urządzeniu mobilnym z symulowanym połączeniem 3G:

Porównanie wczytywania. Wersja z wstępnym renderowaniem wczytuje się o 4,2 sekundy szybciej.

Dlaczego to jest przydatne?

Głównym problemem z wydajnością w przypadku dużych aplikacji jednostronicowych jest to, że użytkownik musi poczekać na zakończenie pobierania pakietów JavaScriptu, które tworzą witrynę, zanim będzie mógł zobaczyć rzeczywiste treści. Im większe pakiety, tym dłużej użytkownik będzie musiał czekać.

Aby rozwiązać ten problem, wielu deweloperów stosuje renderowanie aplikacji na serwerze zamiast uruchamiania jej tylko w przeglądarce. Przy każdym przejściu na inną stronę lub trasę na serwerze generowany jest pełny kod HTML, który jest wysyłany do przeglądarki. Dzięki temu czas do pierwszego wyświetlenia jest krótszy, ale czas do pierwszego bajta jest dłuższy.

Przedrenderowanie to osobna technika, która jest mniej złożona niż renderowanie na serwerze, ale również pozwala poprawić czasy pierwszego wyrenderowania w aplikacji. Podczas generowania przeglądarka bez interfejsu graficznego (czyli bez interfejsu użytkownika) służy do generowania statycznych plików HTML dla każdej trasy. Te pliki można następnie przesłać wraz z pakietami JavaScript potrzebnymi do działania aplikacji.

react-snap

react-snap używa Puppeteer do tworzenia wyrenderowanych wstępnie plików HTML różnych tras w aplikacji. Aby rozpocząć, zainstaluj go jako zależność programistyczną:

npm install --save-dev react-snap

Następnie dodaj skrypt postbuild do package.json:

"scripts": {
  //...
  "postbuild": "react-snap"
}

Polecenie react-snap będzie się automatycznie wykonywać za każdym razem, gdy utworzysz nową wersję aplikacji (npm build).

Ostatnią rzeczą, którą musisz zrobić, jest zmiana sposobu uruchamiania aplikacji. Zmień plik src/index.js na taki:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");

if (rootElement.hasChildNodes()) {
  ReactDOM.hydrate(<App />, rootElement);
} else {
  ReactDOM.render(<App />, rootElement);
}

Zamiast używać tylko funkcji ReactDOM.render do renderowania elementu głównego React bezpośrednio w DOM, sprawdza, czy istnieją już jakieś węzły podrzędne, aby określić, czy zawartość HTML została wstępnie wyrenderowana (lub wyrenderowana na serwerze). W takim przypadku zamiast tworzenia nowego pliku HTML używasz tagu ReactDOM.hydrate, aby dołączyć do niego listenery zdarzeń.

Kompilacja aplikacji będzie teraz generować statyczne pliki HTML jako ładunki dla każdej skanowanej trasy. Aby sprawdzić, jak wygląda ładunek HTML, kliknij adres URL żądania HTML, a potem kliknij kartę Podglądy w Narzędziach deweloperskich w Chrome.

Porównanie stanu przed i po. Zdjęcie po pokazuje renderowane treści.

Flash z niesformatowanymi treściami

Chociaż statyczne strony HTML są teraz renderowane niemal natychmiast, nadal są domyślnie niesformatowane, co może powodować wyświetlanie „błysku niesformatowanego zawartości” (FOUC). Może to być szczególnie widoczne, jeśli do generowania selektorów używasz biblioteki CSS-in-JS, ponieważ pakiet JavaScript musi się najpierw wykonać, zanim będzie można zastosować style.

Aby temu zapobiec, kluczowe reguły CSS lub minimalna liczba reguł CSS, które są potrzebne do renderowania początkowej strony, mogą zostać wstawione bezpośrednio do <head> dokumentu HTML. react-snap używa innej biblioteki zewnętrznej (minimalcss), aby wyodrębnić dowolny kluczowy plik CSS dla różnych tras. Aby to zrobić, w pliku package.json podaj:

"reactSnap": {
  "inlineCss": true
}

Gdy teraz wyświetlisz podgląd odpowiedzi w Narzędziach deweloperskich w Chrome, zobaczysz stronę ze stylami i wstawionym kodem CSS.

Porównanie stanu przed i po. Zdjęcie po pokazuje, że renderowanie i stylizacja treści zostały wykonane dzięki wstawionemu kluczowemu plikowi CSS.

Podsumowanie

Jeśli w swojej aplikacji nie korzystasz z renderowania po stronie serwera, użyj opcji react-snap, aby wstępnie wyrenderować statyczny kod HTML dla użytkowników.

  1. Zainstaluj go jako zależność programistyczną i zacznij od ustawień domyślnych.
  2. Użyj eksperymentalnej opcji inlineCss, aby wbudować w stronę krytyczny kod CSS, jeśli jest to możliwe w przypadku Twojej witryny.
  3. Jeśli używasz podziału kodu na poziomie komponentów w ramach dowolnych tras, uważaj, aby nie renderować wstępnie stanu wczytywania dla użytkowników. Więcej informacji znajdziesz w react-snap PLIKU README.