跳至主要內容

關於新架構

資訊

如果您正在尋找新架構指南,它們已移至 工作小組

自 2018 年以來,React Native 團隊一直在重新設計 React Native 的核心內部結構,以讓開發人員能夠創造出更高品質的體驗。截至 2024 年,此版本的 React Native 已被證明具有規模性,並為 Meta 提供生產應用程式。

術語新架構同時指新的框架架構和將其公開原始碼的工作。

新架構自 React Native 0.68 起便已開放實驗性選擇加入,且在每個後續版本中持續改進。團隊目前正努力讓這成為 React Native 開源生態系統的預設體驗。

為何需要新架構?

在使用 React Native 進行多年的建置後,團隊發現了一組限制,這些限制讓開發人員無法打造出具備高度精緻度的特定體驗。這些限制是架構現有設計的基本要素,因此新架構作為對 React Native 未來的投資而開始。

新架構解鎖了舊有架構中無法實現的功能和改進。

同步佈局和效果

建置適應性使用者介面體驗通常需要測量檢視的大小和位置,並調整佈局。

目前,您會使用 onLayout 事件來取得檢視的佈局資訊並進行任何調整。然而,onLayout 回呼中的狀態更新可能會在繪製前一次渲染後套用。這表示使用者可能會在渲染初始佈局和回應佈局測量之間看到中間狀態或視覺跳動。

有了新架構,我們可以透過同步存取佈局資訊和適當排程的更新來完全避免這個問題,如此一來,使用者便不會看到任何中間狀態。

範例:渲染提示工具

測量並將提示工具置於檢視上方,讓我們得以展示同步渲染解鎖的功能。提示工具需要知道其目標檢視的位置,才能決定其應渲染的位置。

在目前的架構中,我們使用 onLayout 來取得檢視的測量,然後根據檢視所在位置更新提示工具的位置。

function ViewWithTooltip() {
// ...

// We get the layout information and pass to ToolTip to position itself
const onLayout = React.useCallback(event => {
targetRef.current?.measureInWindow((x, y, width, height) => {
// This state update is not guaranteed to run in the same commit
// This results in a visual "jump" as the ToolTip repositions itself
setTargetRect({x, y, width, height});
});
}, []);

return (
<>
<View ref={targetRef} onLayout={onLayout}>
<Text>Some content that renders a tooltip above</Text>
</View>
<Tooltip targetRect={targetRect} />
</>
);
}

透過新架構,我們可以使用 useLayoutEffect 同步測量並在單次提交中套用版面更新,避免視覺上的「跳動」。

function ViewWithTooltip() {
// ...

useLayoutEffect(() => {
// The measurement and state update for `targetRect` happens in a single commit
// allowing ToolTip to position itself without intermediate paints
targetRef.current?.measureInWindow((x, y, width, height) => {
setTargetRect({x, y, width, height});
});
}, [setTargetRect]);

return (
<>
<View ref={targetRef}>
<Text>Some content that renders a tooltip above</Text>
</View>
<Tooltip targetRect={targetRect} />
</>
);
}
A view that is moving to the corners of the viewport and center with a tooltip rendered either above or below it. The tooltip is rendered after a short delay after the view moves
非同步測量和渲染 ToolTip。 查看程式碼
A view that is moving to the corners of the viewport and center with a tooltip rendered either above or below it. The view and tooltip move in unison.
同步測量和渲染 ToolTip。 查看程式碼

支援並行渲染器和功能

新架構支援並行渲染和 React 18 及後續版本中發布的功能。現在,您可以在 React Native 程式碼中使用懸置(用於資料擷取)、轉場和其他新的 React API 等功能,進一步讓 Web 和原生 React 開發之間的程式碼庫和概念保持一致。

並行渲染器也帶來開箱即用的改善,例如自動批次處理,這可減少 React 中的重新渲染。

範例:自動批次處理

透過新架構,您將透過 React 18 渲染器獲得自動批次處理。

在此範例中,滑桿會指定要渲染多少個磁磚。將滑桿從 0 拖曳到 1000 會觸發一連串快速的狀態更新和重新渲染。

在比較 相同程式碼 的渲染器時,你可以視覺上注意到渲染器提供更順暢的 UI,且 UI 更新較少。原生事件處理常式的狀態更新,例如這個原生滑桿元件,現在已批次處理。

A video demonstrating an app rendering many views according to a slider input. The slider value is adjusted from 0 to 1000 and the UI slowly catches up to rendering 1000 views.
使用舊版渲染器渲染頻繁的狀態更新。
A video demonstrating an app rendering many views according to a slider input. The slider value is adjusted from 0 to 1000 and the UI resolves to 1000 views faster than the previous example, without as many intermediate states.
使用 React 18 渲染器渲染頻繁的狀態更新。

新的並行功能,例如 轉場,讓你能夠表達 UI 更新的優先順序。將更新標記為較低優先順序會告訴 React,它可以「中斷」渲染更新,以處理較高優先順序的更新,以確保在重要的地方提供回應式使用者體驗。

範例:使用 startTransition

我們可以建立在先前的範例上,展示轉場如何中斷進行中的渲染,以處理較新的狀態更新。

我們使用 startTransition 包裝磁磚編號狀態更新,以表示可以中斷磁磚的渲染。startTransition 也提供 isPending 旗標,讓我們知道轉場何時完成。

function TileSlider({value, onValueChange}) {
const [isPending, startTransition] = useTransition();

return (
<>
<View>
<Text>
Render {value} Tiles
</Text>
<ActivityIndicator animating={isPending} />
</View>
<Slider
value={1}
minimumValue={1}
maximumValue={1000}
step={1}
onValueChange={newValue => {
startTransition(() => {
onValueChange(newValue);
});
}}
/>
</>
);
}

function ManyTiles() {
const [value, setValue] = useState(1);
const tiles = generateTileViews(value);
return (
<TileSlider onValueChange={setValue} value={value} />
<View>
{tiles}
</View>
)
}

你會注意到,在轉場中進行頻繁更新時,React 渲染較少的中間狀態,因為它會在狀態過期後立即取消渲染狀態。相較之下,在沒有轉場的情況下,會渲染更多中間狀態。這兩個範例都仍然使用自動批次處理。儘管如此,轉場讓開發人員有更大的能力來批次處理進行中的渲染。

A video demonstrating an app rendering many views (tiles) according to a slider input. The views are rendered in batches as the slider is quickly adjusted from 0 to 1000. There are less batch renders in comparison to the next video.
使用轉場渲染磁磚,以中斷過期狀態的進行中渲染。 查看程式碼
A video demonstrating an app rendering many views (tiles) according to a slider input. The views are rendered in batches as the slider is quickly adjusted from 0 to 1000.
渲染磁磚而不將其標記為轉場。 查看程式碼

快速 JavaScript/原生介面

新架構移除了 JavaScript 和原生程式碼之間的非同步橋接,並以 JavaScript 介面 (JSI) 取代。JSI 是一個介面,允許 JavaScript 持有 C++ 物件的參考,反之亦然。有了記憶體參考,您就能直接呼叫方法,而無需序列化成本。

JSI 能讓VisionCamera(一個 React Native 的熱門相機程式庫)即時處理影像。典型的影像緩衝區大小為 10 MB,這表示每秒大約會產生 1 GB 的資料,具體取決於影像速率。與橋接的序列化成本相比,JSI 能輕鬆處理這種大量的介面資料。JSI 可以公開其他複雜的基於執行個體的類型,例如資料庫、影像、音訊範例等。

新架構採用 JSI,從所有原生-JavaScript 互操作中移除了這類型的序列化工作。這包括初始化和重新渲染原生核心元件,例如 ViewText。您可以在新架構中閱讀更多關於我們渲染效能研究,以及我們所測量的效能改善基準。

深入了解

為達成此目的,新架構必須重新調整 React Native 基礎架構的許多部分。若要深入了解重新調整和其他好處,請查看新架構工作小組中的文件

啟用新架構後,我可以期待什麼?

雖然新架構啟用了這些功能和改進,但為您的應用程式或程式庫啟用新架構可能不會立即改善效能或使用者體驗。

例如,您的程式碼可能需要重新調整才能利用新的功能,例如同步配置效果或並發功能。雖然 JSI 會將 JavaScript 和原生記憶體之間的開銷減至最低,但資料序列化可能並非您應用程式效能的瓶頸。

在您的應用程式或程式庫中啟用新架構等於選擇 React Native 的未來。

團隊積極研究和開發新架構解鎖的新功能。例如,網頁對齊是 Meta 積極探索的領域,將會發布到 React Native 開放原始碼生態系統。

您可以在我們專用的討論和建議儲存庫中追蹤並做出貢獻。

我今天應該使用新架構嗎?

目前,新架構被視為實驗性質,我們持續調整向後相容性以獲得更好的採用體驗。

團隊計畫在 2024 年底的 React Native 發行版本中預設啟用新架構。

我們的建議如下

  • 對於大多數的製作應用程式,我們建議現在就啟用新架構。等待正式發布會提供最佳體驗。
  • 如果您維護 React Native 函式庫,我們建議啟用它並驗證您的使用案例是否涵蓋。您可以在 這裡 找到說明

啟用新架構

如果您有興趣體驗新架構,您可以在我們專屬的工作小組中找到說明新架構工作小組 是專門提供新架構採用支援與協調的空間,團隊也會定期在此發布更新。