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

doda AIジョブサーチ PWAとパフォーマンスの話

gyarasu
May 22, 2019

doda AIジョブサーチ PWAとパフォーマンスの話

2019.05.22
『#2 フロントエンド技術交流〜新サービスの裏側初公開+LT枠』 の登壇資料です。
https://tech-lounge.connpass.com/event/122454/

gyarasu

May 22, 2019
Tweet

More Decks by gyarasu

Other Decks in Technology

Transcript

  1. doda AIジョブサーチ
    PWAとパフォーマンスの話
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    パーソルキャリア株式会社
    サービス開発本部
    吉次洋毅
    2019/11/12

    View Slide

  2. 誰︖
    • 吉次 洋毅(ヨシツグ ヒロキ)
    • 1991年⽣まれ(27歳)
    • 徳⼭⾼専 専攻科修了
    • 経歴
    – 某レストラン検索サイトでバックエンドエンジニアなど
    – パーソルキャリアでエンジニアをしつつ
    フリーランスで受託開発 & 他社さんの開発やプロジェクトマネジメントのお⼿伝い
    • 趣味
    – ⼀⼈旅&写真&スーパー銭湯
    – スマブラ(VIPに⾏けそうで⾏けない)
    – 筋トレ(予定)
    • 最近触っている技術
    – Javascript(Nuxt.js / Express.js)
    – PWA
    – AWS / GCP
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  3. 今⽇のお話と⽬標
    1. パーソルキャリア初のPWA『doda AIジョブサーチ』のご紹介
    → 前置きです
    2. NuxtベースでPWAを作った話
    →「これからPWA作ってみよう」という⼈向け。
    3. パフォーマンスの計測と改善をした話
    →Nuxtアプリケーション/PWAのフロントエンドのパフォーマンスが気になる⼈向け
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  4. スライドは後ほど公開します︕
    connpassでお知らせします
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  5. doda AIジョブサーチの
    ご紹介
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  6. パーソルキャリア初のPWA︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    https://doda.jp/AiJobSearch/
    ※現時点でスマホ対応のみ
    • 「イマイチ⾃分に合った検索条件が
    わからない」、「じっくり転職サイ
    トを使う時間がない」そんな⼈に向
    けた新サービス
    • 検索ナシ︕
    • 希望条件を⼊れて、出てきた求⼈に
    対する興味の有無を選ぶだけ︕
    • ⽇々賢くなってイイカンジのレコメ
    ンドをしてくれる
    というコンセプト
    今は最適化されていないので精度よくない
    現在内製の機械学習エンジンを鋭意開発中

    View Slide

  7. 使い⽅
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    希望条件
    の設定
    求⼈の振
    り分け
    いい感じ
    のレコメ
    ンド⽣成
    求⼈への
    応募

    View Slide

  8. DEMO
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  9. 転職しようかな〜と思っていて
    気になった⽅は是⾮使ってみてください︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    ※doda会員登録が必要なので、登録後にいろいろ
    メールが来たり電話がかかってきたりしますのでご
    了承くださいm(_ _)m

    View Slide

  10. NuxtベースでPWAを作った話
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  11. Nuxt.jsを使っている︖
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  12. PWAを作っている or 作ったことがある︖
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  13. 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.

    View Slide

  14. PWAとして何から始める︖
    • ホームスクリーンへの追加(A2HS)
    • キャッシュ(Service Worker Caching)
    • プッシュ通知(Push Notification)
    • バックグラウンド同期(Background Sync)
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    まずは取っ掛かりやすいところから︕
    ※ただし、iOS SafariでのA2HSはcookieの扱いが
    微妙かも…あとプロンプトが出ないので⼿動。

    View Slide

  15. NuxtアプリケーションをPWA化しよう
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    https://github.com/nuxt-community/pwa-module
    ちょっとだけcontributeしてます

    View Slide

  16. pwa-moduleの導⼊
    1. npmパッケージのインストール
    2. nuxt.config.jsのmodulesに追加
    3. .gitignoreにsw.*(=Service Workerのスクリプト)を追加
    ※不要なmoduleは除外できます
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  17. 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

    View Slide

  18. Workboxの設定
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    workboxの設定もnuxt.config.jsに記述

    View Slide

  19. 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で挙動変わったかも
    調査中

    View Slide

  20. Service Workerライフサイクル
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    これ、何︖

    View Slide

  21. 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.

    View Slide

  22. 【まとめ】
    NuxtのWebアプリをPWA化するのはとっても簡単︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  23. doda AIジョブサーチ
    パフォーマンス改善の歴史
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  24. Performance Audit
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    ※Simulated Fast3GでのAudit

    View Slide

  25. これって良いの︖
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  26. パフォーマンスの良し/悪しの観点
    • 基本的には、スコアが⾼いほど良いと思っておく
    – パフォーマンスはUXやコンバージョンに⼤きく貢献する
    • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする
    – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない…
    – 例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  27. パフォーマンスの良し/悪しの観点
    • 基本的には、スコアが⾼いほど良いと思っておく
    – パフォーマンスはUXやコンバージョンに⼤きく貢献する
    • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする
    – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない…
    – 例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    読み込み時間が0.1秒減ると、売上が1%増加
    by amazon.com

    View Slide

  28. パフォーマンスの良し/悪しの観点
    • 基本的には、スコアが⾼いほど良いと思っておく
    – パフォーマンスはUXやコンバージョンに⼤きく貢献する
    • ⼀⽅で、本来Webサービスが提供すべき価値を忘れないようにする
    – 実際には、スコアが⾼ければ⾼いほど良いとは⼀概には⾔えない…
    – 例えば、スコアを伸ばすために本来に必要なコンテンツを削ったりしたら本末転倒…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    (パフォーマンス)×(本来提供したい価値)の最⼤化を⽬
    指すのが基本的な指針

    View Slide

  29. 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.

    View Slide

  30. Lighthouseのまとめ情報
    • 『Lighthouse によるウェブアプリの監査』で検索
    – https://developers.google.com/web/tools/lighthouse/
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  31. 開発途中に計測したもともとの姿…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    しかも、本来出したいコンテンツも完全に⼊ってない状態…

    View Slide

  32. どれだけ良くなった︖
    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.

    View Slide

  33. 開発過程でコンテンツのリッチ化と
    パフォーマンスの改善を両⽴出来た︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  34. パフォーマンス改善でやったこと
    • バンドルサイズの縮⼩
    • 画像の遅延ロード
    • 必要なリソースのみ読み込み(計測タグ関連)
    • APIレスポンスの圧縮
    • CDNの利⽤
    • 計測対象画⾯のAPIリクエストの最適化
    などなど
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  35. バンドルサイズの縮⼩
    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

    View Slide

  36. A-la-carteの罠…︖
    • Vuetify⾃体のサイズは⼩さくなったが、pagesのファイルが少しずつ⼤き
    くなってしまった…
    • 全体としては30KBの削減にとどまった
    • pagesのファイル数が増えるとVuetifyを全部読み込む場合よりもむしろ全
    体のバンドルサイズが⼤きくなってしまうかも…︖
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    特定のライブラリを⼩さくする場合に副作⽤がある可能性も
    考えておくのが良い。
    ご存知の⽅いらっしゃいましたらご教⽰くださいm(_ _)m

    View Slide

  37. 画像の遅延ロード
    • vue-lazyloadを使ってファーストビューに含まれない画像は遅延ロード
    – https://github.com/hilongjw/vue-lazyload
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    横スクロールしたら初めて⾒える
    ようになる画像は遅延ロードする
    (3枚⽬以降)

    View Slide

  38. 必要なリソースのみ読み込み(計測タグ関連)
    • 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.

    View Slide

  39. 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

    View Slide

  40. 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.

    View Slide

  41. 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.

    View Slide

  42. 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.

    View Slide

  43. 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.

    View Slide

  44. APIリクエストの最適化
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  45. SSR時に表⽰されない…︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  46. “fetch メソッドを⾮同期にするためには Promise を返却し
    てください。そうすれば nuxt.js はコンポーネントがレンダリ
    ングされる前に promise が解決されるまで待機します。”
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  47. “fetch メソッドを⾮同期にするためには Promise を返却し
    てください。そうすれば nuxt.js はコンポーネントがレンダリ
    ングされる前に promise が解決されるまで待機します。”
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    SSR時にPromiseの解決を待たずに画⾯を返してしまう
    = コンテンツ部分が空になってしまう

    View Slide

  48. APIリクエストの最適化
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    Promise返してみた。

    View Slide

  49. SSR時に表⽰されるようになった︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  50. でもタブで切り替えしたとき(CSR)に
    引っかかりが⽣じてしまうようになった…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  51. “fetch メソッドを⾮同期にするためには Promise を返却し
    てください。そうすれば nuxt.js はコンポーネントがレンダリ
    ングされる前に promise が解決されるまで待機します。”
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    CSR時にもPromiseが解決されるまで待機してしまう

    View Slide

  52. CRS時はPromiseの解決を待たずに
    とにかく画⾯を切り替えたい
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  53. CRS時はPromiseの解決を待たずに
    とにかく画⾯を切り替えたい
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.
    快適なインタラクションを優先したい

    View Slide

  54. 【解決策】
    SSRとCSRで処理を分ける
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  55. SSR/CSRに応じたfetch最適化
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  56. その他TIPS
    • ChromeのAuditでパフォーマンス測定する場合はシークレットモードで
    ⾏う。通常のモードで⾏うと、インストールしているChrome拡張が邪魔
    して、スコアに影響することがある。
    – 実⾏後にこれが出てたら要注意。シークレットモードでやり直そう。
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  57. 今後のパフォーマンス関連の展望
    • 定期的にパフォーマンスを計測する仕組みづくり
    – バンドルファイルサイズの可視化をCI/CDに組み込む
    – フロントエンドの各指標を可視化する仕組みづくり
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  58. 最後に1つだけ…
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide

  59. パーソルキャリアでは
    ⼀緒に働く仲間を募集しています︕
    Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide


  60. Copyright © PERSOL CAREER Co., Ltd. All Rights Reserved.

    View Slide