はじめに
Suspense テクニックは当初、非同期コンポーネントをロードするために設計されましたが、 徐々に全ての非同期プロセスに適用されるようになりました。その中でも非同期リクエストはSusppenseが使われる最も重要なシナリオです。近い将来、Susppenseベースの開発パターンが主流になると同時に、ユーザーエクスペリエンスもSusppenseを使うことで最適化されるでしょう。
Suspenseの使い方は
Vueの使い方は
Reactの使い方は
Suspense
一般的な技術として、RespenseはReactとVueで基本的に同じように実装されています。
通信手段:Susppenseとその内部に組み込まれたコンポーネント間の通信、つまりSusppenseがコンポーネントの非同期状態を取得する方法。
レンダリングとは:Susppenseがその中に組み込まれたコンポーネントのレンダリングを制御する方法です。
Susppenseがコンポーネントの非同期状態を取得する方法
表面的には、VueもReactもSuspenseにプロミス関連のプロップを渡していないように見えます。固まった考え方では、propsがコンポーネントへの唯一のエントリポイントであると仮定するのは簡単です。
実際、サスペンスはフレームワークの組み込みコンポーネントとして、ランタイムに存在するあらゆる変数を取得する「完全な自由」を持っています。
Vueの場合、セットアップでpromiseを "return "すると、Vueはそのpromiseを取得し、自動的に一番近いSuspenseに渡します。
Reactの場合、レンダリングでプロミスが "throw "されると、Reactはそのプロミスをキャプチャして、自動的に一番近いSusppenseに渡すことができます。
このようにして、サスペンスはコンポーネントの非同期状態を取得します。
Susppenseに埋め込まれたコンポーネントのレンダリングを制御する方法
サスペンスは常にコンポーネントを隠しコンテナにプリレンダリングし、その後、関連するプロミスの状態に基づいて選択を行います:
プロミスがペンディング状態の場合、フォールバックコンポーネントは実際のdomコンテナにレンダリングされます。
プロミスがresolve状態に達した場合、プリレンダリングされたコンポーネントを実際のdomコンテナに直接移動し、フォールバックコンポーネントをクリアします。
もしプロミスがrejectの状態になったら、フレームワークはrejectエラーを直接投げます。
フェーズ1 ユーザー・エクスペリエンスの最適化
コンポーネントで非同期データをロードすることは、ビジネスシナリオで最も一般的な要件です。 コンポーネントの状態は、非同期データの状態に応じて変化します。
異なるステートに対応するコンポーネントのコンテンツをレンダリングするために、従来のv-if/v-elseの形式、またはjsxの3項式を使用すると、実際にパフォーマンス上の問題が発生する可能性があります:
// template
<Loading v-if="loading">loading...</Loading>
<Content v-else>実際のコンテンツ</Content>
// jsx
(
loading ? <Loading>loading</Loading> : <Content>実際のコンテンツ</Content>
)
2つの異なる要素のレンダリングを切り替える場合、どちらもコンポーネントの破壊と再構築を伴います。サスペンスでは、実要素とフォールバックの両方が同時に存在します。 フォールバックが現れても実要素は破壊されず、フォールバックが消えても再構築されません。
このようにして、ページのレンダリングパフォーマンスが大幅に改善されるため、ユーザーエクスペリエンスは最初の段階で最適化されます。
フェーズ2 ユーザー・エクスペリエンスの最適化
レンダリングのパフォーマンスは大幅に改善されました。では、他に何を最適化できるのでしょうか?Reactの並行処理パターンは、ローディング状態をキルオフするという新しいアイデアをもたらします。
React Concurrency PatternはReact Fiberアーキテクチャの応用で、コンポーネントツリーの更新はコンポーネント単位で非同期化され、メインスレッドをブロックしないようにコンポーネントの更新を中断することができます。
実際の環境では、ユーザーの端末性能やネットワーク速度が異なり、性能が良くてネットワーク速度が速い人もいれば、性能が悪くてネットワーク速度が遅い人もいて、このような状況になります:
高い | 低い | デバイスのコンディションはすでにとても良く、ミリ秒単位でデータをロードしていますが、それでもロード状態を点滅させています |
低い | 高い | デバイスの状態が悪く、セカンドレベルでデータをロードする場合、ロード状態があると快適です。 |
上記の問題は、Reactの同時実行パターンと組み合わせてSusppenseを使用することで解決できます:
codesandbox.io/s/elated-ca...
更新をクリックすると、リストが更新されます
リストを更新するインターフェースには、0~1秒の間のランダムな時間がかかります。
インターフェイスが0.5秒以内に戻った場合、ローディングステータスは表示されません。
インターフェイスが0.5秒以外の時間を返した場合、ロードステータスが表示されます。
FAQ
待ってください、Reactの並行処理パターンを使わなくても、第2段階のUX最適化を実現できます。
タイマーを追加して、一定時間経過後にのみローディングが表示されるようにするだけです。
Vue UXはReactより劣っていますか?
VueはSusppenseのパフォーマンス最適化に貢献することはできませんが、Vueは別の方向からレンダリングパフォーマンスの大幅な向上をもたらします:vnodeを事前に分析し、タイプに応じて適切なpatchFlagを与え、フラグに応じて最も効率的な更新方法を取ります。





