Trasy renderowania z wyprzedzeniem z przyspieszeniem reakcji

Nie używasz renderowania po stronie serwera, ale mimo to chcesz zwiększyć wydajność swojej strony React? Wypróbuj renderowanie wstępne

react-snap to biblioteka innej firmy, która wstępnie renderuje strony w Twojej witrynie na statyczne pliki HTML. Może to poprawić czas pierwszego renderowania w aplikacji.

Oto porównanie tej samej aplikacji z renderowaniem wstępnym załadowanym i bez renderowania załadowanego w symulowanym połączeniu 3G na urządzeniu mobilnym:

Porównanie wczytywania obok siebie. Wersja wykorzystująca renderowanie wstępne wczytuje się o 4,2 sekundy szybciej.

Dlaczego to jest przydatne?

Głównym problemem związanym z wydajnością w przypadku dużych aplikacji jednostronicowych jest to, że użytkownik musi czekać na zakończenie pobierania pakietów JavaScript, które składają się na stronę, zanim będą mogli zobaczyć prawdziwą treść. Im większe pakiety, tym dłużej użytkownik musi czekać.

Aby rozwiązać ten problem, wielu deweloperów renderuje aplikację na serwerze, a nie tylko uruchamia ją w przeglądarce. Przy każdym przejściu strony/trasy pełny kod HTML jest generowany na serwerze i wysyłany do przeglądarki, co skraca czas pierwszego wyrenderowania, ale wiąże się z dłuższym czasem do pierwszego bajtu.

Renderowanie wstępne to odrębna technika, która jest mniej złożona niż renderowanie przez serwer, ale pozwala też poprawić czas pierwszego wyrenderowania w aplikacji. Do generowania statycznych plików HTML każdej trasy w czasie kompilacji używana jest przeglądarka bez interfejsu graficznego lub przeglądarka bez interfejsu użytkownika. Następnie można je wysłać wraz z pakietami JavaScript potrzebnymi do działania aplikacji.

reakcja

react-snap używa Puppeteer do tworzenia wstępnie renderowanych plików HTML różnych tras w aplikacji. Najpierw zainstaluj ją jako zależność deweloperską:

npm install --save-dev react-snap

Następnie dodaj skrypt postbuild w narzędziu package.json:

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

Spowoduje to automatyczne uruchamianie polecenia react-snap za każdym razem, gdy utworzona zostanie nowa kompilacja aplikacji (npm build).

Ostatnia rzecz, jaką musisz zrobić, to zmienić sposób 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ć obiektu ReactDOM.render tylko do renderowania głównego elementu React bezpośrednio w modelu DOM, funkcja sprawdza, czy są już dostępne węzły podrzędne, i określa, czy treści HTML zostały wstępnie wyrenderowane (lub wyrenderowane na serwerze). W takim przypadku komponent ReactDOM.hydrate jest używany do dołączania odbiorników zdarzeń do już utworzonego kodu HTML, zamiast tworzyć go od nowa.

Kompilacja aplikacji spowoduje teraz wygenerowanie statycznych plików HTML jako ładunków dla każdej przemierzanej trasy. Jeśli chcesz zobaczyć, jak wygląda ładunek HTML, kliknij adres URL żądania HTML, a potem kartę Podgląd w Narzędziach deweloperskich w Chrome.

Porównanie „przed” i „po”. Po zakończeniu ujęcia widać, że treść została wyrenderowana.

Flash z niesformatowanymi treściami

Chociaż statyczny kod HTML jest teraz renderowany niemal natychmiast, w dalszym ciągu pozostaje domyślnie niestylizowany, co może powodować problemy z wyświetlaniem „błysku niesformatowanej treści” (FOUC). Może to być szczególnie zauważalne, jeśli do generowania selektorów używasz biblioteki CSS-in-JS, ponieważ przed zastosowaniem stylów pakiet JavaScript musi się zakończyć wykonywaniem.

Aby temu zapobiec, krytyczny kod CSS, czyli minimalna ilość kodu CSS potrzebna do wyrenderowania pierwszej strony, można umieścić bezpośrednio w kodzie <head> dokumentu HTML. react-snap używa działającej od wewnątrz innej biblioteki zewnętrznej – minimalcss, do wyodrębniania krytycznego kodu CSS dla różnych tras. Aby to zrobić, określ w pliku package.json te elementy:

"reactSnap": {
  "inlineCss": true
}

Podgląd odpowiedzi w Narzędziach deweloperskich w Chrome pokazuje teraz stylizowaną stronę z wbudowanymi najważniejszymi elementami CSS.

Porównanie „przed” i „po”. Ostatnie ujęcie pokazuje, że treść została wyrenderowana i ma określony styl z powodu wbudowanych krytycznych elementów CSS.

Podsumowanie

Jeśli w swojej aplikacji nie stosujesz tras renderowania po stronie serwera, użyj react-snap, aby wstępnie wyrenderować statyczny kod HTML użytkownikom.

  1. Zainstaluj je jako zależność deweloperską i zacznij od ustawień domyślnych.
  2. Użyj eksperymentalnej opcji inlineCss, aby wbudować krytyczny kod CSS, jeśli sprawdza się w Twojej witrynie.
  3. Jeśli dzielisz kod na poziomie komponentu w ramach dowolnych tras, uważaj, aby nie renderować z wyprzedzeniem stanu wczytywania użytkownikom. Więcej szczegółów znajdziesz w react-snap README tym artykule.