iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Modern Web

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

Day 22 - 掌握 React 19 Metadata 與資源載入優化

  • 分享至 

  • xImage
  •  

Document Metadata

Document Metadata (如 <title><link><meta>)會放在 HTML 的 <head> 區塊中,這部分的內容會對 SEO 和網站相關資訊的呈現很重要。

在 React 19 之前如果在 Component 內使用,會被放在 <body> 中,但通常我們會希望放在 <head> 中。通常會使用第三方 library 像是 react-helmet 或是透過框架的內建方法來解決這個問題。

在 React 19 之後,React 將自動確保與這些 Metadata 對應的 DOM 元素被正確地放置在 <head> 中。

使用範例:

function UserData({ user }) {
  return (
    <article>
      <h1>{user.name}</h1>
      <title>{user.name}'s Profile</title>
      <meta name="author" content={user.name} />
      <link rel="author" href={user.url} />
      <meta name="description" content="user description" />
      <p>{user.bio}</p>
    </article>
  );
}

Stylesheet 優化

在處理 Stylesheet 時,載入順序至關重要,因為後載入的樣式會覆蓋先載入的樣式規則。另外若初次渲染時若樣式未完全載入,會出現無樣式內容閃爍(FOUC, Flash of Unstyled Content),讓使用者體驗不好。

Stylesheet 搭配 Suspense

在 React 19 對 Stylesheet 載入進行優化,透過 Stylesheet 搭配 Suspense 可以讓 script 和 Stylesheet 載入同時進行。透過 Suspense 可以在載入 CSS 時顯示 fallback UI,當 CSS 完全載入時再顯示真正的內容。

使用範例:

function MyComponent() {
  return (
    <Suspense fallback="loading...">
      <link rel="stylesheet" href="foo" precedence="default" />
      <link rel="stylesheet" href="bar" precedence="high" />
      <article class="foo-class bar-class">{/* ... */}</article>
    </Suspense>
  );
}

當在 <link> 使用 rel="stylesheet" 時才能使用 precedence 屬性。precedence用來告訴 React 這個 Stylesheet 相對於其他樣式的優先級。高優先級的樣式會覆蓋低優先級的樣式,載入的結果會像下面這樣:

<html>
  <head>
    <link rel="stylesheet" href="bar" />
    <link rel="stylesheet" href="foo" />
  </head>
  <body>
     <!-- 其他內容 -->
  </body>
</html>

除了使用 <link> 來載入樣式外,也可以使用 <style> 來載入樣式。功能都是類似的,一樣有 precedence 來告訴 React 這個樣式優先級。另外如果在不同的 Component 多次載入相同的 Stylesheet, React 也只會載入一次。

Async Script

如果是正常的使用 <script> 會阻塞 HTML 解析,因為瀏覽器會在載入與執行完腳本後才繼續處理其他內容。為了避免阻塞可以使用 async 屬性來非同步加載 JavaScript 文件。

在 React 19 之前使用 Async Script 並不會保證載入順序,React 19 改進了 Async Script,可以在 Component 中載入 <script> ,並且也會去除重複載入。

使用範例:

function MyComponent() {
  return (
    <>
      <script async src="/path/to/some/script.js" />
      {/* ... */}
    </>
  );
}

針對 preload 的處理

在 React 19 也推出了許多新 API 來處理資源的 preload。React 會將這些內容放到 <head> 中,並會根據優先順序重新排序。透過 preload 可以優化初始頁面載入時間,除此之外也可以與事件處理器結合使用,讓我們在預計要切換頁面時提前加載所需資源。

  • preload:用於預加載 stylesheet、字體、圖片或外部的 script。
  • preinit:用於提前載入 script,或插入 stylesheet。
  • preloadModulepreinitModule:這些 API 是針對 ESM module。
  • prefetchDNS:提前解析 DNS 資源。
  • preconnect:提前與伺服器建立連接。

使用範例:

import { prefetchDNS, preconnect, preload, preinit } from "react-dom";
function MyComponent() {
  preinit("https://.../path/to/some/script.js", { as: "script" });
  preload("https://.../path/to/font.woff", { as: "font" });
  preload("https://.../path/to/stylesheet.css", { as: "style" });
  prefetchDNS("https://...");
  preconnect("https://...");
}

參考資料:
https://www.youtube.com/watch?v=IBBN-s77YSI
https://react.dev/blog/2024/04/25/react-19
https://react.dev/reference/react-dom/components/script
https://react.dev/reference/react-dom/components/style
https://www.youtube.com/watch?v=AJOGzVygGcY


上一篇
Day 21 - 掌握 React 19 use API,處理 Context 和非同步資料
下一篇
Day 23 - 掌握 React Memoization : React.Memo 、useMemo 和 useCallback
系列文
前進React 生態系 : 技術應用與概念解析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言