Merender rute dengan reaksi-snap

Bukan rendering sisi server, tetapi masih ingin mempercepat performa situs React? Coba pra-rendering!

react-snap adalah library pihak ketiga yang melakukan pra-render halaman di situs Anda menjadi file HTML statis. Hal ini dapat meningkatkan waktu First Paint dalam aplikasi Anda.

Berikut ini perbandingan aplikasi yang sama dengan dan tanpa pra-rendering yang dimuat pada simulasi koneksi 3G dan perangkat seluler:

Perbandingan pemuatan yang berdampingan. Versi yang menggunakan pra-rendering memuat 4,2 detik lebih cepat.

Mengapa hal ini bermanfaat?

Masalah performa utama pada aplikasi web satu halaman yang besar adalah pengguna harus menunggu paket JavaScript yang membentuk situs tersebut selesai didownload sebelum dapat melihat konten sebenarnya. Semakin besar paket, semakin lama pengguna harus menunggu.

Untuk mengatasi hal ini, banyak developer menggunakan pendekatan rendering aplikasi di server, bukan hanya mem-bootingnya di browser. Dengan setiap transisi halaman/rute, HTML lengkap akan dihasilkan di server dan dikirim ke browser, sehingga mengurangi waktu First Paint, tetapi menyebabkan Time to First Byte lebih lambat.

Pra-rendering adalah teknik terpisah yang tidak begitu kompleks dibandingkan rendering server, tetapi juga menyediakan cara untuk meningkatkan waktu First Paint pada aplikasi Anda. Browser headless, atau browser tanpa antarmuka pengguna, digunakan untuk membuat file HTML statis dari setiap rute selama waktu build. File ini kemudian dapat dikirim bersama dengan paket JavaScript yang diperlukan untuk aplikasi.

beri reaksi

react-snap menggunakan Puppeteer untuk membuat file HTML yang telah dirender sebelumnya untuk berbagai rute di aplikasi Anda. Untuk memulai, instal paket sebagai dependensi pengembangan:

npm install --save-dev react-snap

Kemudian, tambahkan skrip postbuild di package.json Anda:

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

Hal ini akan otomatis menjalankan perintah react-snap setiap kali build baru aplikasi dibuat (npm build).

Hal terakhir yang perlu Anda lakukan adalah mengubah cara aplikasi di-booting. Ubah file src/index.js menjadi seperti berikut:

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);
}

Alih-alih hanya menggunakan ReactDOM.render untuk merender elemen React root secara langsung ke DOM, pemeriksaan ini memeriksa apakah ada node turunan yang sudah ada untuk menentukan apakah konten HTML telah dipra-render (atau dirender di server). Jika demikian, ReactDOM.hydrate akan digunakan untuk melampirkan pemroses peristiwa ke HTML yang sudah dibuat, bukan membuatnya baru.

Membangun aplikasi kini akan menghasilkan file HTML statis sebagai payload untuk setiap rute yang di-crawl. Anda dapat melihat tampilan payload HTML dengan mengklik URL permintaan HTML, lalu mengklik tab Previews dalam Chrome DevTools.

Perbandingan sebelum dan sesudah. Foto setelahnya menunjukkan konten telah dirender.

Flash konten tanpa gaya

Meskipun kini HTML statis langsung dirender, HTML tersebut masih tidak diberi gaya secara default, yang dapat menyebabkan masalah tampilan "flash konten tanpa gaya" (FOUC). Hal ini dapat terlihat terutama jika Anda menggunakan library CSS-in-JS untuk menghasilkan pemilih karena paket JavaScript harus menyelesaikan eksekusi sebelum gaya apa pun dapat diterapkan.

Untuk membantu mencegah hal ini, CSS penting, atau jumlah minimum CSS yang diperlukan halaman awal untuk dirender, dapat menjadi inline langsung ke <head> dokumen HTML. react-snap menggunakan library pihak ketiga lainnya di balik layar, minimalcss, untuk mengekstrak setiap CSS penting untuk rute yang berbeda. Anda dapat mengaktifkannya dengan menentukan hal berikut dalam file package.json:

"reactSnap": {
  "inlineCss": true
}

Melihat pratinjau respons di Chrome DevTools kini akan menampilkan halaman yang ditata gayanya dengan CSS penting inline.

Perbandingan sebelum dan sesudah. Setelah foto menunjukkan konten telah dirender dan ditata gayanya karena CSS kritis inline.

Kesimpulan

Jika Anda bukan rute rendering sisi server dalam aplikasi Anda, gunakan react-snap untuk melakukan pra-render HTML statis kepada pengguna Anda.

  1. Instal paket sebagai dependensi pengembangan dan mulailah dengan setelan default saja.
  2. Gunakan opsi inlineCss eksperimental untuk membuat CSS penting menjadi inline jika berfungsi untuk situs Anda.
  3. Jika Anda menggunakan pemisahan kode pada level komponen dalam rute apa pun, berhati-hatilah agar jangan melakukan pra-render status pemuatan kepada pengguna Anda. README react-snap membahas ini secara lebih detail.