Các tuyến đường kết xuất trước có React-snap

Bạn không hiển thị phía máy chủ nhưng vẫn muốn tăng hiệu suất cho trang web React của mình? Thử kết xuất trước!

react-snap là một thư viện bên thứ ba. Tính năng này kết xuất trước các trang trên trang web của bạn thành tệp HTML tĩnh. Điều này có thể cải thiện thời gian Thời gian hiển thị đầu tiên trong ứng dụng của bạn.

Dưới đây là so sánh cùng một ứng dụng khi có và không được kết xuất trước được tải trên kết nối 3G mô phỏng và thiết bị di động:

So sánh song song khi tải. Phiên bản sử dụng tính năng kết xuất trước tải nhanh hơn 4,2 giây.

Tại sao điều này hữu ích?

Vấn đề chính về hiệu suất đối với các ứng dụng trang đơn lớn là người dùng cần phải đợi(các) gói JavaScript tạo nên trang web này hoàn tất quá trình tải xuống trước khi có thể xem bất kỳ nội dung thực nào. Gói càng lớn thì người dùng sẽ càng phải đợi lâu hơn.

Để giải quyết vấn đề này, nhiều nhà phát triển đã áp dụng phương pháp kết xuất ứng dụng trên máy chủ thay vì chỉ khởi động ứng dụng trên trình duyệt. Với mỗi lần chuyển đổi trang/tuyến, HTML hoàn chỉnh sẽ được tạo trên máy chủ và gửi tới trình duyệt, giúp giảm thời gian hiển thị đầu tiên nhưng đổi lại chi phí thời gian cho byte đầu tiên chậm hơn.

Kết xuất trước là một kỹ thuật riêng ít phức tạp hơn so với kết xuất trên máy chủ, nhưng cũng cung cấp một cách để cải thiện thời gian Hiển thị trước trong ứng dụng của bạn. Trình duyệt không có giao diện người dùng hoặc trình duyệt không có giao diện người dùng được dùng để tạo các tệp HTML tĩnh cho mọi tuyến trong thời gian xây dựng. Sau đó, các tệp này có thể được chuyển cùng với các gói JavaScript cần thiết cho ứng dụng.

chụp nhanh phản ứng

react-snap sử dụng Puppeteer để tạo tệp HTML kết xuất trước gồm nhiều tuyến trong ứng dụng của bạn. Để bắt đầu, hãy cài đặt dưới dạng phần phụ thuộc cho hoạt động phát triển:

npm install --save-dev react-snap

Sau đó, hãy thêm tập lệnh postbuild vào package.json của bạn:

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

Thao tác này sẽ tự động chạy lệnh react-snap mỗi khi có một bản dựng mới của ứng dụng đã tạo (npm build).

Việc cuối cùng bạn cần làm là thay đổi cách khởi động ứng dụng. Thay đổi tệp src/index.js thành như sau:

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

Thay vì chỉ sử dụng ReactDOM.render để kết xuất phần tử React gốc trực tiếp vào DOM, phương thức này sẽ kiểm tra xem liệu đã có nút con nào hay chưa để xác định xem nội dung HTML đã được kết xuất trước (hoặc hiển thị trên máy chủ) hay chưa. Trong trường hợp đó, ReactDOM.hydrate sẽ được sử dụng để đính kèm trình nghe sự kiện vào HTML đã tạo thay vì tạo lại.

Giờ đây, việc tạo ứng dụng sẽ tạo các tệp HTML tĩnh dưới dạng tải trọng cho từng tuyến được thu thập dữ liệu. Bạn có thể xem tải trọng HTML trông như thế nào bằng cách nhấp vào URL của yêu cầu HTML rồi nhấp vào thẻ Xem trước trong Công cụ của Chrome cho nhà phát triển.

So sánh trước và sau. Ảnh sau khi chụp cho thấy nội dung đã kết xuất.

Flash của nội dung chưa được định kiểu

Mặc dù HTML tĩnh hiện hiển thị gần như ngay lập tức, nhưng theo mặc định, HTML tĩnh vẫn chưa được định kiểu, điều này có thể gây ra vấn đề hiển thị "flash của nội dung chưa định kiểu" (FOUC). Điều này có thể đặc biệt đáng chú ý nếu bạn đang sử dụng thư viện CSS trong JS để tạo các bộ chọn vì gói JavaScript sẽ phải hoàn tất quá trình thực thi trước khi có thể áp dụng bất kỳ kiểu nào.

Để ngăn chặn điều này, CSS quan trọng hoặc số lượng CSS tối thiểu cần thiết để trang đầu tiên hiển thị, có thể được đặt trực tiếp vào <head> của tài liệu HTML. react-snap sử dụng một thư viện bên thứ ba khác, minimalcss, để trích xuất mọi CSS quan trọng cho các tuyến khác. Bạn có thể bật tính năng này bằng cách chỉ định thông tin sau trong tệp package.json:

"reactSnap": {
  "inlineCss": true
}

Xem bản xem trước phản hồi trong Công cụ của Chrome cho nhà phát triển giờ đây sẽ hiển thị trang đã được tạo kiểu có CSS quan trọng cùng dòng.

So sánh trước và sau. Ảnh chụp sau cho thấy nội dung đã kết xuất và được tạo kiểu nhờ CSS quan trọng cùng dòng.

Kết luận

Nếu bạn không phải là tuyến hiển thị phía máy chủ trong ứng dụng của mình, hãy sử dụng react-snap để kết xuất trước HTML tĩnh cho người dùng.

  1. Hãy cài đặt phiên bản này dưới dạng phần phụ thuộc phát triển và chỉ bắt đầu với các chế độ cài đặt mặc định.
  2. Sử dụng tuỳ chọn inlineCss thử nghiệm để chèn CSS quan trọng vào cùng dòng nếu tuỳ chọn này phù hợp với trang web của bạn.
  3. Nếu bạn đang sử dụng tính năng phân tách mã ở cấp thành phần trong bất kỳ tuyến nào, hãy cẩn thận không kết xuất trước trạng thái tải cho người dùng. react-snap README sẽ trình bày chi tiết hơn về vấn đề này.