Opt-in設計とOpt-out設計
機能やオプションのデフォルト動作をどう設定するかという設計思想。ユーザー体験と認知負荷に大きな影響を与える。
Opt-out型(デフォルト有効)
機能がデフォルトで有効になっており、無効化するには明示的な操作が必要。
特徴
- 暗黙的な動作: ユーザーが何もしなくても機能が働く
- 初期体験の簡便性: 最初から機能が使える
- 予測困難性: デフォルト動作を知らないと予想外の挙動が発生
- 影響範囲の拡大: 意図せず広範囲に機能が適用される可能性
適用場面
- セキュリティ機能(デフォルトで安全な状態)
- 最適化やパフォーマンス向上(多くの場合に有益)
- 標準的なベストプラクティス
事例:Next.js v13-14のCache
App Routerでは、デフォルトでデータがキャッシュされました:
// 暗黙的にキャッシュされる
fetch("https://api.example.com/data")
開発者が意識しなくてもパフォーマンスが向上する意図でしたが:
- 予想外のデータの鮮度問題
- 無効化方法の理解が必要
- 認知負荷の増大
Opt-in型(デフォルト無効)
機能がデフォルトで無効になっており、有効化するには明示的な宣言が必要。
特徴
- 明示的な動作: ユーザーが意図的に機能を有効化
- 予測可能性: 宣言した場所でのみ機能が働く
- 初期学習コスト: 機能の存在と使い方を知る必要がある
- 影響範囲の限定: 局所的な制御が可能
適用場面
- 破壊的な変更や副作用のある機能
- ユースケースが限定的な最適化
- 実験的な機能(Feature Flag)
事例:Next.js v16の"use cache"
v16では、明示的にキャッシュを宣言する方式に変更:
export async function getData() {
"use cache";
return fetch("https://api.example.com/data");
}
開発者が意図した場所でのみキャッシュが有効化されます:
- 予測可能な動作
- 局所的な制御
- 認知負荷の軽減
設計の選択基準
Opt-out型を選ぶべき場合
- 安全性が優先: セキュリティ、プライバシー保護
- ほぼ常に有益: 99%のケースで望ましい動作
- 無効化が簡単: 明確なOpt-out手段がある
Opt-in型を選ぶべき場合
- 副作用が大きい: 予期しない影響が広範囲に及ぶ
- ユースケースが限定的: 特定の状況でのみ有用
- 学習が必要: 正しく使うための理解が求められる
移行の課題
Opt-out型からOpt-in型への移行は破壊的変更(Breaking Change)になります:
- 既存コードが動かなくなる可能性
- 段階的な移行戦略が必要
- ドキュメントとコミュニケーションが重要
[[Next.js]]の事例では、v14でfetch()のデフォルトCache廃止、v15でRouter Cacheのデフォルト変更、v16で"use cache"導入と、段階的に移行しました。
プライバシーとの関係
個人情報の扱いでは、Opt-in型が倫理的・法的に求められる:
- GDPRやプライバシー法規制
- クッキー同意
- データ収集の明示的同意
マーケティングやトラッキングは、Opt-out型では倫理的に問題があります。
認知負荷の観点
Opt-out型の認知負荷
- 初期: 低い(何もしなくても動く)
- 理解: 高い(暗黙の動作を理解する必要)
- 制御: 高い(無効化方法を探す必要)
Opt-in型の認知負荷
- 初期: 高い(有効化方法を学ぶ必要)
- 理解: 低い(明示的なので予測しやすい)
- 制御: 低い(宣言した場所でのみ動作)
長期的には、Opt-in型の方が認知負荷が低いことが多いです。
関連
- 認知負荷
- [[Next.js]]
- App Router
- 抽象化
- フィードバック
参照
- Next.jsキャッシング戦略の変遷 - Opt-out型からOpt-in型への移行の実例
- 仕様駆動開発への懐疑
- shadcn-uiが支持された理由 - コード所有モデルによる透明性重視の設計