Merender rute dengan reaksi-snap

Tidak menggunakan 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. Hal ini dapat meningkatkan waktu First Paint di aplikasi Anda.

Berikut adalah perbandingan aplikasi yang sama dengan dan tanpa pra-rendering yang dimuat di koneksi 3G simulasi 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 sebenarnya. Makin besar paket, makin lama pengguna harus menunggu.

Untuk mengatasi hal ini, banyak developer menggunakan pendekatan untuk merender aplikasi di server, bukan hanya mem-booting-nya di browser. Dengan setiap transisi halaman/rute, HTML lengkap akan dibuat di server dan dikirim ke browser, yang mengurangi waktu First Paint, tetapi dengan mengorbankan Time to First Byte yang lebih lambat.

Pra-rendering adalah teknik terpisah yang kurang kompleks daripada rendering server, tetapi juga memberikan cara untuk meningkatkan waktu First Paint di 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.

react-snap

react-snap menggunakan Puppeteer untuk membuat file HTML pra-rendering dari berbagai rute di aplikasi Anda. Untuk memulai, instal sebagai dependensi pengembangan:

npm install --save-dev react-snap

Kemudian, tambahkan skrip postbuild di package.json Anda:

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

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

Mem-build 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 Pratinjau dalam Chrome DevTools.

Perbandingan sebelum dan sesudah. Rekaman setelahnya menunjukkan bahwa konten telah dirender.

Flash konten tanpa gaya

Meskipun HTML statis sekarang hampir langsung dirender, HTML tersebut masih tidak memiliki gaya secara default yang dapat menyebabkan masalah tampilan "flash of unstyled content" (FOUC). Hal ini dapat sangat terlihat jika Anda menggunakan library CSS-in-JS untuk membuat pemilih karena paket JavaScript harus selesai dijalankan sebelum gaya apa pun dapat diterapkan.

Untuk membantu mencegah hal ini, CSS penting, atau jumlah minimum CSS yang diperlukan agar halaman awal dirender, dapat disisipkan langsung ke <head> dokumen HTML. react-snap menggunakan library pihak ketiga lain di bawah, minimalcss, untuk mengekstrak 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 bergaya dengan CSS penting yang disisipkan.

Perbandingan sebelum dan sesudah. Tampilan setelah pengambilan menunjukkan konten telah dirender dan diberi gaya karena CSS penting yang disisipkan.

Kesimpulan

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

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