SPAにおける`
フロントエンドのアーキテクチャを語る際、私たちは往々にして「どのフレームワークを使うか」という流行の表面をなぞりがちだ。しかし、ブラウザという巨大なエンジンが解釈するHTMLのセマンティクス、特に`
今日は、SPA(Single Page Application)における`
1. ``は「単一」であるべきという制約と現実
HTML仕様において、`
しかし、SPAではページ遷移が「DOMの置換」として行われる。ここで多くのエンジニアが陥る罠が、「`
一見すると正しいように思える。しかし、ブラウザのアクセシビリティツリー(AOM)が、DOMの高速な書き換えに追従できず、フォーカス管理が迷子になるケースが多発する。特に、非同期でコンテンツをロードし、`innerHTML`や仮想DOMのパッチを当てる際、`
2. フォーカス管理:UXを崩壊させる「沈黙のバグ」
SPAで最も軽視されがちなのが、ルート遷移時のフォーカス移動だ。リンクをクリックしてページが変わった際、スクリーンリーダーのフォーカスが`body`の先頭や、最悪の場合は`document`全体に戻ってしまうことがある。
これを防ぐための、堅牢な実装パターンをTypeScriptで示そう。
/
- ページ遷移時にメインコンテンツへフォーカスを強制するアクセシビリティ・フック
- レンダリング完了後に実行することが必須となる
/
import { useEffect, useRef } from ‘react’;
export const useFocusMain = (contentKey: string) => {
const mainRef = useRef
useEffect(() => {
// 仮想DOMのコミットが完了したことを保証するために微小な遅延を設ける場合もあるが、
// 基本的にはMutationObserver等でDOMの確定を検知するのが最も安全
const mainElement = mainRef.current;
if (mainElement) {
// 既存のフォーカスを解除し、mainに移動させる
mainElement.setAttribute(‘tabindex’, ‘-1’);
mainElement.focus({ preventScroll: true });
}
}, [contentKey]); // コンテンツのキーが変わるたびに実行
return mainRef;
};
ここで重要なのは、`tabindex=”-1″`を動的に付与することだ。これにより、HTML本来のフォーカス可能性を維持しつつ、プログラムからの強制遷移を許可する。この小さな実装が、キーボードユーザーにとっての「アプリケーションの信頼性」を決定づける。
3. レンダリング負荷とメモリリークの回避
`
パフォーマンスを最適化する戦略
- コンポーネントのクリーンアップ: `useEffect`のクリーンアップ関数内で、必ず`ResizeObserver`や`addEventListener`を明示的に解除する。
- DOMの断片化を避ける: `main`直下で大量のDOMを生成・破棄せず、`DocumentFragment`や仮想DOMのレンダリングエンジンを信頼しつつ、階層を深めすぎない(CSS Containmentの活用を検討せよ)。
- CSS `contain` プロパティ: `main { contain: content; }` を指定することで、メインコンテンツ内の変更が外側のレイアウトに波及するのを防ぎ、ブラウザのリフローコストを劇的に下げることができる。
4. 非同期の競合:Race Conditionへの対策
SPAでは、ページ遷移のたびにAPIからデータを取得する。ここで厄介なのが、「前の遷移のフェッチが、後の遷移のレンダリングより遅れて完了する」という競合問題だ。
これを放置すると、`
// 競合を防ぐためのAbortController活用例
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const data = await api.get(‘/content’, { signal: controller.signal });
updateState(data);
} catch (err) {
if (err.name !== ‘AbortError’) handleErr(err);
}
};
fetchData();
// クリーンアップでリクエストをキャンセルする
return () => controller.abort();
}, [url]);
結論:ユーザーのための「静かなる設計」
`
SPAの柔軟性に甘え、DOMを乱雑に書き換える実装は、エンジニアとしての怠慢でしかない。ブラウザの内部挙動を理解し、アクセシビリティを設計の最上位に置く。この泥臭い積み重ねこそが、洗練されたWebアプリケーションを形作る唯一の道なのだ。
コードを書くとき、自問してほしい。「この`

コメント