iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Modern Web

前進React 生態系 : 技術應用與概念解析系列 第 15

Day 15 - 掌握 Suspense:優化 React 的 SSR 體驗

  • 分享至 

  • xImage
  •  

React 16 Suspense 和 React Lazy

其實在 React 16 時就有 Suspense,需要搭配 lazy 使用。使用原因是為了優化效能,減少初始的 JavaScript bundle 大小。可以達到延遲載入的效果,只在需要的時候才載入元件。

import { lazy, Suspense } from "react";

const LazyComponent = lazy(() => import("./LazyComponent"));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

React 18 Suspense

React 18 的 Suspense 不僅解決了元件 Lazy Loading,還進一步用來處理資料載入和 Server-Side Rendering (SSR) 的優化。

在 React 18 之前的 Server-Side Rendering (SSR) 流程

  1. React Server 向 API 取得頁面需要的所有資料
  2. 得到所有資料後,React Server 渲染頁面的 HTML
  3. 渲染完後,React Server 將 HTML、CSS、JavaScript 傳回給 Client
  4. 瀏覽器先生成一個靜態頁面 (還沒有 JavaScript 交互功能)
  5. 載入 JavaScript
  6. 和之前的 HTML 做對照,使網頁產生互動效果,這個流程稱為 Hydration。透過注入水分讓網頁上的功能活起來,產生互動效果。

在 React 18 之前的 Server Side Render 問題

  • 資料延遲:需要等到所有資料都取得後才能將完整頁面傳回,這會導致資料較慢的情況下,使用者可能會看到一段空白頁面。
  • 渲染延遲:SSR 還需要完整載入 JavaScript 來進行頁面交互。
  • 互動延遲:即便頁面顯示出來,Hydration 之前的頁面還不能互動,使用者可能會點擊按鈕卻無反應,導致不良的使用體驗。

Suspense 是怎麼解決問題的?

React 18 中的 Suspense 透過 Streaming 和 Selective Hydration 技術來優化效能,讓頁面更快進行互動。這部份的 SSR 通常會使用框架來達成,像是 Next.js, Remix 等。

Streaming

允許將頁面的 HTML 分解為較小的塊,並逐步將這些塊發送到用戶端。以餐廳來舉例,傳統 SSR 的作法是等所有菜都準備好後才一起端上桌,而 Streaming 則允許某道菜準備好後就立刻上桌,讓客人可以更快吃到飯菜。

兩個差別會長這樣:

傳統的 SSR 中,必須等到所有資料和 HTML 都準備好,才能顯示畫面。

img

Streaming 的渲染流程,當部分內容準備好後,就可以先送回給瀏覽器進行渲染。

img

這樣的分段渲染可以減少 Client 的等待時間,從而提升效能和用戶體驗。

Selective Hydration

Selective Hydration 允許在 hydration 過程中,根據用戶的行為,優先處理使用者互動的區域。當使用者與某個元件互動時,React 會優先對這些元件進行 hydration,而不必等整個頁面完成。

例如,當用戶點擊一個尚未完成 hydration 的按鈕時,React 會中斷其他元件的 Hydration,會優先處理用戶點擊的區域,從而提供即時回饋。

Suspense 運作原理

在 React 18 中,Suspense 是基於 Promise 的概念運作。當 Suspense 等待一個 Promise 完成時,它會顯示一個 fallback UI,直到 Promise 被 resolve 或 reject。

另外 Suspense 能實現也是基於 React 18 的 Concurrent Rendering 和 Fiber 架構,詳細內容會在之後的文章分享。

參考資料和圖片來源:
https://react.dev/reference/react/Suspense
https://github.com/reactwg/react-18/discussions/37
https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
https://www.youtube.com/watch?v=pj5N-Khihgc&list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa&index=4


上一篇
Day 14 - 三種 React 資料請求策略:從 fetch-on-render 到 render-as-you-fetch
下一篇
Day 16 - 選擇合適的渲染策略:CSR、SSR 和其他渲染方法
系列文
前進React 生態系 : 技術應用與概念解析22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言