Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
doda AIジョブサーチ PWAとパフォーマンスの話
Search
gyarasu
May 22, 2019
Technology
0
1.6k
doda AIジョブサーチ PWAとパフォーマンスの話
2019.05.22
『#2 フロントエンド技術交流〜新サービスの裏側初公開+LT枠』 の登壇資料です。
https://tech-lounge.connpass.com/event/122454/
gyarasu
May 22, 2019
Tweet
Share
More Decks by gyarasu
See All by gyarasu
QAエンジニア組織立ち上げはじめの一歩
gyarasu
0
34
Firebase Cloud Messaging のベストプラクティス を、探している
gyarasu
1
2.4k
RESTful Firebase with Vue.js
gyarasu
1
390
Next.jsではじめるPWA
gyarasu
2
1.5k
副業時代のプロジェクトマネジメント
gyarasu
3
2.8k
PWA基礎_1
gyarasu
0
290
PWA基礎_2
gyarasu
0
170
PWA基礎_3
gyarasu
0
150
フロントエンドエンジニア (実稼働まで) ひとりでできるもん
gyarasu
0
2.5k
Other Decks in Technology
See All in Technology
Platform Engineering for Software Developers and Architects
syntasso
1
520
安心してください、日本語使えますよ―Ubuntu日本語Remix提供休止に寄せて― 2024-11-17
nobutomurata
1
990
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
430
【若手エンジニア応援LT会】ソフトウェアを学んできた私がインフラエンジニアを目指した理由
kazushi_ohata
0
150
データプロダクトの定義からはじめる、データコントラクト駆動なデータ基盤
chanyou0311
2
310
これまでの計測・開発・デプロイ方法全部見せます! / Findy ISUCON 2024-11-14
tohutohu
3
370
第1回 国土交通省 データコンペ参加者向け勉強会③- Snowflake x estie編 -
estie
0
130
適材適所の技術選定 〜GraphQL・REST API・tRPC〜 / Optimal Technology Selection
kakehashi
1
170
個人でもIAM Identity Centerを使おう!(アクセス管理編)
ryder472
3
200
スクラム成熟度セルフチェックツールを作って得た学びとその活用法
coincheck_recruit
1
140
AWS Media Services 最新サービスアップデート 2024
eijikominami
0
200
AWS Lambda のトラブルシュートをしていて思うこと
kazzpapa3
2
170
Featured
See All Featured
A better future with KSS
kneath
238
17k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Docker and Python
trallard
40
3.1k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
506
140k
GraphQLとの向き合い方2022年版
quramy
43
13k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
Designing the Hi-DPI Web
ddemaree
280
34k
Ruby is Unlike a Banana
tanoku
97
11k
Transcript
doda AIジョブサーチ PWAとパフォーマンスの話 Copyright © PERSOL CAREER Co., Ltd. All
Rights Reserved. パーソルキャリア株式会社 サービス開発本部 吉次洋毅 2019/11/12
誰︖ • 吉次 洋毅(ヨシツグ ヒロキ) • 1991年⽣まれ(27歳) • 徳⼭⾼専 専攻科修了
• 経歴 – 某レストラン検索サイトでバックエンドエンジニアなど – パーソルキャリアでエンジニアをしつつ フリーランスで受託開発 & 他社さんの開発やプロジェクトマネジメントのお⼿伝い • 趣味 – ⼀⼈旅&写真&スーパー銭湯 – スマブラ(VIPに⾏けそうで⾏けない) – 筋トレ(予定) • 最近触っている技術 – Javascript(Nuxt.js / Express.js) – PWA – AWS / GCP Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
今⽇のお話と⽬標 1. パーソルキャリア初のPWA『doda AIジョブサーチ』のご紹介 → 前置きです 2. NuxtベースでPWAを作った話 →「これからPWA作ってみよう」という⼈向け。 3.
パフォーマンスの計測と改善をした話 →Nuxtアプリケーション/PWAのフロントエンドのパフォーマンスが気になる⼈向け Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
スライドは後ほど公開します︕ connpassでお知らせします Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
doda AIジョブサーチの ご紹介 Copyright © PERSOL CAREER Co., Ltd. All
Rights Reserved.
パーソルキャリア初のPWA︕ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
https://doda.jp/AiJobSearch/ ※現時点でスマホ対応のみ • 「イマイチ⾃分に合った検索条件が わからない」、「じっくり転職サイ トを使う時間がない」そんな⼈に向 けた新サービス • 検索ナシ︕ • 希望条件を⼊れて、出てきた求⼈に 対する興味の有無を選ぶだけ︕ • ⽇々賢くなってイイカンジのレコメ ンドをしてくれる というコンセプト 今は最適化されていないので精度よくない 現在内製の機械学習エンジンを鋭意開発中
使い⽅ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
希望条件 の設定 求⼈の振 り分け いい感じ のレコメ ンド⽣成 求⼈への 応募
DEMO Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
転職しようかな〜と思っていて 気になった⽅は是⾮使ってみてください︕ Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved. ※doda会員登録が必要なので、登録後にいろいろ メールが来たり電話がかかってきたりしますのでご 了承くださいm(_ _)m
NuxtベースでPWAを作った話 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
Nuxt.jsを使っている︖ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
PWAを作っている or 作ったことがある︖ Copyright © PERSOL CAREER Co., Ltd. All
Rights Reserved.
Vue.js×PWAの概観 • 『Vue.jsで始めるPWA』で検索︕(⼀部最新化出来てませんmm) – https://qiita.com/gyarasu/items/2f18edc4ae251180d89e • PWAでできること – ホームスクリーンへの追加(Add to
Home Screen) – キャッシュ(Service Worker Caching) – プッシュ通知(Push Notification) – バックグラウンド同期(Background Sync) • 気になる制約(iOS12 Safari) – 未対応のAPI • Web Push • Background Sync – 参考: 『Whatʼs new on iOS 12.2 for Progressive Web Apps』 • https://medium.com/@firt/whats-new-on-ios-12-2-for-progressive-web- apps-75c348f8e945 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
PWAとして何から始める︖ • ホームスクリーンへの追加(A2HS) • キャッシュ(Service Worker Caching) • プッシュ通知(Push Notification)
• バックグラウンド同期(Background Sync) Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. まずは取っ掛かりやすいところから︕ ※ただし、iOS SafariでのA2HSはcookieの扱いが 微妙かも…あとプロンプトが出ないので⼿動。
NuxtアプリケーションをPWA化しよう Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
https://github.com/nuxt-community/pwa-module ちょっとだけcontributeしてます
pwa-moduleの導⼊ 1. npmパッケージのインストール 2. nuxt.config.jsのmodulesに追加 3. .gitignoreにsw.*(=Service Workerのスクリプト)を追加 ※不要なmoduleは除外できます Copyright
© PERSOL CAREER Co., Ltd. All Rights Reserved.
A2HSの設定 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
ウェブアプリマニフェスト(manifest.json)に書 くべき内容をそのままnuxt.config.jsに記載すれば OK https://developers.google.com/web/fundamentals/web-app-manifest/?hl=ja
Workboxの設定 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
workboxの設定もnuxt.config.jsに記述
Service Worker Cacheについて • Service WorkerによるCacheは2種類 – Pre Cache –
Runtime Cache • Pre Cache – 静的なアセットをキャッシュする • nuxt buildしたときのバンドルファイル – Workboxモジュールが有効化されていれば⾃動的にやってくれる • Runtime Cache – 動的なHTTPリクエストをキャッシュする – フロントエンドから⾮同期で呼び出すAPI • Runtime Cacheの戦略 – リソースの特性(更新頻度など)に応じて戦略や保持する期間を設定する – https://speakerdeck.com/gyarasu/pwaji-chu-3?slide=7 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. v3で挙動変わったかも 調査中
Service Workerライフサイクル Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved. これ、何︖
Service Workerライフサイクル • https://developer.mozilla.org/ja/docs/Web/API/ServiceWorker_API /Using_Service_Workers • skipWaiting – “Use self.skipWaiting()
anytime before activation to skip installed stage and directly jump to activating stage without waiting for currently controlled clients to close.” – すでにページをコントロールしているSWがある場合も、waitingをスキップしてactive に移⾏する(SWを新しいものに上書きする) • clientsClaim – “Use self.clients.claim() in the active handler to start controlling all open clients without reloading them.” – SWがページをコントロールするようになるのは、activate後に再度ページが読み込まれ たタイミング。初回のページロードのタイミングでコントロールを開始する。 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
【まとめ】 NuxtのWebアプリをPWA化するのはとっても簡単︕ Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
doda AIジョブサーチ パフォーマンス改善の歴史 Copyright © PERSOL CAREER Co., Ltd. All
Rights Reserved.
Performance Audit Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved. ※Simulated Fast3GでのAudit
これって良いの︖ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
パフォーマンスの良し/悪しの観点 • 基本的には、スコアが⾼いほど良いと思っておく – パフォーマンスはUXやコンバージョンに⼤きく貢献する • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない… –
例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒… Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
パフォーマンスの良し/悪しの観点 • 基本的には、スコアが⾼いほど良いと思っておく – パフォーマンスはUXやコンバージョンに⼤きく貢献する • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない… –
例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒… Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. 読み込み時間が0.1秒減ると、売上が1%増加 by amazon.com
パフォーマンスの良し/悪しの観点 • 基本的には、スコアが⾼いほど良いと思っておく – パフォーマンスはUXやコンバージョンに⼤きく貢献する • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない… –
例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒… Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. (パフォーマンス)×(本来提供したい価値)の最⼤化を⽬ 指すのが基本的な指針
Lighthouseで確認できるパフォーマンス指標 • First Contentful Paint – 初回のテキストもしくは画像が表⽰されるまでにかかった時間 • First Meaningful
Paint – 主要コンテンツが表⽰されるまでにかかった時間 • Speed Index – ページのコンテンツが⽬に⾒える状態になるまでにかかった時間 • First CPU Idle – メインスレッドでの処理が終わってCPUがアイドル状態になるまでにかかった時間 • Time to Interactive – ユーザ操作が可能になるまでにかかった時間 • Estimated Input Latency – ユーザの⼊⼒に対するアプリの応答速度 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
Lighthouseのまとめ情報 • 『Lighthouse によるウェブアプリの監査』で検索 – https://developers.google.com/web/tools/lighthouse/ Copyright © PERSOL CAREER
Co., Ltd. All Rights Reserved.
開発途中に計測したもともとの姿… Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
しかも、本来出したいコンテンツも完全に⼊ってない状態…
どれだけ良くなった︖ 4.3 5.9 5.4 5.9 16.7 3.8 3.8 4.3 5
5.8 0 2 4 6 8 10 12 14 16 18 First Contentful Paint First Meaningful Paint Speed Index First CPU Idle Time to Interactive ms パフォーマンス指標の⽐較 Before After Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
開発過程でコンテンツのリッチ化と パフォーマンスの改善を両⽴出来た︕ Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
パフォーマンス改善でやったこと • バンドルサイズの縮⼩ • 画像の遅延ロード • 必要なリソースのみ読み込み(計測タグ関連) • APIレスポンスの圧縮 •
CDNの利⽤ • 計測対象画⾯のAPIリクエストの最適化 などなど Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
バンドルサイズの縮⼩ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
• Nuxtでは、内包されいてるwebpack-bundle-analyzerを使ってバンドル サイズを可視化することができる • やり⽅は簡単。nuxt.config.jsでbuild.analyzeをtrueで指定してあげる – https://ja.nuxtjs.org/api/configuration-build/#analyze • UIライブラリとしてVuetifyでA-la-carteを利⽤していたが、使⽤するコ ンポーネントやディレクティブのみ読み込むように変更した – https://ja.nuxtjs.org/api/configuration-build/#analyze 1.4MB → 556KB
A-la-carteの罠…︖ • Vuetify⾃体のサイズは⼩さくなったが、pagesのファイルが少しずつ⼤き くなってしまった… • 全体としては30KBの削減にとどまった • pagesのファイル数が増えるとVuetifyを全部読み込む場合よりもむしろ全 体のバンドルサイズが⼤きくなってしまうかも…︖ Copyright
© PERSOL CAREER Co., Ltd. All Rights Reserved. 特定のライブラリを⼩さくする場合に副作⽤がある可能性も 考えておくのが良い。 ご存知の⽅いらっしゃいましたらご教⽰くださいm(_ _)m
画像の遅延ロード • vue-lazyloadを使ってファーストビューに含まれない画像は遅延ロード – https://github.com/hilongjw/vue-lazyload Copyright © PERSOL CAREER Co.,
Ltd. All Rights Reserved. 横スクロールしたら初めて⾒える ようになる画像は遅延ロードする (3枚⽬以降)
必要なリソースのみ読み込み(計測タグ関連) • doda AI JobSearch(https://doda.jp/AiJobSearch/)はdoda (https://doda.jp/)の括りに含まれるサービス • ⼀⽅でAI JobSearchはターゲットを絞って運⽤しており、dodaで導⼊し ている広告タグや各種ツール系のタグ等は不要。
• GTMでそれらを設定しているが、AI Job Search側では読み込みたくない ので、GTMのコンテナを分け、必要最低限のタグのみを設定することで対 応。 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
APIレスポンスの圧縮 • 求⼈情報を取得するためのAPIのレスポンスに、多くの情報を含めている のでレスポンスサイズが⼤きくなってしまっていた • バックエンドのAPIサーバは現在Express.jsで構築しているので、 compressionを使⽤して、APIレスポンスをgzip圧縮した。 – https://github.com/expressjs/compression –
levelの設定は6(=デフォルト)くらいで圧縮率が頭打ちになったので6にした • 20件程度の求⼈情報を含むAPIのレスポンス • 求⼈⼀覧表⽰⽤と、詳細表⽰⽤でエンドポイントを分けて最適化するよう な対応は別途検討する必要がある Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. 192KB → 59KB
CDNの利⽤ • バンドルファイルや求⼈画像の静的アセットはCDNに置く • dodaではAkamaiを利⽤中 • CDNの恩恵 – 距離が近くなる(dodaの場合国内向けサービスなのでそこまで恩恵はないかも) –
デバイスに最適化した画像の配信 – トラフィック分散 – 可⽤性の向上 • Nuxt.config.jsのbuild.publicPathにCDNのURLを指定すると、nuxt build実⾏後、クライアント側のバンドルファイルをCDNをアップロード する – https://ja.nuxtjs.org/api/configuration-build/#publicpath Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
PWAでCDNを使うときの注意点 • CDNにクロスオリジンでアクセスする場合は要注意 • Service WorkerからCDNにアクセスできない問題が発⽣する • 『Nuxt × PWA
× CDNでハマった件について』 – https://qiita.com/gyarasu/items/005e4c74fa166d048dbe – scriptタグのsrc属性でのクロスオリジン指定はOK(HTML5の仕様) – Service Workerは内部的にjsによってHTTPリクエストを⾶ばしているので、この部分 で引っかかる Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
APIリクエストの最適化 • 計測対象画⾯では初期表⽰時に複数のAPI を呼び出している – いいねサマリ取得API – Yes/Noチェック⽤の求⼈リスト取得API – レコメンドリスト取得API×2
計4リクエスト • レンダリングは2種類 – SSR: URLに直接アクセスした場合 – CSR: 画⾯下部のタブを押した場合(router.push で移動したとき) • 改善ポイントは2つ – 並列に複数のAPIを呼び出す – SSR/CSRそれぞれに合わせたデータの取得⽅法 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
APIリクエストの最適化 • もともとは、mounted()内で直列にAPIを呼び出していた – SSR時にコンテンツが⼊った状態で表⽰されない – クライアントサイドでマウントされたあとにAPI呼び出して結果を表⽰するまで待つ必要 がある • fetchの活⽤で解決
– モチベーションは「SSR時にコンテンツを⼊れた状態で表⽰したい」 →レンダリングされる前にデータをストアに⼊れる必要がある – https://ja.nuxtjs.org/api/pages-fetch/ • 複数APIを並列実⾏ – API呼び出しはvuexのactionsに書いているので、actionsの関数はPromiseを返却する ようにする – 必要なAPI分Promiseを⽣成し、Promise.allで並列実⾏ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
APIリクエストの最適化 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
SSR時に表⽰されない…︕ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
“fetch メソッドを⾮同期にするためには Promise を返却し てください。そうすれば nuxt.js はコンポーネントがレンダリ ングされる前に promise が解決されるまで待機します。”
Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
“fetch メソッドを⾮同期にするためには Promise を返却し てください。そうすれば nuxt.js はコンポーネントがレンダリ ングされる前に promise が解決されるまで待機します。”
Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. SSR時にPromiseの解決を待たずに画⾯を返してしまう = コンテンツ部分が空になってしまう
APIリクエストの最適化 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
Promise返してみた。
SSR時に表⽰されるようになった︕ Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
でもタブで切り替えしたとき(CSR)に 引っかかりが⽣じてしまうようになった… Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
“fetch メソッドを⾮同期にするためには Promise を返却し てください。そうすれば nuxt.js はコンポーネントがレンダリ ングされる前に promise が解決されるまで待機します。”
Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved. CSR時にもPromiseが解決されるまで待機してしまう
CRS時はPromiseの解決を待たずに とにかく画⾯を切り替えたい Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
CRS時はPromiseの解決を待たずに とにかく画⾯を切り替えたい Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved. 快適なインタラクションを優先したい
【解決策】 SSRとCSRで処理を分ける Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
SSR/CSRに応じたfetch最適化 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
その他TIPS • ChromeのAuditでパフォーマンス測定する場合はシークレットモードで ⾏う。通常のモードで⾏うと、インストールしているChrome拡張が邪魔 して、スコアに影響することがある。 – 実⾏後にこれが出てたら要注意。シークレットモードでやり直そう。 Copyright © PERSOL
CAREER Co., Ltd. All Rights Reserved.
今後のパフォーマンス関連の展望 • 定期的にパフォーマンスを計測する仕組みづくり – バンドルファイルサイズの可視化をCI/CDに組み込む – フロントエンドの各指標を可視化する仕組みづくり Copyright © PERSOL
CAREER Co., Ltd. All Rights Reserved.
最後に1つだけ… Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
パーソルキャリアでは ⼀緒に働く仲間を募集しています︕ Copyright © PERSOL CAREER Co., Ltd. All Rights
Reserved.
終 Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.