Merender rute dengan reaksi-snap

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

react-snap adalah pihak ketiga library yang melakukan pra-rendering halaman di situs Anda menjadi file HTML statis. Hal ini dapat memperbaiki Gambar Pertama dalam aplikasi Anda.

Berikut adalah perbandingan aplikasi yang sama dengan dan tanpa pra-rendering dimuat di 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 kinerja utama pada aplikasi web satu halaman berukuran besar adalah pengguna harus menunggu paket JavaScript yang membentuk situs selesai mengunduh sebelum mereka dapat melihat konten yang sebenarnya. Semakin besar paketnya, lebih lama lagi pengguna harus menunggu.

Untuk mengatasi hal ini, banyak pengembang mengambil pendekatan {i>rendering<i} aplikasi pada server alih-alih hanya melakukan {i> booting<i} di browser. Setiap kolom transisi halaman/rute, HTML lengkap dibuat di server dan dikirim ke browser, yang mengurangi waktu First Paint tetapi memakan biaya lebih lambat Time to First Byte.

Pra-rendering adalah teknik terpisah yang tidak terlalu kompleks dibandingkan server tetapi juga menyediakan cara untuk memperbaiki waktu Gambar Pertama dalam aplikasi. Browser headless, atau browser tanpa antarmuka pengguna, digunakan untuk menghasilkan file HTML statis setiap rute selama waktu build. File ini dapat dikirim bersama dengan paket JavaScript yang diperlukan untuk aplikasi.

beri reaksi

react-snap menggunakan Puppeteer untuk membuat file HTML pra-render dari rute yang berbeda di aplikasi Anda. Kepada menginstalnya sebagai dependensi pengembangan:

npm install --save-dev react-snap

Kemudian, tambahkan skrip postbuild di package.json Anda:

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

Perintah ini akan otomatis menjalankan perintah react-snap setiap kali build baru aplikasi yang 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);
}

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

Membangun aplikasi sekarang akan menghasilkan file HTML statis sebagai {i>payload<i} untuk setiap rute yang di-crawl. Anda dapat melihat tampilan {i>payload<i} HTML seperti dengan mengklik URL permintaan HTML, lalu mengklik Previews di dalam Chrome DevTools.

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

Flash konten tanpa gaya

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

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

"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 rute rendering sisi server bukan untuk aplikasi Anda, gunakan react-snap untuk merender HTML statis terlebih dahulu ke pengguna.

  1. Instal aplikasi sebagai dependensi pengembangan dan mulai dengan perintah default setelan.
  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, pastikan berhati-hatilah agar tidak melakukan pra-rendering status pemuatan kepada pengguna Anda. Tujuan react-snap README membahas hal ini secara lebih rinci.