フロントエンドの非機能要件
フロントエンドの非機能要件
Section titled “フロントエンドの非機能要件”フロントエンドの非機能要件は、ユーザー体験に直接影響する重要な要件です。
フロントエンドで着目すべき非機能要件
Section titled “フロントエンドで着目すべき非機能要件”1. パフォーマンス要件
Section titled “1. パフォーマンス要件”レスポンスタイム:
- 初回表示時間(FCP): 1.8秒以内
- 最大コンテンツ表示時間(LCP): 2.5秒以内
- First Input Delay(FID): 100ミリ秒以内
- Cumulative Layout Shift(CLS): 0.1以下
実装例:
パフォーマンスを向上させるための実装例を示します。画像の最適化、コード分割、メモ化を組み合わせることで、初回表示時間を短縮できます。
// 画像の最適化// Next.jsのImageコンポーネントを使用することで、自動的に画像を最適化// loading="lazy"で遅延読み込みを実装し、初期表示を高速化import Image from 'next/image';
<Image src="/product.jpg" width={500} height={300} alt="Product" loading="lazy" // 遅延読み込み: 画面に表示されるまで画像を読み込まない priority={false} // 優先度の設定: falseにすることで、重要な画像以外は後から読み込む/>
// コード分割// 大きなコンポーネントを動的にインポートすることで、初期バンドルサイズを削減// ユーザーが実際にそのコンポーネントを使用するタイミングで読み込むconst HeavyComponent = dynamic(() => import('./HeavyComponent'), { loading: () => <Loading />, // 読み込み中はローディング表示 ssr: false, // サーバーサイドレンダリングを無効化(クライアント側のみで実行)});
// メモ化// 高価な計算を行うコンポーネントをメモ化することで、不要な再レンダリングを防止// propsが変更されない限り、前回のレンダリング結果を再利用const MemoizedComponent = React.memo(ExpensiveComponent);これらの最適化により、FCP(First Contentful Paint)を1.8秒以内、LCP(Largest Contentful Paint)を2.5秒以内に抑えることができます。
バンドルサイズ:
- JavaScriptバンドル: 200KB以下(gzip圧縮後)
- CSSバンドル: 50KB以下(gzip圧縮後)
- 画像: WebP形式を使用、適切なサイズに最適化
2. セキュリティ要件
Section titled “2. セキュリティ要件”XSS対策:
- ユーザー入力のサニタイズ
- Reactの自動エスケープを活用
- Content Security Policy(CSP)の設定
実装例:
XSS(Cross-Site Scripting)攻撃を防ぐための実装例を示します。ユーザー入力を受け取る際は、必ず適切なエスケープまたはサニタイズを実施する必要があります。
// 危険な実装(XSS脆弱性)// dangerouslySetInnerHTMLを使用すると、HTMLタグがそのまま実行されるため、// 悪意のあるスクリプトが注入される可能性がある<div dangerouslySetInnerHTML={{ __html: userInput }} />
// 安全な実装// Reactはデフォルトで自動的にエスケープを行うため、通常のJSX記法を使用すれば安全// ユーザー入力に含まれるHTMLタグは文字列として表示される<div>{userInput}</div> // Reactが自動的にエスケープ
// サニタイズが必要な場合// リッチテキストエディタなど、HTMLを表示する必要がある場合は、// DOMPurifyなどのライブラリでサニタイズしてから使用するimport DOMPurify from 'dompurify';// サニタイズにより、危険なスクリプトタグなどを除去し、安全なHTMLのみを残す<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />この実装により、XSS攻撃を防ぎ、ユーザーのセキュリティを保護できます。
CSRF対策:
- CSRFトークンの実装
- SameSite Cookieの設定
実装例:
CSRF(Cross-Site Request Forgery)攻撃を防ぐための実装例を示します。CSRFトークンをリクエストヘッダーに含めることで、正当なリクエストであることを証明します。
// CSRFトークンの送信// HTMLのmetaタグからCSRFトークンを取得// サーバー側で生成されたトークンを、クライアント側で取得して使用するconst csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
// APIリクエスト時にCSRFトークンをヘッダーに含める// サーバー側でこのトークンを検証することで、正当なリクエストかどうかを判断fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrfToken, // CSRFトークンをヘッダーに追加 }, body: JSON.stringify(data),});この実装により、CSRF攻撃を防ぎ、ユーザーの操作を保護できます。
3. 可用性要件
Section titled “3. 可用性要件”エラーハンドリング:
- 適切なエラーメッセージの表示
- エラーバウンダリーの実装
- リトライ機能の実装
実装例:
エラーハンドリングとリトライ機能の実装例を示します。エラーバウンダリーは、Reactコンポーネントツリー内で発生したエラーをキャッチし、適切に処理します。リトライ機能は、ネットワークエラーなどの一時的なエラーに対して自動的に再試行を行います。
// エラーバウンダリー// Reactコンポーネントツリー内で発生したエラーをキャッチし、ユーザーに適切なエラー画面を表示// エラーが発生したコンポーネントの代わりに、エラーフォールバックUIを表示するclass ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; }
// エラーが発生した際に、stateを更新してエラー状態にする static getDerivedStateFromError(error) { return { hasError: true }; }
// エラーの詳細情報をログに記録し、エラー報告サービスに送信 // これにより、本番環境でのエラーを追跡・分析できる componentDidCatch(error, errorInfo) { console.error('Error:', error, errorInfo); // エラーログを送信 errorReportingService.report(error); }
// エラーが発生している場合はエラーフォールバックを表示、そうでなければ通常の子コンポーネントを表示 render() { if (this.state.hasError) { return <ErrorFallback />; // エラー時の代替UI } return this.props.children; // 通常のコンポーネント }}
// リトライ機能// TanStack Queryを使用したデータフェッチングのリトライ機能// ネットワークエラーなどの一時的なエラーに対して、自動的に再試行を行うconst { data, error, retry } = useQuery({ queryKey: ['users'], queryFn: fetchUsers, retry: 3, // 最大3回までリトライ // 指数バックオフ: 1秒、2秒、4秒...とリトライ間隔を増やしていく(最大30秒) retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),});この実装により、エラーが発生してもアプリケーションがクラッシュせず、ユーザーに適切なエラーメッセージを表示できます。また、一時的なネットワークエラーに対して自動的にリトライすることで、ユーザー体験を向上させます。
オフライン対応:
- Service Workerの実装
- オフライン時の動作定義
4. アクセシビリティ要件
Section titled “4. アクセシビリティ要件”WCAG準拠:
- レベルA: 最低限の要件
- レベルAA: 推奨される要件
- レベルAAA: 最高レベルの要件
実装例:
アクセシビリティを向上させるための実装例を示します。セマンティックHTML、キーボード操作、フォーカス管理を適切に実装することで、スクリーンリーダーやキーボードのみで操作するユーザーにも使いやすいアプリケーションになります。
// セマンティックHTML// アイコンのみのボタンには、aria-labelでアクセシブルな名前を提供// スクリーンリーダーが「メニューを開く」と読み上げることで、視覚障害者にも機能が伝わる<button aria-label="メニューを開く"> <MenuIcon /></button>
// キーボード操作// マウスだけでなく、キーボードでも操作できるようにする// Enterキーまたはスペースキーでクリックと同じ動作を実行const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { handleClick(); }};
// フォーカス管理// モーダルやフォームが開いた際に、適切な要素にフォーカスを移動// これにより、キーボードユーザーがスムーズに操作できるconst inputRef = useRef<HTMLInputElement>(null);useEffect(() => { inputRef.current?.focus(); // コンポーネントがマウントされた際に、入力欄にフォーカス}, []);この実装により、WCAG 2.1 レベルAAに準拠し、すべてのユーザーがアプリケーションを利用できるようになります。
5. ブラウザ互換性要件
Section titled “5. ブラウザ互換性要件”対応ブラウザ:
- Chrome(最新版と1つ前)
- Firefox(最新版と1つ前)
- Safari(最新版と1つ前)
- Edge(最新版)
実装例:
ブラウザ互換性を確保するための実装例を示します。ポリフィルを使用することで、古いブラウザでも最新のJavaScript機能を使用できます。機能検出により、ブラウザがサポートしていない機能を使用する前に確認できます。
// ポリフィルの使用// core-jsは、古いブラウザで最新のJavaScript機能(Promise、Array.fromなど)を使用できるようにする// regenerator-runtimeは、async/awaitなどの非同期処理を古いブラウザで動作させるimport 'core-js/stable';import 'regenerator-runtime/runtime';
// 機能検出// ブラウザがService Workerをサポートしているか確認してから使用する// サポートしていないブラウザでは、Service Workerの登録をスキップしてエラーを防ぐif ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js');}この実装により、主要なブラウザでアプリケーションが正常に動作することを保証できます。
6. モバイル対応要件
Section titled “6. モバイル対応要件”レスポンシブデザイン:
- モバイルファーストの設計
- タッチ操作の最適化
- 画面サイズの考慮
実装例:
モバイル対応のためのレスポンシブデザインの実装例を示します。モバイルファーストのアプローチでは、まずモバイル向けのスタイルを定義し、その後で大きな画面向けのスタイルを追加します。これにより、モバイルデバイスでのパフォーマンスを最適化できます。
/* モバイルファースト *//* まず、モバイル向けの基本スタイルを定義 *//* モバイルデバイスでは、パディングを1remに設定 */.container { padding: 1rem;}
/* メディアクエリを使用して、768px以上の画面(タブレット・デスクトップ)向けのスタイルを追加 *//* 大きな画面では、パディングを2remに増やすことで、より広い余白を確保 */@media (min-width: 768px) { .container { padding: 2rem; }}この実装により、モバイル、タブレット、デスクトップのすべてのデバイスで最適な表示を実現できます。
フロントエンドの非機能要件チェックリスト
Section titled “フロントエンドの非機能要件チェックリスト”パフォーマンス
Section titled “パフォーマンス”- FCPが1.8秒以内
- LCPが2.5秒以内
- FIDが100ミリ秒以内
- CLSが0.1以下
- JavaScriptバンドルが200KB以下
- 画像が最適化されている
セキュリティ
Section titled “セキュリティ”- XSS対策が実装されている
- CSRF対策が実装されている
- 機密情報がクライアントに露出していない
- HTTPSが使用されている
- エラーハンドリングが実装されている
- エラーバウンダリーが実装されている
- リトライ機能が実装されている
- オフライン対応が実装されている
アクセシビリティ
Section titled “アクセシビリティ”- WCAG 2.1 レベルAAに準拠
- キーボード操作が可能
- スクリーンリーダーに対応
- 適切なARIA属性が設定されている
ブラウザ互換性
Section titled “ブラウザ互換性”- 主要ブラウザで動作確認済み
- ポリフィルが適切に設定されている
- 機能検出が実装されている
モバイル対応
Section titled “モバイル対応”- レスポンシブデザインが実装されている
- タッチ操作が最適化されている
- モバイルでのパフォーマンスが良好
フロントエンドの非機能要件:
- パフォーマンス: Core Web Vitals、バンドルサイズ、画像最適化
- セキュリティ: XSS対策、CSRF対策、機密情報の保護
- 可用性: エラーハンドリング、オフライン対応
- アクセシビリティ: WCAG準拠、キーボード操作、スクリーンリーダー対応
- ブラウザ互換性: 主要ブラウザでの動作確認
- モバイル対応: レスポンシブデザイン、タッチ操作の最適化
適切な非機能要件を定義・実装することで、高品質なフロントエンドアプリケーションを構築できます。