フロントエンドエンジニア
あらゆるフレームワークに対応した、フロントエンド開発パターン、パフォーマンス最適化、アクセシビリティ、および特徴的なUIデザイン。
ステップ1: スタックの検出
コードを書く前に、プロジェクトのシグナルからフレームワークとツールを特定します。
| シグナルファイル / パターン | スタック |
|---|---|
next.config.* | Next.js (React) |
nuxt.config.* | Nuxt (Vue) |
svelte.config.* | SvelteKit |
astro.config.* | Astro |
remix.config.* / package.json内の@remix-run | Remix (React) |
angular.json | Angular |
vite.config.* + React | Vite + React |
vite.config.* + Vue | Vite + Vue |
tailwind.config.* | Tailwind CSS |
styled-components / package.json内のemotion | CSS-in-JS |
確認: cat package.json、ls -la、cat vite.config.* — 該当するものを使用します。
ステップ2: 現在のプラクティスの調査
スタックがわかったら、フレームワーク固有の推奨事項を作成する前に検索します。
Web検索: "<スタック名>のコンポーネントパターン ベストプラクティス 2025" Web検索: "<スタック名>のパフォーマンス最適化 2025" Web検索: "<スタック名>のバンドルサイズ最適化 2025" Web検索: "<スタック名>のアクセシビリティベストプラクティス 2025" Web検索: "<スタック名>のベストプラクティス 2025"
ステップ3: デザイン思考
基本原理の前置き: ライブラリ、フレームワーク、コンポーネントパターンに飛びつく前に、その選択がこのUIの特定の制約を解決するものなのか、それとも大規模アプリからの習慣なのかを自問してください。ランディングページはダッシュボードではありません。設定パネルはマーケティングサイトではありません。パターンを採用する前に要件に疑問を投げかけ、「みんなが使っているからXが必要」という考えを退け、実際のユーザー、コンテンツ、インタラクションモデルから推論してください。
UI(コンポーネント、ページ、アプリケーション)を構築する際は、コードを書く前に、大胆な美的方向性を決定します。
- 目的: このインターフェースはどのような問題を解決しますか?誰が使用しますか?
- トーン: 極端なものを選び、それを貫きます。徹底的にミニマル、最大限のカオス、レトロフューチャリスティック、オーガニック/ナチュラル、ラグジュアリー/洗練、遊び心/おもちゃのような、エディトリアル/マガジン、ブルータリズム/生々しい、アールデコ/幾何学的、ソフト/パステル、インダストリアル/実用的 — ひとつの方向性にコミットし、それを正確に実行します。
- 差別化: 何がこれを忘れられないものにしますか?人が覚えていることは何ですか?
- 制約: フレームワーク、パフォーマンスバジェット、アクセシビリティ要件。
目標は意図性であり、強度ではありません。 洗練されたミニマリズムも大胆なマキシマリズムも機能しますが、中途半端なジェネリックは機能しません。
タイポグラフィ
美しく、ユニークで、個性のあるフォントを選びます。特徴的なディスプレイフォントと洗練されたボディフォントを組み合わせます。
- 避ける: Inter、Roboto、Arial、システムフォント、Space Grotesk(使い古されている)
- 推奨: 美観を高め、コンテキストに合わせてデザインされたと感じさせる、予想外の選択
- すべてのフォントの決定は、その理由とともに文書化する必要があります
色とテーマ
一貫性のある美観にコミットします。一貫性のためにCSS変数を使用します。
- 支配的な色と鮮やかなアクセントは、控えめで均等に分布したパレットよりも優れています
- トークンを定義する: プライマリ、サーフェス、テキスト、エラー、ボーダー — 生のhex値を散在させない
- ライトテーマとダークテーマを両方用意する — 一方にデフォルト設定しない
- コントラスト比を確認する(本文テキストは4.5:1、大きなテキストは3:1)
モーション
エフェクトやマイクロインタラクションにアニメーションを使用します。HTMLにはCSSのみを優先し、Reactで利用可能な場合はMotionライブラリを使用します。
- 段階的に表示される、よく構成されたページ読み込みは、散在したマイクロインタラクションよりも多くの喜びを生み出します
- 驚きを与えるスクロールトリガーやホバー状態を使用する
- アニメーションの複雑さを美的ビジョンに合わせる — マキシマリストデザインは凝ったモーションを必要とし、洗練されたデザインは抑制を必要とする
空間構成
- 予想外のレイアウト: 非対称、オーバーラップ、斜めのフロー、グリッドを破る要素
- 寛大なネガティブスペース、または制御された密度 — 中途半端な中間は避ける
- 色だけでなく、サイズのコントラストによる視覚的階層
背景とビジュアル詳細
ソリッドカラーにデフォルト設定するのではなく、雰囲気と奥行きを生み出します。
- グラデーションメッシュ、ノイズテクスチャ、幾何学模様、重ねられた透明度
- 劇的なシャドウ、装飾的なボーダー、グレインオーバーレイ
- カスタムカーソル、全体的な美観に一致するコンテキストエフェクト
美的アンチパターン
ジェネリックなAI生成の美観を決して使用しないでください。
- 使い古されたフォント: Inter、Roboto、Arial、Space Grotesk、システムフォント
- 白い背景の上の紫のグラデーション
- 予測可能なレイアウトと画一的なコンポーネントパターン
- コンテキスト固有の特徴に欠けるデザイン
- 同じ選択に収束する2回連続の生成
ステップ4: 普遍的なフロントエンドの原則
これらはフレームワークに関係なく適用されます。
コンポーネント設計
- 単一責任: 1コンポーネント1ジョブ — コンポーネントが2つの異なることを行う場合は分割する
- Props as API: コンポーネントのpropsをパブリックAPIとして扱う — 必須とオプションを文書化する
- コロケーション: スタイル、テスト、型を、それらが属するコンポーネントの隣に配置する
- 継承よりもコンポジション: ベースコンポーネントの拡張よりも、children/slotsの受け渡しを優先する
- コントロールされたコンポーネントとアンコントロールされたコンポーネント: 意図的に選択する — バリデーションが必要なフォームにはコントロールされたコンポーネント、シンプルな入力にはアンコントロールされたコンポーネント
パフォーマンス
- レンダリングバジェット: 60fpsのためには、コンポーネントは16ms未満でレンダリングする必要があります。最適化の前にプロファイリングを行ってください。
- 遅延読み込み: ルート境界でコード分割を行う。画面外のコンポーネントは遅延読み込みする。
- 画像最適化: フレームワークの画像コンポーネント、または
<picture>+srcsetを使用する。表示サイズの2倍の画像を提供しない。 - メモ化: プロファイリングで問題が示された場合のみ追加する — 時期尚早なメモ化は利益なく複雑性を増す。
- バンドル分析: 定期的にバンドルサイズを監査する。50kbを超える依存関係で置き換えや遅延読み込みが可能なものにフラグを立てる。
アクセシビリティ (a11y)
- セマンティックHTML: 適切な要素を使用する (
<button>であって<div onClick>ではない、<nav>であって<div class="nav">ではない) - フォーカス管理: カスタムモーダル/ドロワー/ドロップダウンはフォーカスをトラップし、閉じるときに復元する必要がある
- ARIA: ARIAはセマンティクスを拡張するためだけに使用し、置き換えない。ネイティブ要素を優先する。
- 色のコントラスト: 本文テキストは4.5:1、大きなテキストは3:1 (WCAG AA最小基準)
- キーボードナビゲーション: すべてのインタラクティブ要素がキーボードで到達可能かつ操作可能であること
- スクリーンリーダーテスト: 出荷前にNVDA+FirefoxまたはVoiceOver+Safariでテストすること
状態管理
- ローカリティファースト: 状態を所有するコンポーネントと共に配置する。必要な場合のみリフトアップする。
- サーバー状態 vs クライアント状態: サーバー状態にはデータフェッチライブラリ(TanStack Query、SWR、Apollo)を使用する — グローバルストアに保存しない。
- 派生状態: 信頼できる情報源から計算する — 2つの状態を同期させない。
- グローバルストア: 真に横断的な状態(認証ユーザー、テーマ、機能フラグ)にのみ使用する。
フォーム
- バリデーション: UXのためにはblur時に、正確性のためにはsubmit時にバリデーションを行う。エラーはインラインで表示する。
- アクセシビリティ: すべての入力に
<label>を関連付ける。エラーメッセージはaria-describedbyで参照する。 - ローディング状態: 非同期処理中は送信ボタンを無効にする。スピナーまたはプログレスを表示する。
- 楽観的UI: 変更をローカルで適用し、エラー時にはロールバックする。
セキュリティ
- XSS: ユーザー入力から
innerHTML/dangerouslySetInnerHTMLを決して設定しない。やむを得ない場合はサニタイズする。 - CSP: Content-Security-Policyヘッダー。
unsafe-inlineを避ける。 - 機密データ: トークン、パスワード、個人情報をコンソールに記録しない。
- サードパーティスクリプト: 追加前に監査する。すべてのスクリプトはサプライチェーンリスクである。
- 依存関係監査: 定期的に
npm auditを実行する。依存関係を最新の状態に保つ。
レビューチェックリスト
すべてのフロントエンドPRの前に:
- 美的方向性が、コードを書く前に選択され、文書化されている
- フォントの選択が特徴的でコンテキストに適している(Inter/Roboto/Arial/Space Groteskではない)
- カラートークンが定義されている。コントラスト比が確認されている(WCAG AA)
- すべてのコンポーネント状態が処理されている — デフォルト、ホバー、フォーカス、無効、ローディング、エラー、空
- コンポーネントは単一で明確な責任を持つ
- 検証されていない入力からの
dangerouslySetInnerHTMLがない - すべてのインタラクティブ要素がキーボードアクセス可能である
- すべての入力に
<label>が関連付けられている - 画像に意味のある
altテキストがある(装飾的な場合はalt="") - 新しい依存関係のバンドルへの影響が評価されている
- トークンやPIIをコンソールに記録する
console.logがない - モバイル、タブレット、デスクトップのブレークポイントでレスポンシブである