Merender rute dengan reaksi-snap

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

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

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

Perbandingan pemuatan berdampingan. Versi yang menggunakan pra-rendering dimuat 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 selesai didownload sebelum dapat melihat konten yang 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 mengorbankan Time to First Byte yang lebih lambat.

Pra-rendering adalah teknik terpisah yang tidak terlalu rumit dibandingkan rendering server, tetapi juga menyediakan cara untuk memperbaiki waktu First Paint dalam aplikasi Anda. Browser headless, atau browser tanpa antarmuka pengguna, digunakan untuk menghasilkan file HTML statis dari setiap rute selama waktu build. Kemudian, file tersebut dapat dikirimkan bersama dengan paket JavaScript yang diperlukan untuk aplikasi.

reaksi-snap

react-snap menggunakan Puppeteer untuk membuat file HTML yang telah dipra-render dari berbagai rute dalam aplikasi Anda. Untuk memulai, instal sebagai dependensi pengembangan:

npm install --save-dev react-snap

Lalu 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 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 langsung ke DOM, cara ini akan memeriksa apakah ada node turunan yang sudah ada untuk menentukan apakah konten HTML telah dirender sebelumnya (atau dirender pada server). Jika demikian, ReactDOM.hydrate akan digunakan untuk melampirkan pemroses peristiwa ke HTML yang sudah dibuat, bukan membuatnya baru.

Sekarang, build aplikasi 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 di dalam Chrome DevTools.

A sebelum dan sesudah perbandingan. After shot menunjukkan konten yang telah dirender.

Flash konten tanpa gaya

Meskipun HTML statis kini dirender dengan segera, HTML tersebut tetap tidak ditata gayanya secara default yang dapat menyebabkan masalah menampilkan "flash konten tanpa gaya" (FOUC). Hal ini dapat terlihat terutama jika Anda menggunakan library CSS-in-JS untuk menghasilkan pemilih karena paket JavaScript harus selesai dieksekusi sebelum gaya apa pun dapat diterapkan.

Untuk membantu mencegah hal ini, CSS yang penting, atau jumlah minimum CSS yang diperlukan untuk merender halaman awal, dapat langsung disisipkan ke <head> pada dokumen HTML. react-snap menggunakan library pihak ketiga lainnya, minimalcss, untuk mengekstrak CSS penting apa pun untuk berbagai rute. Anda dapat mengaktifkannya dengan menentukan hal berikut dalam file package.json:

"reactSnap": {
  "inlineCss": true
}

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

A sebelum dan sesudah perbandingan. Gambar sesudah menampilkan konten yang telah dirender dan ditata karena CSS penting yang disisipkan.

Kesimpulan

Jika Anda bukan rute rendering sisi server di aplikasi Anda, gunakan react-snap untuk merender HTML statis terlebih dahulu kepada pengguna.

  1. Instal paket ini sebagai dependensi pengembangan dan mulailah dengan setelan default.
  2. Gunakan opsi inlineCss eksperimental untuk menyejajarkan CSS penting jika berfungsi untuk situs Anda.
  3. Jika Anda menggunakan pemisahan kode pada level komponen dalam rute apa pun, berhati-hatilah agar tidak merender status pemuatan terlebih dahulu kepada pengguna. README react-snap membahas hal ini secara lebih mendetail.