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.4k
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
23
Firebase Cloud Messaging のベストプラクティス を、探している
gyarasu
1
1.8k
RESTful Firebase with Vue.js
gyarasu
1
360
Next.jsではじめるPWA
gyarasu
2
1.4k
副業時代のプロジェクトマネジメント
gyarasu
3
2.7k
PWA基礎_1
gyarasu
0
260
PWA基礎_2
gyarasu
0
160
PWA基礎_3
gyarasu
0
140
フロントエンドエンジニア (実稼働まで) ひとりでできるもん
gyarasu
0
2.4k
Other Decks in Technology
See All in Technology
MLOpsの「壁」を乗り越える、LINEヤフーの Data Quality as Code
lycorptech_jp
PRO
5
500
コンテナセキュリティの基本と脅威への対策
kyohmizu
3
760
On Your Data を超えていく!
hirotomotaguchi
2
670
Cloud Native Java with Spring Boot (CNCF Aarhus, April 2024)
thomasvitale
1
170
ゼロから始めるVue.jsコミュニティ貢献 / first-vuejs-community-contribution-link-and-motivation
lmi
1
120
複雑な構成要素を持つUIとの向き合い方 〜新・支出グラフでの実例〜 / B43 TECH TALK
nakamuuu
0
140
JSON攻略法.pdf
miyakemito
8
5k
長期間TiDBを使ってきた話 @ 私たちはなぜNewSQLを使うのかTiDB選定5社が語る選定理由と活用LT / Experiences with TiDB Over Time
chibiegg
2
890
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
2.1k
一生覚えておきたい「システム開発=コミュニケーション」〜初めての実務案件振り返りLT〜
maimyyym
0
130
Python と Snowflake はズッ友だょ!~ Snowflake の Python 関連機能をふりかえる ~
__allllllllez__
1
120
Google Cloud Next '24でブログを10本書いた方法と勉強会を沸かせた方法
yasumuusan
0
290
Featured
See All Featured
Being A Developer After 40
akosma
57
580k
How to Ace a Technical Interview
jacobian
272
22k
Fantastic passwords and where to find them - at NoRuKo
philnash
37
2.5k
Web development in the modern age
philhawksworth
202
10k
Principles of Awesome APIs and How to Build Them.
keavy
121
16k
Building Effective Engineering Teams - LeadDev
addyosmani
28
1.8k
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.6k
Gamification - CAS2011
davidbonilla
76
4.6k
Learning to Love Humans: Emotional Interface Design
aarron
267
39k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Adopting Sorbet at Scale
ufuk
68
8.6k
Building Adaptive Systems
keathley
31
1.9k
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.