Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Remix + Cloudflare Pages + Cloudflare D1 で ポケモン SV のレンタルチームを検索できるアプリを作ってみた

Remix + Cloudflare Pages + Cloudflare D1 で ポケモン SV のレンタルチームを検索できるアプリを作ってみた

BuriKaigi2023 登壇資料です。Twitter で公開されているポケモンSVのレンタルチームを検索できるアプリを Remix + Cloudflare Pages + Cloudflare D1 で作成しました。Edge location でデータベース操作とレンダリングを行う爆速アプリの構成についてお話します。

アプリ:https://pokemon-rental-teams-search.pages.dev/

Atsusuke Murata

January 21, 2023
Tweet

More Decks by Atsusuke Murata

Other Decks in Programming

Transcript

  1. Remix + Cloudflare Pages + D1 でポケモン SV のレンタ
    ルチームを検索できるアプリを作ってみた
    @もやし丸
    1

    View Slide

  2. 自己紹介
    もやし丸
    Software Engineer / Scrum Master
    GitHub: @kuroppe1819
    Twitter: @mys_x101
    2

    View Slide

  3. 作ったもの
    ポケモン SV のレンタルチームを検
    索できるサイト
    https://pokemon-rental-teams-
    search.pages.dev/
    3

    View Slide

  4. レンタルチームとは?
    インターネット上で公開されている ID を入力して、簡単にバトルチームを借りることが
    できる機能です。自分の育てたバトルチームを公開して、世界中のポケモントレーナー
    に使ってもらうことも可能です。
    「バトルスタジアム」で世界中のポケモントレーナーとバトルしよう!
    4

    View Slide

  5. バトルチームの作り方
    5

    View Slide

  6. ポケモンを育てよう!
    6

    View Slide

  7. ポケモン SV 時代の育成
    は「金」と「レイド」が
    すべて
    孵化作業は過去の話
    ステータスを上げるアイテムはす
    べて金で購入できる
    レイドポケモンを倒すとレベル上
    げやテラスタイプを変更するアイ
    テムをドロップする
    7

    View Slide

  8. 効率よくお金を稼ぐ
    金策ニンフィアを育成し、学校最
    強大会を A ボタン連打で周回する
    大体 10 分で 10 万円稼げる
    私は Arduino で自動周回できるよ
    うにしました
    8

    View Slide

  9. 世代が進むにつれて育成のハードルが下がっている
    9

    View Slide

  10. というわけで皆さんも Let's ポケモンバトル
    10

    View Slide

  11. レンタルチームを借りてみよう!
    Q. レンタルチームはどこで公開されている?
    A. Twitter、Youtube、まとめサイト...etc
    11

    View Slide

  12. Twitter でレンタルチー
    ムを検索してみよう!
    #
    レンタルチーム , #
    レンタルパーティ or
    #pokemon vgc
    で検索!
    12

    View Slide

  13. Twitter でレンタルチー
    ムを検索してみよう!
    #
    レンタルチーム , #
    レンタルパーティ or
    #pokemon vgc
    で検索!
    → 自分のお気に入りのポケモ
    ンが含まれているチームを見
    つけるのが大変
    13

    View Slide

  14. そこで役に立つのが Pokemon Rental Teams Search
    14

    View Slide

  15. Pokemon Rental Teams Search なら検索したポケモンが
    含まれるレンタルチームを表示してくれます
    15

    View Slide

  16. ここから技術の話
    16

    View Slide

  17. Web アプリの構成
    17

    View Slide

  18. Web アプリの構成
    18

    View Slide

  19. pokemon-rental-teams-search-app
    Remix + Cloudflare Pages + Cloudflare D1
    19

    View Slide

  20. pokemon-rental-teams-search-app
    20

    View Slide

  21. pokemon-rental-teams-search-app の役割
    レンタルチームの表示
    検索
    21

    View Slide

  22. なぜ Cloudflare D1 を採用したのか
    Edge location で DB が動く = Origin server (DB)へのアクセス時間を短縮できる
    コールドスタートなし
    22

    View Slide

  23. なぜ Remix を採用したのか
    Edge location でのレンダリング - Remix and NextGen “Edge”
    Cloudflare Workers との連携が強力
    23

    View Slide

  24. Remix + Cloudflare D1 で検索アプリを作ってみる
    24

    View Slide

  25. プロジェクト作成
    1. npx [email protected]
    2. Cloudflare Pages を選択してプロジェクト作成
    25

    View Slide

  26. D1 データベース作成 ~ Worker と D1 をバインド
    D1 Get started - Cloudflare Docs を参照
    26

    View Slide

  27. データベースからデータ
    を取得してみる
    loader
    GET アクセス時のデータフェッチ
    を定義
    loader の戻り値をコンポーネント
    側の useLoaderData で受け取れる
    27

    View Slide

  28. 検索を実装してみる -
    Component
    Remix の Form コンポーネントを使って
    実装する例
    28

    View Slide

  29. 検索を実装してみる -
    loader
    request からクエリ文字列を取り出す
    29

    View Slide

  30. ローカル開発環境で動作確認
    Worker 起動オプションに --d1
    , --persist
    を付与する
    wrangler pages dev ./public --d1= --persist
    $ npm run dev
    30

    View Slide

  31. 完成
    31

    View Slide

  32. ポケモンレンタルチーム検索サイトの読み込み時間
    250ms~350ms で応答できる(TTFB)
    レイアウトが変化した箇所だけフェッチするため、検索のレスポンスが高速
    32

    View Slide

  33. 投稿, 更新, 削除の実装
    action
    POST, PUT, PATCH, DELETE など
    のミューテーションを定義する
    form 要素, useSubmit などからリ
    クエストする
    ルートに対して GET 以外のリクエ
    ストが行われた場合、loader の前
    に action が呼び出される。
    33

    View Slide

  34. Styling
    Flowbite を採用した - Tailwind CSS ベースの UI コンポーネントライブラリ
    バンドルサイズが 1MB を超えないようにライブラリを選んだ
    UI ライブラリや CSS in JS ライブラリを入れると 1MB に抑えるのがきつい
    34

    View Slide

  35. Remix v1.11.0 で CSS Modules と Vanilla Extract がサポ
    ートされました
    With this release, we can now support:
    Direct CSS side-effect imports
    CSS Modules
    Vanilla Extract
    remix v1.11.0 - GitHub
    35

    View Slide

  36. Astro を採用してもよか
    った
    コンポーネント側にロジックがな
    く、データを表示するだけ
    getRuntime を使うと .astro

    ァイルから Cloudflare runtime に
    アクセスできる
    Cloudflare Workers との連携は
    Remix の方が強力
    36

    View Slide

  37. pokemon-rental-teams-app まとめ
    Remix + Cloudflare D1 構成は  Edge location で DB 操作とレンダリングを行うので非
    常に高速
    Remix が変更があったレイアウトのみデータフェッチしてくれるため、検索のレスポン
    スも高速
    バンドルサイズ 1MB (無料枠)の制限に注意
    37

    View Slide

  38. pokemon-rental-teams-search-data-sync
    Cloudflare Workers + Cloudflare D1 + AWS Lambda
    38

    View Slide

  39. pokemon-rental-teams-search-data-sync
    39

    View Slide

  40. pokemon-rental-teams-search-data-sync の役割
    Twitter からレンタルチーム画像付きのツイートのみを取得して DB に保存する
    40

    View Slide

  41. Cron Trigger で Worker
    を定期実行
    Worker の 「Triggers」 タブから設
    定する
    41

    View Slide

  42. Cloudflare Workers の制限
    V8 の JavaScript エンジンを使っているため、Node.js が動かない
    Worker limits - Cloudflare
    42

    View Slide

  43. Cloudflare Workers か
    ら Lambda を実行
    AWS Lambda を叩くとレンタルチ
    ームの画像を含むツイート情報を
    返してくれるので、そのレスポン
    スを DB に書き込む
    CPU runtime が 10ms しかないか
    つ、Worker 非対応のライブラリが
    まだまだ多いため、DB 操作以外の
    処理は AWS Lambda に切り出した
    43

    View Slide

  44. レンタルチームの画像を
    含むツイートを返す
    Twitter の Recent Search API を叩
    いて取得したツイート情報から画
    像の URL を取得する
    取得した画像の URL を 画像比較
    用の AWS Lambda に渡すと、画像
    の一致率が返ってくる
    一致率が閾値以上ならメモリにス
    タック、閾値未満なら破棄
    44

    View Slide

  45. 画像の一致率を求める
    単純な画素の比較
    ユーザーは Switch の Twitter 連携
    機能を使ってレンタルチームの画
    像を投稿するので、縦横幅のサイ
    ズが 1280 x 720 の JPEG 画像に
    統一されている
    JPEG 形式の画像をバイナリデータ
    に変換して比較しているだけ
    45

    View Slide

  46. AWS Lambda の並列実行
    1280 x 720 の画像の画素比較にかかる時間は 1 枚あたり約 1 秒
    100 枚ほどの画像を比較すると、Amazon API Gateway の Timeout 時間 30 秒を超えて
    しまうため、Promise.All で並列実行する
    1 分 30 秒 →19 秒に短縮
    Lambda URL を使うと Timeout を 15 分まで伸ばすことが可能だが、今回は素直に並列
    実行した
    46

    View Slide

  47. これから
    ヒストグラム比較で類似度を算出するとスマホのカメラで直撮りしたレンタルチームの
    画像も拾えるようになるかもしれない
    テンプレートマッチング法などで画像のポケモン名を抽出したい
    総ポケモン数 x 対応言語数 x 手持ちポケモンの数 = 最大比較数
    400 x 6 x 6 = 14400
    47

    View Slide

  48. pokemon-rental-teams-data-sync のまとめ
    定期実行でレンタルチームのツイートを DB に書き込んでいる
    Cloudflare Workers は DB の操作のみ行い、他の処理は外部に切り出している
    レンタルチームの比較は単純な画素比較
    画像比較の方法を変えると自動で収集できるツイートが増えるかも
    48

    View Slide

  49. 全体のまとめ
    Twitter で公開されているレンタルチームを検索するアプリを作ってみたので、ポケモン
    対戦に興味のある方はぜひ使ってみてください
    Remix + Cloudflare D1 で Edge location で動くアプリを簡単に作れるよ
    Worker の制限内に収まるように外部サービスをうまく活用してアプリケーションを設計
    しよう
    49

    View Slide