サーバー不要!Vue3で作るアニメキャラMBTI診断アプリ
15年前、ちょっとした性格診断やアンケートアプリを作るとなれば、LAMPスタック一択という時代があった。ユーザーがラジオボタンをポチポチと押し、「結果を見る」をクリックする。するとサーバーにPOSTリクエストが飛び、PHPがセッションからデータを拾ってゴニョゴニョと計算し、結果画面をレンダリングして返す。そんな往復運動を当然のように実装してきた身からすると、現代のブラウザが持つ処理能力と、アーキテクチャの進化にはいまだにハッとさせられることがある。
GitHubの海を漂っていて目に止まった「ACGTI」というリポジトリも、そんな気付きを与えてくれるプロジェクトの一つだ。一言で言えば、MBTI(マイヤーズ・ブリッグス・タイプ指標)のフレームワークをベースにした二次元キャラクター診断アプリである。「ぼっち・ざ・ろっく!」や「名探偵コナン」、「原神」など、40以上のキャラクターから自分の性格に合致するものを導き出してくれる。
一見すると、SNSでよくバズっているエンタメ系の診断サイトに過ぎない。しかしソースコードを開いてみると、そこには現代的なフロントエンド開発における「ちょうどいい塩梅」が詰まっていた。
純フロントエンドがもたらすゼロ・レイテンシ
このプロジェクトの最大の美徳は、バックエンドを完全に排除したアーキテクチャにある。Vue 3、TypeScript、Tailwind CSSという王道の技術スタックを採用し、ビルドにはViteを使用。39問に及ぶ質問データ、8つのアーキタイプ、キャラクターの属性データは、すべて静的なJSONファイルとして切り出されており、データベースは一切存在しない。
ユーザーの回答状態の保持や、スコアリング、キャラクターのマッチングロジックは、すべてブラウザ上のJavaScript上で完結している。サーバーとの通信が発生しないため、結果表示に至るまでの遷移に遅延が全くない。SPA(Single Page Application)の強みを極限まで活かした、シームレスで心地よいUXが実現されているのだ。
ロジックとUIの鮮やかな分離
診断系のアプリケーションで往々にしてカオスになりがちなのが、状態管理と計算ロジックの混在だ。コンポーネントの中にif文が連なり、スコアの集計と画面の描画が密結合してしまう悲劇は、誰もが一度は経験したことがあるだろう。
ACGTIでは、Vue 3のComposition APIを活用し、コンポーネントからビジネスロジックを見事に分離している。計算エンジンのアプローチを単純化すると、おおよそ以下のような設計思想が透けて見える。
// スコアリングの抽象化イメージ
export function calculateScores(answers: number[], questions: Question[]) {
const scores = { E: 0, I: 0, S: 0, N: 0, T: 0, F: 0, J: 0, P: 0 };
answers.forEach((ans, idx) => {
const q = questions[idx];
scores[q.dimension] += ans * q.weight; // 回答(-3〜+3)と重みを乗算
});
return scores;
}
UIコンポーネントは「ユーザーの入力を受け取る」「結果を表示する」ことに徹し、複雑な次元の重み付けや計算はピュアな関数として切り出されている。これにより、質問の追加やアルゴリズムの調整を行っても、画面側のコードには一切手を触れずに済む。エンジニアの精神衛生に極めて優しい設計だ。
プライバシー保護の最適解としての「サーバーレス」
技術的な保守性の高さに加えて、このアーキテクチャが提供するもう一つの巨大な価値が「プライバシーの保護」である。
診断系アプリは、時に個人のセンシティブな傾向や心理状態を入力させる性質を持つ。ACGTIのREADMEには「本ツールはエンターテインメント目的であり、心理診断ではない」という免責事項があるが、それでも「自分の回答データがどこかのサーバーに保存され、分析されているのではないか」という不安をユーザーに抱かせないことは重要だ。計算をすべてローカルで行い、外部へのデータ送信を行わないこの構成は、現代のWebサービスにおいて最も強力な信頼の担保となる。
データベースが不要なユースケースにおいて、フロントエンドだけでどれだけの価値を生み出せるか。重厚なインフラを組まずとも、表現力豊かでセキュアなアプリケーションは作れる。その鮮やかな証明が、ここにある。
参考リポジトリ: tianxingleo/ACGTI
Photo by Rubaitul Azad on Unsplash