使用因應回應預先算繪路徑

這不是伺服器端轉譯,但仍想加快 React 網站的效能嗎?歡迎試用預先算繪功能!

react-snap」是第三方 這個程式庫能預先將網站上的網頁轉譯成靜態 HTML 檔案這可以 改善 畫面首次顯示所需時間 才出現次數

以下比較相同的應用程式啟用及未預先算繪的情況 是在模擬 3G 連線和行動裝置上載入:

並排載入的比較項目。使用預先算繪的版本載入時間加快 4.2 秒。

這種報表有哪些優點?

大型單頁應用程式的主要效能問題是 使用者需要等待組成網站的 JavaScript 套件完成 才會看到實際內容套裝組合的數量越大 使用者等待的時間。

為解決這個問題,許多開發人員採取的做法 更新伺服器,而不是只在瀏覽器中啟動。在 網頁/路徑轉換時,完整的 HTML 會在伺服器上產生,並傳送至 縮短首次繪製時間,但成本也比較慢 時間到了第一位元組。

預先轉譯是另一種技術,比伺服器複雜。 也能縮短您載入模型檔案時第一個繪製時間的 應用程式。使用無頭瀏覽器或沒有使用者介面的瀏覽器 在建構時間期間產生每個路徑的靜態 HTML 檔案。這些檔案 之後,您就能與 應用程式。

回應小睡

react-snap 使用 Puppeteer 執行以下操作: 在應用程式中建立不同路徑的預先轉譯 HTML 檔案。目的地: 請先將其安裝為開發依附元件:

npm install --save-dev react-snap

然後在 package.json 中新增 postbuild 指令碼:

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

這樣每當有新的建構版本時,系統就會自動執行 react-snap 指令 (npm build)。

最後,您需要變更應用程式的啟動方式。 將 src/index.js 檔案變更為以下內容:

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

不要僅使用 ReactDOM.render 轉譯根 React 元素 這個函式會檢查是否已有任何子節點 判斷 HTML 內容是否已預先轉譯 (或是在 伺服器)。在這種情況下,系統會改用 ReactDOM.hydrate 來附加事件 接聽程式,而不是建立新的 HTML。

建構應用程式之後,系統會產生 靜態 HTML 檔案做為酬載 的每個路徑您可以查看 HTML 酬載 例如點選 HTML 要求的網址,然後按一下「預覽」 開啟 Chrome 開發人員工具

前後對照比較。後圖顯示內容完成轉譯。

閃爍未加上樣式的內容

靜態 HTML 現在會幾乎立即轉譯, 預設為不設定樣式,可能會導致出現「未設定樣式的閃爍」問題 內容」(FOUC)。如果使用 CSS-in-JS 產生選擇器,因為 JavaScript 套件必須完成 才會套用任何樣式

為避免發生這個問題,「重要」CSS 供應商或 CSS 供應商 初始化所需的初始頁面,可以直接內嵌於 <head> 中 其他部分「react-snap」是根據 ,minimalcss 則可擷取任何 因此主要的 CSS 值不同您可以藉由指定 在您的 package.json 檔案中:

"reactSnap": {
  "inlineCss": true
}

現在看看 Chrome 開發人員工具的回應預覽畫面,結果預覽會顯示內含重要 CSS 的樣式化頁面。

前後對照比較。下方圖中顯示的內容已經過內嵌,且因內嵌重要的 CSS 而調整樣式。

結論

如果您不是應用程式中的伺服器端算繪路徑,請使用 react-snap 可向使用者預先轉譯靜態 HTML。

  1. 將其安裝為開發依附元件,並僅以預設值開始 可以管理叢集設定,像是節點 資源調度、安全性和其他預先設定項目
  2. 使用實驗性的 inlineCss 選項,內嵌重要的 CSS (如果適用) 賺取收益
  3. 如果您使用程式碼分割功能,將程式碼分割至任何路徑中的元件層級,則 請小心不要向使用者預先轉譯載入狀態。 react-snap 讀我資訊 其他課程則會詳細說明