2026-05-16
クライアント完結ツールのプライバシー設計指針
クライアントサイド完結のWebツールは、データをサーバーに一切送信しないことでプライバシーを守ります。設計・実装・UI表示まで実例を交えて解説します。
この記事の要点
- クライアント完結とはJSの処理がブラウザ内で完結しサーバーへのデータ送信がゼロの設計を指す
- テキスト変換・計算・画像処理・ハッシュ計算など幅広い処理がモダンブラウザAPIで実現できる
- ロジックを純粋関数に切り出すとユニットテストが書きやすくなり品質担保が容易になる
- UI上に「データはブラウザ内で処理されます」と明示することがユーザーの信頼獲得に直結する
- 大規模処理やリアルタイム協調編集などクライアント完結に向かない用途も存在する
パスワード・画像・個人データをWebサービスに貼り付けるとき、「本当にサーバーには送っていないのか?」と気になることはないでしょうか。
クライアント完結型のWebツールは、処理をすべてブラウザ内で完結させる設計です。ユーザーのデータがネットワークを一切通過しない仕組みを実現します。
クライアント完結とは何か
クライアント完結とは、ページ読み込み後の処理がすべてブラウザ内で完結するアーキテクチャです。ユーザーが入力したデータは、ネットワークを一切通過しません。
通常のWebアプリケーションでは「ユーザーの入力→サーバーへ送信→処理→結果を返す」という流れを取ります。クライアント完結型は「入力→ブラウザ内で処理→結果表示」というフローです。サーバーとの通信が発生するのは、最初のHTMLやJavaScriptファイルのダウンロード時だけです。
なぜサーバーに送らないのか
プライバシーリスクの排除
サーバーに送信されたデータは、その後どこに保存されるかわかりません。ログファイルに残る可能性があり、将来的にセキュリティインシデントの対象になりえます。処理がブラウザで完結していれば、そもそもデータがサーバーに存在しないため、流出リスクがゼロになります。
パスワード・画像・位置情報など、センシティブな情報を扱うツールでは特にこの設計原則が重要です。健康データ(BMI・カロリー)や金融計算のパラメーターも、プライバシー設計の文脈で「慎重に扱うべきデータ」の代表例です。
GDPRや個人情報保護法との親和性
EUのGDPRや日本の個人情報保護法では、個人情報の処理に対して利用者への説明義務が生じます。クライアント完結型なら、個人情報の「取得」「保存」「第三者提供」にあたらないケースが多いです。コンプライアンス上のリスクを大幅に低減できます。
サーバーレスによる運用コストの削減
処理をサーバーで行わないため、計算コストが発生しません。Cloudflare PagesやGitHub Pagesなど静的ホスティングで配信でき、ランニングコストをほぼゼロにできます。
スケーリングも不要です。ユーザーが増えても、ブラウザがCPUを使うだけです。
ブラウザAPIで実現できる処理
モダンブラウザには、サーバーが不要なほど豊富なAPIが揃っています。
テキスト処理
Stringのメソッド群やRegExpで、文字列の変換・カウント・並び替えが実現できます。Intl.SegmenterやIntl.Collatorを使えば、日本語の書記素クラスタ単位の処理も完結します。
エンコード・変換
TextEncoder・TextDecoderでUTF-8バイト列への変換が行えます。btoa・atobでBase64変換、encodeURIComponentでURLエンコードも同様に実現できます。
暗号・ハッシュ
Web Crypto API(crypto.subtle)は、SHA-256・SHA-512などのハッシュ計算に対応しています。AESによる暗号化/復号やRSAキーペアの生成も同じAPIで実現できます。
const buffer = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(input)
);
const hex = Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
画像処理
Canvas APIとcreateImageBitmapを使うと、画像のリサイズ・圧縮・変換がブラウザ内で完結します。OffscreenCanvasを使えばメインスレッドをブロックせずに処理できます。
QRコード・SVG生成
qrcodeなどのピュアJSライブラリを使えば、QRコードのSVGやPNG生成もサーバー不要です。SVGはDOMで生成でき、そのままファイルとしてダウンロードできます。
設計パターン: ロジックとUIの分離
クライアント完結ツールを品質高く作るための核心は、ロジックとUIの分離です。
src/
lib/tools/base64-tool.ts ← 純粋関数(UIに依存しない)
components/tools/Base64Tool.tsx ← UIのみ(ロジックを呼ぶだけ)
ロジックを純粋関数として切り出すと、以下のメリットがあります。
- ユニットテストが書きやすい: DOM・ブラウザAPI不要でロジックを検証できる
- 再利用しやすい: 別のUIフレームワークに移行しても関数はそのまま使える
- デバッグが容易: 入力と出力が明確で副作用がない
// src/lib/tools/base64-tool.ts
export function encodeBase64(input: string): string {
const bytes = new TextEncoder().encode(input);
return btoa(String.fromCharCode(...bytes));
}
export function decodeBase64(input: string): string {
const bytes = Uint8Array.from(atob(input), c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
このように副作用のない純粋関数として書けば、vitestで高速にテストできます。
Web Workerで重い処理をバックグラウンドへ
ハッシュ計算・画像処理・大量テキストの解析など、処理に時間がかかる場合はWeb Workerをメインスレッドの外で実行します。
// worker.js
self.onmessage = async (e) => {
const { input } = e.data;
const result = await heavyProcess(input);
self.postMessage({ result });
};
// メインスレッド
const worker = new Worker('/worker.js');
worker.postMessage({ input });
worker.onmessage = (e) => setResult(e.data.result);
ReactではWorkerをuseRefで保持し、unmount時にterminate()するパターンが一般的です。UIがフリーズせずレスポンシブのまま処理できるため、ユーザー体験が大幅に改善します。
UIで信頼を明示する
処理がブラウザ完結であることをUIで明示することが、ユーザーの信頼獲得に直結します。
「🔒 データはブラウザ内で処理され、サーバーに送信されません」という一文をフッターに常時表示することが重要です。これにより、ユーザーが安心してデータを入力できるようになります。
クライアント完結に向かないケース
すべての処理をクライアント完結にできるわけではありません。以下のケースはサーバーを使う方が合理的です。
| ケース | 理由 |
|---|---|
| リアルタイム協調編集 | 複数ユーザー間のデータ同期が必要 |
| 大規模データの永続化 | LocalStorageは容量限界(5MB前後)がある |
| 外部APIへのアクセス | CORS制限やシークレットキーの秘匿が必要 |
| サーバーサイドレンダリング | SEOや初期表示速度のための静的HTML生成 |
| メール送信・通知 | SMTPサーバーはブラウザから直接呼べない |
Webツール(計算・変換・エンコード・生成)は処理が自己完結するため、クライアント完結との相性が非常に良いカテゴリです。
てもとツールでの実践例
てもとツールでは40以上のツールすべてをクライアント完結で実装しています。代表的な例を挙げます。
- ハッシュ値計算: Web Crypto APIの
crypto.subtle.digestでSHA-256/512を計算。ファイルや文字列をサーバーに送らずにハッシュを生成できます。 - Base64エンコード・デコード:
TextEncoderでUTF-8変換後にbtoaでエンコード。日本語テキストでも文字化けしません。 - 画像リサイズ:
createImageBitmapとOffscreenCanvasでブラウザ内リサイズ。画像がサーバーに送信されることは一切ありません。
まとめ
クライアント完結の設計は、プライバシー保護・運用コスト削減・コンプライアンスリスク低減の3点で大きなメリットをもたらします。
重要なポイントを再確認します。
- ブラウザAPIは
TextEncoder・Web Crypto・Canvas・Intlなど、多くの処理に対応している - ロジックを純粋関数に切り出すことでテスト容易性と再利用性が高まる
- 重い処理はWeb Workerでバックグラウンド実行する
- UIに「ブラウザ内で処理」と明示することがユーザーの信頼につながる
- リアルタイム協調・大規模永続化など、向かないケースも把握しておく
Webツールを作るときに「この処理はサーバーが本当に必要か?」と問い直すことが、よりプライバシーフレンドリーなサービス設計の第一歩です。