Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Findy TECH BATON 2025 11 27 nirila
Search
nirila
November 27, 2025
15
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Findy TECH BATON 2025 11 27 nirila
https://findy.connpass.com/event/375098/
nirila
November 27, 2025
Featured
See All Featured
Embracing the Ebb and Flow
colly
88
5.2k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
How to build a perfect <img>
jonoalderson
1
6.1k
Raft: Consensus for Rubyists
vanstee
142
7.8k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
410
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
For a Future-Friendly Web
brad_frost
184
10k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Design in an AI World
tapps
1
350
Transcript
リアクション機能実装するぞ! ~ パフォーマンス改善の実践 ~ 👍 ❤ 🐫 🙇 ✅ 💤
😊 😿 🐡 🍕 🐄
2 自己紹介 • 25新卒エンジニア • 趣味 ◦ 開発 (Unity, C#,
Go, Ruby, ...) ◦ VRChat ◦ Misskey nirila (にりら) BOOTH バックエンドエンジニア Kubernetesが熱い(何も分からない)
ほんぺん
創作でつながる クリエイターズマーケット BOOTHについて
メッセージに対し 絵文字でリアクションできる 機能を作ろう!
リアクション機能
要件決め
• 会話一覧で最新のメッセージ・リアクションを表示する • 更新順に会話一覧を並び替える • 一部のメッセージに対してリアクションできないようにする ◦ 一斉送信 • 通知を送信する
要件(一部) ・・・ 他多数
• 会話一覧で最新のメッセージ・リアクションを表示する • 更新順に会話一覧を並び替える • 一部のメッセージに対してリアクションできないようにする ◦ 一斉送信 • 通知を送信する
要件(一部) ・・・ 他多数
🛒ショップから見た時 👶ユーザーから見た時 会話一覧で最新のメッセージ・リアクションを表示する
✅リアクションを実装する✅
• 一つのconversationに複数メッセージ 現状のテーブル構造 conversation conversation conversation message message message message
message message message message message 会話グループ
• messageに紐づく形でreactionテーブルを追加 リアクション実装 conversation message message message リアクション reaction リアクション
reaction リアクション reaction conversationで2000万レコードのマイグレーションが必要だったため大変(割愛)
• 会話一覧で最新のメッセージとリアクションを表示 リアクション実装 conversation message message message リアクション reaction リアクション
reaction リアクション reaction それぞれの会話で最新の内容がわかるように
リアクション実装 リアクションできた~!!!!!
あれ、会話一覧の様子が...
あれ、会話一覧の様子が... 💥
会話一覧のパフォーマンスが悪い
それぞれの会話毎に最新のメッセージとリアクションを表示したい 会話一覧のパフォーマンスが悪い
• 最新のリアクションを表示するには ◦ 3つのテーブルをつなげないといけない 会話一覧のパフォーマンスが悪い 素直に実装するとN+1が発生する conversation message reaction
N+1対策が必須
1. preloadを利用する 2. 複数のクエリに分割する N+1の解決策
• rails標準的な書き方ができる • わかりやすい preloadを利用した解決
✅最新のメッセージとリアクション欲しい!✅ preloadを利用した解決 実際改善するの? @conversations.preload(:messages, reactions: :message) 👉メッセージをまずpreloadして... 👉次にreactionもpreload! そういえばreactionに紐づいてるメッセージも必要だ...💭
✅最新のメッセージとリアクション欲しい!✅ preloadを利用した解決 実際改善するの? @conversations.preload(:messages, reactions: :message) 👉メッセージをまずpreloadして... 👉次にreactionもpreload! そういえばreactionに紐づいてるメッセージも必要だ...💭 preloadで解決!
と思ったらパフォーマンスが!
• rails標準的な書き方ができる • わかりやすい • 実データと同規模データで検証した所、パフォーマンスが悪化 • 不要なデータを読み込んでしまう preloadを利用した解決 大量のレコードを読むことに
• 会話一覧を取得、これを元に他のデータを取得 複数のクエリに分割
• データ取得をいくつかのステップに分ける a. conversation 一覧を取得 b. 会話内での最新メッセージを取得 c. 会話内での最新リアクションを取得 •
それぞれidが最大のものを取得 複数のクエリに分割
• 不要なデータを読み込まないように 複数のクエリに分割 クエリを分割することでパフォーマンス問題を解決 実装 実行時間 発行クエリ数 N+1実装 579.29ms 76
最適化後 64.38ms 22 複数クエリに分けた場合の性能 88.9%削減 71.1%削減
⚠しかし可読性などの面で別の課題が発生⚠ 複数のクエリに分割
controllerとviewの間に取得用のレイヤを追加 複雑なコードを分離 複数のクエリに分割 ユニットテストがしやすく! ⚠しかし可読性などの面で別の課題が発生⚠
複数クエリへの分割を採用
ほかに選択肢あったんじゃない?
他の選択肢:会話ごとのデータを拡充 会話ごとの最新のメッセージ・リアクションのIDを あらかじめDBに保存 N+1も複雑なクエリも不要!
N+1も複雑なクエリも不要! 他の選択肢:会話ごとのデータを拡充 会話ごとの最新のメッセージ・リアクションのIDを あらかじめDBに保存 • マイグレーションがさらに大規模 • 工数の都合で見送り
• 一見正しそうな解決策に見えるが落とし穴も ◦ preloadが返って遅くなる場合が存在 • クエリ分割による回避も可能だが、代わりにコードが複雑 • 設計段階で見通しを完全に立てることは難しい ◦ 仮実装であらかじめパフォーマンスは確認すべき
学び
ご清聴ありがとうございました
付録
• 環境によって絵文字の見え方が違う 環境による見え方の違い 🐫😊🐄🙇💤👍 フォント 画像
• ユーザー同士のメッセージをまとめたスレッドのようなもの conversationとは
• ページネーションするので20個まで読み込み • 一つのconversationに3000件のメッセージが含まれる場合も conversationやmessageの数