BuriKaigi2023 登壇資料です。Twitter で公開されているポケモンSVのレンタルチームを検索できるアプリを Remix + Cloudflare Pages + Cloudflare D1 で作成しました。Edge location でデータベース操作とレンダリングを行う爆速アプリの構成についてお話します。
アプリ:https://pokemon-rental-teams-search.pages.dev/
Remix + Cloudflare Pages + D1 でポケモン SV のレンタルチームを検索できるアプリを作ってみた@もやし丸1
View Slide
自己紹介もやし丸Software Engineer / Scrum MasterGitHub: @kuroppe1819Twitter: @mys_x1012
作ったものポケモン SV のレンタルチームを検索できるサイトhttps://pokemon-rental-teams-search.pages.dev/3
レンタルチームとは?インターネット上で公開されている ID を入力して、簡単にバトルチームを借りることができる機能です。自分の育てたバトルチームを公開して、世界中のポケモントレーナーに使ってもらうことも可能です。「バトルスタジアム」で世界中のポケモントレーナーとバトルしよう!4
バトルチームの作り方5
ポケモンを育てよう!6
ポケモン SV 時代の育成は「金」と「レイド」がすべて孵化作業は過去の話ステータスを上げるアイテムはすべて金で購入できるレイドポケモンを倒すとレベル上げやテラスタイプを変更するアイテムをドロップする7
効率よくお金を稼ぐ金策ニンフィアを育成し、学校最強大会を A ボタン連打で周回する大体 10 分で 10 万円稼げる私は Arduino で自動周回できるようにしました8
世代が進むにつれて育成のハードルが下がっている9
というわけで皆さんも Let's ポケモンバトル10
レンタルチームを借りてみよう!Q. レンタルチームはどこで公開されている?A. Twitter、Youtube、まとめサイト...etc11
Twitter でレンタルチームを検索してみよう!#レンタルチーム , #レンタルパーティ or#pokemon vgcで検索!12
Twitter でレンタルチームを検索してみよう!#レンタルチーム , #レンタルパーティ or#pokemon vgcで検索!→ 自分のお気に入りのポケモンが含まれているチームを見つけるのが大変13
そこで役に立つのが Pokemon Rental Teams Search14
Pokemon Rental Teams Search なら検索したポケモンが含まれるレンタルチームを表示してくれます15
ここから技術の話16
Web アプリの構成17
Web アプリの構成18
pokemon-rental-teams-search-appRemix + Cloudflare Pages + Cloudflare D119
pokemon-rental-teams-search-app20
pokemon-rental-teams-search-app の役割レンタルチームの表示検索21
なぜ Cloudflare D1 を採用したのかEdge location で DB が動く = Origin server (DB)へのアクセス時間を短縮できるコールドスタートなし22
なぜ Remix を採用したのかEdge location でのレンダリング - Remix and NextGen “Edge”Cloudflare Workers との連携が強力23
Remix + Cloudflare D1 で検索アプリを作ってみる24
プロジェクト作成1. npx [email protected]2. Cloudflare Pages を選択してプロジェクト作成25
D1 データベース作成 ~ Worker と D1 をバインドD1 Get started - Cloudflare Docs を参照26
データベースからデータを取得してみるloaderGET アクセス時のデータフェッチを定義loader の戻り値をコンポーネント側の useLoaderData で受け取れる27
検索を実装してみる -ComponentRemix の Form コンポーネントを使って実装する例28
検索を実装してみる -loaderrequest からクエリ文字列を取り出す29
ローカル開発環境で動作確認Worker 起動オプションに --d1, --persistを付与するwrangler pages dev ./public --d1= --persist$ npm run dev30
完成31
ポケモンレンタルチーム検索サイトの読み込み時間250ms~350ms で応答できる(TTFB)レイアウトが変化した箇所だけフェッチするため、検索のレスポンスが高速32
投稿, 更新, 削除の実装actionPOST, PUT, PATCH, DELETE などのミューテーションを定義するform 要素, useSubmit などからリクエストするルートに対して GET 以外のリクエストが行われた場合、loader の前に action が呼び出される。33
StylingFlowbite を採用した - Tailwind CSS ベースの UI コンポーネントライブラリバンドルサイズが 1MB を超えないようにライブラリを選んだUI ライブラリや CSS in JS ライブラリを入れると 1MB に抑えるのがきつい34
Remix v1.11.0 で CSS Modules と Vanilla Extract がサポートされましたWith this release, we can now support:Direct CSS side-effect importsCSS ModulesVanilla Extractremix v1.11.0 - GitHub35
Astro を採用してもよかったコンポーネント側にロジックがなく、データを表示するだけgetRuntime を使うと .astroファイルから Cloudflare runtime にアクセスできるCloudflare Workers との連携はRemix の方が強力36
pokemon-rental-teams-app まとめRemix + Cloudflare D1 構成は Edge location で DB 操作とレンダリングを行うので非常に高速Remix が変更があったレイアウトのみデータフェッチしてくれるため、検索のレスポンスも高速バンドルサイズ 1MB (無料枠)の制限に注意37
pokemon-rental-teams-search-data-syncCloudflare Workers + Cloudflare D1 + AWS Lambda38
pokemon-rental-teams-search-data-sync39
pokemon-rental-teams-search-data-sync の役割Twitter からレンタルチーム画像付きのツイートのみを取得して DB に保存する40
Cron Trigger で Workerを定期実行Worker の 「Triggers」 タブから設定する41
Cloudflare Workers の制限V8 の JavaScript エンジンを使っているため、Node.js が動かないWorker limits - Cloudflare42
Cloudflare Workers から Lambda を実行AWS Lambda を叩くとレンタルチームの画像を含むツイート情報を返してくれるので、そのレスポンスを DB に書き込むCPU runtime が 10ms しかないかつ、Worker 非対応のライブラリがまだまだ多いため、DB 操作以外の処理は AWS Lambda に切り出した43
レンタルチームの画像を含むツイートを返すTwitter の Recent Search API を叩いて取得したツイート情報から画像の URL を取得する取得した画像の URL を 画像比較用の AWS Lambda に渡すと、画像の一致率が返ってくる一致率が閾値以上ならメモリにスタック、閾値未満なら破棄44
画像の一致率を求める単純な画素の比較ユーザーは Switch の Twitter 連携機能を使ってレンタルチームの画像を投稿するので、縦横幅のサイズが 1280 x 720 の JPEG 画像に統一されているJPEG 形式の画像をバイナリデータに変換して比較しているだけ45
AWS Lambda の並列実行1280 x 720 の画像の画素比較にかかる時間は 1 枚あたり約 1 秒100 枚ほどの画像を比較すると、Amazon API Gateway の Timeout 時間 30 秒を超えてしまうため、Promise.All で並列実行する1 分 30 秒 →19 秒に短縮Lambda URL を使うと Timeout を 15 分まで伸ばすことが可能だが、今回は素直に並列実行した46
これからヒストグラム比較で類似度を算出するとスマホのカメラで直撮りしたレンタルチームの画像も拾えるようになるかもしれないテンプレートマッチング法などで画像のポケモン名を抽出したい総ポケモン数 x 対応言語数 x 手持ちポケモンの数 = 最大比較数400 x 6 x 6 = 1440047
pokemon-rental-teams-data-sync のまとめ定期実行でレンタルチームのツイートを DB に書き込んでいるCloudflare Workers は DB の操作のみ行い、他の処理は外部に切り出しているレンタルチームの比較は単純な画素比較画像比較の方法を変えると自動で収集できるツイートが増えるかも48
全体のまとめTwitter で公開されているレンタルチームを検索するアプリを作ってみたので、ポケモン対戦に興味のある方はぜひ使ってみてくださいRemix + Cloudflare D1 で Edge location で動くアプリを簡単に作れるよWorker の制限内に収まるように外部サービスをうまく活用してアプリケーションを設計しよう49