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
MAUが1年で292%に成長した「aumoのおでかけ比較サイト」における取り組み
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
gree_tech
PRO
October 13, 2023
Technology
2.3k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
MAUが1年で292%に成長した「aumoのおでかけ比較サイト」における取り組み
GREE Tech Conference 2023で発表された資料です。
https://techcon.gree.jp/2023/session/TrackA-2
gree_tech
PRO
October 13, 2023
More Decks by gree_tech
See All by gree_tech
多彩なデータに負けないデータ分析パイプライン構築
gree_tech
PRO
0
24
AI駆動で挑むプロダクト刷新 ── アーキテクチャ設計とワークフロー最適化の実践事例 ──
gree_tech
PRO
0
21
『ヘブンバーンズレッド』のリグレッションテストにおけるストーリーの自動プレイ
gree_tech
PRO
0
23
REALITYにTAチームができるまでの軌跡〜ミッション:ガチャ本数5倍に対応せよ!〜
gree_tech
PRO
0
19
イベント続きでもミスらないライブサービスゲーム公式サイト運用システム開発
gree_tech
PRO
0
21
20年間 SNS サービス「GREE」 を支えた技術の刷新と、長期運用サービスの Kubernetes へのリアーキテクト
gree_tech
PRO
0
68
グラフ基盤ワークフローで実現するLLMによる自動ゲームプレイ
gree_tech
PRO
0
32
AIエージェントに脆弱性診断の仕事を奪われかけた ークローリングからコード全診断までの限界突破ー
gree_tech
PRO
0
29
アバター使っておもろいものを作り続けたい
gree_tech
PRO
0
24
Other Decks in Technology
See All in Technology
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
6
4.9k
re:Invent初参加で変わったこと、2回目にやってみたいこと(JAWS-UG彩の国埼玉 #12)
mhrtech
2
220
パッチ更新でterraform initが落ちた日
grimoh
1
140
Local CI × GitHub Actions
gogutan
2
190
Refining Active Record
shugo
0
150
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
110
「Docker Desktop不要の時代」は 来たのか?
ueponx
0
770
AIにシークレットを見せない、WSL2で安全な開発環境
yazm
0
300
AI時代のPRレビューにどう向き合うか?
kairim0
1
240
"優秀な誰か"の下位互換にならないために
yut0naga1_fa
1
1.8k
20261017福岡devIO 「AIは"良いダッシュボード"を作れるか?
jtakeda
0
140
大型犬好きによるPugの紹介
yamanoku
1
160
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
sira's awesome portfolio website redesign presentation
elsirapls
0
450
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
220
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
First, design no harm
axbom
PRO
2
1.3k
Side Projects
sachag
456
43k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.7k
Automating Front-end Workflow
addyosmani
1369
210k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
320
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
950
Transcript
MAUが1年で292%に成長した 「aumoのおでかけ比較サイト」 における取り組み アウモ株式会社 エンジニア 関谷恒甫 栗本拓弥
目次 • 発表者紹介 • aumoについて • フロントエンドをRailsのテンプレートエンジンからNuxt.jsに 移行した話 • フロントエンドにNGINXのリバースプロキシを設置してキャッ
シュを導入した話 • まとめ 2
自己紹介 3 • 名前:関谷恒甫 • 所属:アウモ株式会社 • 担当:メディアチームにおける開発全般 • 経歴:
◦ 2020年4月:グリーに新卒入社 ◦ 2020年4月:アウモに配属 ◦ 2020年6月:WFSに配属 ◦ 2021年12月:アウモに配属
自己紹介 • 名前:栗本拓弥 • 所属:アウモ株式会社 • 担当:メディアチームにおける開発全般 • 経歴: ◦
2022年4月:グリーに新卒入社 ◦ 2022年4月:アウモに配属 4
aumoについて
サービスの全体像
メディア事業
メディア事業の提供サービス
新規事業の取り組み
SaaS事業
SaaS事業の提供サービス
SaaS 事業の機能紹介
Fintech
Fintech事業の概要
マーケティングソリューション
マーケティングソリューションの概要
おでかけ比較サイトのフロントエンドを Railsのテンプレートエンジンから Nuxt.jsに移行した話 17
何をやったのか • aumo.jpの一覧ページ(例 aumo.jp/areas/241)のフロントエンドを、 Railsのテンプレートエンジン(slim)からNuxt.jsに移行した。 18
19 gourmet.aumo.jp aumo.jp なぜやるのか • aumoではaumo.jpドメインと3つのサブドメイン(gourmet.aumo.jp, leisure.aumo.jp, travel.aumo.jp)で一覧 ページを運営しています。
なぜやるのか (歴史的経緯のため)ドメインによって フロントエンドの実装が異なる • サブドメイン ◦ Nuxt.js • aumo.jp ◦
Railsテンプレートエンジン 20
なぜやるのか • 一覧ページを開発する際は基本的にドメイン4つ全てが開発の対象 ◦ サブドメインではNuxt.jsのコンポーネントを使い回すことができる が、aumo.jpドメインではそれらを使えないので、テンプレートエン ジンのコードも書く必要がある。。。 21
なぜやるのか • 一覧ページを開発する際は基本的にドメイン4つ全てが開発の対象 ◦ サブドメインではNuxt.jsのコンポーネントを使い回すことができる が、aumo.jpドメインではそれらを使えないので、テンプレートエン ジンのコードも書く必要がある。。。 22 2度手間!!!
移行の流れ ※アウモでは業務時間の1~2割程度を、各自がやりたい開発改善等の 時間に当てて良いということになってるので、その仕組みを今回は 利用しました。 23 1. アプリケーションコード変更 2. インフラ変更 3.
リリース
移行の流れ 1. アプリケーションコード変更 2. インフラ変更 3. リリース 24
アプリケーションコードの変更 • テンプレートエンジンのコードを、Nuxtに書き換える。 • 基本的には既存のNuxtのコンポーネントを使い回す。 • aumo.jpドメインのみに存在するUI等がある場合に、コンポーネントを新規 作成or修正。 • デザインが同じでもaumo.jpドメインとサブドメインで仕様が違う可能性があ
るので、コードを一つ一つ確認し差分があった場合は、PMと適時仕様をすり 合わせる。 25
移行の流れ 1. アプリケーションコード変更 2. インフラ変更 3. リリース 26
インフラの変更 • aumo.jpドメインには一覧ページ(https://aumo.jp/areas/241)だけで なく、記事ページ(https://aumo.jp/articles/145272)も存在する。 • 一覧ページへのアクセスのみをNuxtサーバに転送するように変更する必要 がある。 ◦ ALBのリスナールールを編集して、特定のパスパターン (例
/areas/*)の時のみリクエストを転送するように設定。 27
インフラ構成の変更 28 BEFORE
インフラ構成の変更 29 BEFORE AFTER
移行の流れ 1. アプリケーションコード変更 2. インフラ変更 3. リリース 30
リリース ここまでは順調だったが。。。 31
リリース1回目 レスポンス速度が悪化する 32
リリース1回目 レスポンス速度が悪化する 原因 • コード変更に伴い、リリースのタイミングでAPI側 で既存のキャッシュが使えなくなり、 Elasticsearchへのアクセスが増えて負荷が上 がった。 対策 •
元々Elasticsearchの負荷が高めだったので、 この機会にスケールアップを実施。 33
リリース2回目 相変わらずレスポンス速度が遅い状態が続く 34
リリース2回目 相変わらずレスポンス速度が遅い状態が続く 原因 • aumo.jpからリクエストが転送される分、Nuxtサーバへのリクエストが 増えたから? 対策 • サーバー台数を増やしてみる。 35
リリース3回目 相変わらずレスポンス速度が遅い状態が続く 36
リリース3回目 相変わらずレスポンス速度が遅い状態が続く 原因 • パフォーマンスチューニングをほとんど行っておらず、API側でN+1のク エリが複数発生していたから? 対策 • N+1のクエリをひたすら潰す。 37
リリース4回目 相変わらずレスポンス速度が遅い状態が続く 38
リリース4回目 相変わらずレスポンス速度が遅い状態が続く 原因 • 不明。何も思いつかず。 対策 • レスポンスが遅い原因が不明のままなので、問題を切り分けてみる。 • aumo.jpドメインのレスポンスのみが遅いのかサブドメインのレスポンス
も遅いのかを見分けるために、aumo.jpとサブドメインで使うコンテナを 分ける。 39
リリース5回目 aumo.jpドメインへのリクエストのみが遅く、 サブドメインへのリクエストは正常なことが判明 40
アクセスログの調査 アクセスログをよく見てみる • 最初の数分は問題なさそうだが、チラホラ遅い レスポンスが混ざっている。 • その後は全部のレスポンスが遅くなる。 • 遅いレスポンスをよく見ると、エリア番号が大き い傾向があることに気づく。
41
アクセスログの調査 アクセスログをよく見てみる • 最初の数分は問題なさそうだが、チラホラ遅い レスポンスが混ざっている。 • その後は全部のレスポンスが遅くなる。 • 遅いレスポンスをよく見ると、エリア番号が大き い傾向があることに気づく。
42
アクセスログの調査 43 アクセスログをよく見てみる • 最初の数分は問題なさそうだが、チラホラ遅い レスポンスが混ざっている。 • その後は全部のレスポンスが遅くなる。 • 遅いレスポンスをよく見ると、エリア番号が大き
い傾向があることに気づく。 エリア番号が関係してそうなコード を 探す。
問題のコード 44 computed: { targetAreaRegion () { return this.allRegions.find((region) =>
region.prefectures.some((pref) => pref.areas.some((area) => Number(area.id) === Number(this.targetArea) ) ) ) } } allRegions = [{ id: 1, name: '北海道・東北', prefectures: [{ id: 1, name: '北海道', areas: [{ id: 1, name: '札幌市' }, ...], }, ...] }, ...] ・allRegionsはregion->prefecture->areaという階層構造になっていて、階層構造を上か らiterateしていき、targetArea(例 札幌市)が属するregion(例 北海道・東北地方)を探す。 ・areaは全部で1600個程あるので、targetAreaが配列の後ろの方にある場合は探すのに 時間がかかる。 ・computedプロパティでキャッシュしてるので大丈夫だと思っていたが。。。
Nuxt.jsをSSRで利用する時の落とし穴 45 原因 • Nuxt.jsをSSRで利用する場合は、computedプロパティが キャッシュされない。 https://github.com/nuxt/nuxt/issues/2447 対策 • 計算が重い処理はcomputedプロパティではなく、storeに保存すること
で、レンダリング中に処理が走るのを1回だけにする。
リリース成功!!! 46 リリース6回目
学んだ点 • ログは超大事。生のアクセスログ、ALBのメトリクス、ECSのメトリクスなど色 んなログを見るべき。 • テストが充実してないと、リファクタリングのハードルが上がる。 • リファクタリングは辛いので、設計の段階でなるべく先まで見通して、リファクタ リングをそもそもしなくて済むようにできるのがベスト。 より詳細が知りたい方は、テックブログを見てください!
https://techblog.aumo.co.jp/articles/2233 47
おでかけ比較サイトのフロントエンドにNGINXのリ バースプロキシを設置して キャッシュを導入した話 48
何をやったのか • 一覧ページを表示しているNuxtサーバの前段に NGINXリバースプロキシを置いて、ページキャッシュを導入した。 49 既存の構成 リクエストが来るたび 大量のAPIを叩いていた リバプロ導入した構成 1回目のリクエストは
従来通り 2回目以降のリクエストは NGINXがキャッシュを返す
なぜやるのか • SEO対策として一覧ページのコンテンツをリッチにして、 MAUが大きく成長した! が、、 50 追加したコンテンツ例
なぜやるのか • SEO対策として一覧ページのコンテンツをリッチにして、 MAUが大きく成長した! が、、 51 追加したコンテンツ例 MAUの推移
なぜやるのか • しかし、ページがリッチになるにつれてレスポンス速度が遅くなってしまって いた 52
なぜやるのか レスポンス速度の悪化によりCoreWebVitalの指標が低下してしまった • CoreWebVitalとは ◦ Googleが定めるWebサイトのUXを測る重要な指標のこと。 ◦ PageSpeed Insightsというサイトで誰でも計測できる •
CoreWebVitalの主な指標 ◦ Time to First Byte (TTFB): ▪ レスポンスの最初のByteが返るまでの時間 ◦ First Contentful Paint (FCP): ▪ 視覚コンテンツの初期表示時間 ◦ Largest Contentful Paint (LCP): ▪ 最大コンテンツの表示時間 53
なぜやるのか 54 • CoreWebVitalが不合格だらけなので、これを改善することで、 MAUがさらに成長するかもしれない
なぜやるのか 55 • CoreWebVitalが不合格だらけなので、これを改善することで、 MAUがさらに成長するかもしれない ちくしょう。 速度改善だ!
なぜやるのか • 今後コンテンツがさらにリッチになっても、レスポンス速度の悪化を招かな いようにしたい。 • Nuxtのレスポンスを丸々キャッシュする「ページキャッシュ」を 導入すると、キャッシュ済みページへのアクセスは一瞬で返せる。 56
なぜやるのか • 今後コンテンツがさらにリッチになっても、レスポンス速度の悪化を招かな いようにしたい。 • Nuxtのレスポンスを丸々キャッシュする「ページキャッシュ」を 導入すると、キャッシュ済みページへのアクセスは一瞬で返せる。 57 ちくしょう。 ページキャッシュだ!
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 3. リリース 58
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 3. リリース 59
NGINXリバースプロキシ設置 - インフラ構成 - BEFORE
NGINXリバースプロキシ設置 - インフラ構成 - 61 BEFORE AFTER
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 3. リリース 62
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 1. 数千件の特定URLをキャッシュする 2. SPとPCでキャッシュを分ける 3.
リリース 63
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 1. 数千件の特定URLをキャッシュする 2. SPとPCでキャッシュを分ける 3.
リリース 64
NGINXでページキャッシュ導入 65 要件1 • 数千件の特定URLをキャッシュする 対応 • mapディレクティブで対象パスを制限 ◦ 条件分岐というとif文が頭に浮かびますが、NGINXではif文は邪悪と言わ
れておりなるべく使わないべきとされています。 そこで、mapディレクティブで条件分岐を行うようにしました。
NGINXでページキャッシュ導入 66 • mapディレクティブで対象パスを制限 map $host$request_uri $is_target_path { default 0;
include /etc/nginx/cache_target_path.map; } aumo.jp/prefectures/13/scenes/8 1; aumo.jp/prefectures/27/categories/a12 1; gourmet.aumo.jp/areas/466/categories/a15 1; /etc/nginx/cache_target_path.map
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 1. 数千件の特定URLをキャッシュする 2. SPとPCでキャッシュを分ける 3.
リリース 67
NGINXでページキャッシュ導入 68 要件2 • SPとPCでキャッシュを分ける 対応 • キャッシュキーにPCかSPかの情報を含める
NGINXでページキャッシュ導入 69 • キャッシュキーにPCかSPかの情報を含める ◦ PCかSPかの情報をもつ$deviceをmapディレクティブで用意する ◦ キャッシュキー(proxy_cache_key)に$deviceを加える ▪ キャッシュキーの例:aumo.jp/areas/13:sp
location / { ...... proxy_cache_key $host$uri:$device; ...... }
ページキャッシュ導入の流れ 1. NGINXリバースプロキシ設置 2. NGINXでページキャッシュ導入 3. リリース 70
リリース後の効果計測 71 • レスポンス速度 ◦ 0.00秒でレスポンスを返している!
72 • CoreWebVital指標 ◦ 合格!! リリース後の効果計測 指標 定義 キャッシュ前 目標値
キャッシュ後 全体 不合格 合格 合格 LCP メインコンテンツの読み込み速度 4.3s 2.5s 1.7s FID 操作を行ってから応答が発生するま での遅延時間 489ms 100ms なし CLS 読み込み時のレイアウトのずれ 0 0 0 TTFB サーバー初期応答時間 2.8s 0.8s 0.5s FCP 視覚コンテンツの初期表示時間 3.7s 1.8s 1.3s INP コンテンツの反応速度 3,943ms 200ms 2,263ms
73 • MAU ◦ MAUが成長! リリース後の効果計測
キャッシュについてのまとめ 74 • 速度改善にも種類がある ◦ バックエンド: DBアクセスのキャッシュ、N+1 ◦ フロントエンド: ページキャッシュ、CDN
• ページキャッシュを導入すれば、ページがリッチになってもレスポンス速度が速 いまま変化しない より詳細が知りたい方は、テックブログを見てください! https://techblog.aumo.co.jp/articles/2278
このセッションのまとめ 75 • フロントエンドをRailsのテンプレートエンジンからNuxt.jsに移行することで 開発工数削減ができた。 • フロントエンドにNGINXのリバースプロキシを設置してキャッシュを導入する ことでレスポンス速度の改善ができた。 • これからもサービスの質を高めて、より多くの人に使ってもらえるサービスに成
長させていきます!
ご成長(静聴)ありがとうございました! 76
77