2025年1月27日

Reactの差分検知(Fiber Reconciliation)のRender phaseについて

  • 差分検知を理解するために、「Component(JSX)→ React.createElement → vDOMのオブジェクト」を理解して頭に入れておく必要がある

Component(JSX)

// カウントするReactコンポーネント
function Counter() {
  const [count, setCount] = useState(0)
  return (
    <span>
      <div>
        <h1>hello world!!</h1>
        <div>クリック数: {count}</div>
        <button onClick={() => setCount(count + 1)}>クリック</button>
      </div>
    </span>
  )
}

React.createElement

// JSXをcreateElementに置き換えると
function Counter() {
  const [count, setCount] = useState(0)

  return React.createElement(
    'span',
    null,
    React.createElement(
      'div',
      null,
      React.createElement('h1', null, 'hello world!!'),
      React.createElement('div', null, 'クリック数: ', count),
      React.createElement(
        'button',
        { onClick: () => setCount(count + 1) },
        'クリック'
      )
    )
  )
}

vDOMのオブジェクト

{
  type: 'span',
  props: {
    // spanの中が1つの要素だけならchildrenがobjectになる
    children: {
      type: 'div',
      props: {
        // divの中が複数の要素ならchildrenが配列になる(要素が1つになるまで配列だと思う)
        children: [
          {
            type: 'h1',
            props: {
              children: 'hello world!!',
            },
          },
          {
            type: 'div',
            props: {
              children: ['クリック数: ', count],
            },
          },
          {
            type: 'button',
            props: {
              onClick: () => setCount(count + 1),
              children: 'クリック',
            },
          },
        ],
      },
    },
  },
}

Fiber Reconciliation

  • Fiberとは、React elementから作成されるReconcilerの最小の作業単位のこと。

  • Fiber ReconcilerでのReconciliation Flowは以下の通り

reconciliation-flow

  • 1.workLoop

    • TODO: 調査
  • 2.Render phase

  • 3.Commit phase

    • render phaseの間に作成されたvDOMの変更をActual DOMに更新をかける責務
    • commit phaseは2段階に分かれる。
    • Mutation phase
    • Layout phase
      • DOMで更新されたnodesのの新たなレイアウトを計算する責務を持つ(commitLayoutEffectsメソッド)
      • 更新するnodeの方に依存して、異なる関数を呼ぶ大きな切り替かわるstatementがcommitLayoutEffectsメソッド。layout phaseが終わると、Actual DOMへの変更の適応が成功したということになる。
      • commitLayoutEffects
      • Commit phaseを2つに分けることで、Reactは効率的な方法でDOMに更新を適用できる。Commit phaseは、Reconciler内の他の主要な機能と協調して動作することで、Reactアプリケーションが複雑化し、大量のデータを扱うようになっても、高速で応答性が高く、信頼性の高いアプリケーションを実現するのに役立つ。
      • FiberRootNodeが差分検知のcommit phaseを管理する責務を持つ鍵となるデータ構造である。
      • reactはレンダリングプロセスを終了するとcommitRootメソッドを呼ぶ。commitRootはActual DOMにwork in progress treeの変更点をcommitする責務を持つ。

参照

Fluent React: Build Fast, Performant, and Intuitive Web Applications