Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

GO TechTalk #22 Reactで描くタクシーアプリ『GO』の世界

GO Inc. dev
September 12, 2023

GO TechTalk #22 Reactで描くタクシーアプリ『GO』の世界

■ 内容
・​​Reactで地図上にタクシーをゴリゴリ描画する方法(大橋)p.4 ~
・最近の推しフロントエンド構成(鈴木)p.46 ~

■ YouTube
https://www.youtube.com/watch?v=kG81x8E-LM8&t=180s

■ connpass
https://jtx.connpass.com/event/293119/

GO Inc. dev

September 12, 2023
Tweet

More Decks by GO Inc. dev

Other Decks in Programming

Transcript

  1. © GO Inc. 5 自己紹介 大橋平和(@lighttiger2505) ▪ GO株式会社 ▪ バックオフィス基盤3グループ(タクシー会

    社様の管理画面) ▪ グループマネージャー ▪ サーバーサイドエンジニア ▪ 好きな言語: Golang ▪ 好きなエディタ: Vim(Neovim) ▪ 最近、生の歓びを感じること ▪ ARMORED CORE VI FIRES OF RUBICONで対 戦用の機体をアセンブルすること
  2. © GO Inc. リアルタイム運行管理の要件 ▪ 大きなタクシー会社様が快適に使える ▪ タクシー車両3~4000程度の描画が高速にできる ▪ マップ上に操作可能なピンなどを配置したい

    ▪ 地点登録をしてそこにジャンプをするなどの便利機能がある ▪ 地図検索や住所検索などをしたい ▪ 駅や建物などを検索してジャンプしたりなどする 12
  3. © GO Inc. 14 Reactで地図描画するときの技術選定の要素 1. ベースマップ(タイルレイヤー) a. 地図の画像の提供元。Google MapsやMapboxなど

    2. マップライブラリ a. 地図の描画を制御し、ベースマップの上にビジュアライズ要素を 追加するためのライブラリ。Leafletやdeck.glなど 3. Reactラッパー a. マップライブラリをReactのコンポーネントとして扱うためのラ イブラリ。react-leafletやreact-map-glなど
  4. © GO Inc. 16 ベースマップ A. Google Maps a. 言わずと知れたGoogle社の提供する地図

    B. Mapbox a. Mapbox社の提供する開発者向けのカスタマイズ可能な地図 C. OpenStreetMap a. コミュニティベースでメンテナンスされるオープンライセンスの 地図 D. ArcGIS a. 地理情報システム開発では世界有数の技術力を持つESIR社の提供 する地図
  5. © GO Inc. 18 マップライブラリ A. Leaflet a. 昔からあるシンプルなライブラリ。コミュニティにてメンテ B.

    Maps JavaScript API a. Google公式提供のライブラリ。GitHubにリポジトリはないが GoogleMapの直接利用時には意識的に読み込み C. Mapbox GL JS a. Mapbox公式提供のライブラリ、WebGLベースで描画 D. deck.gl a. 大規模データセット用に開発されたWebGLベースのライブラ リ。Uberが運営のvisglというオープンソースコミュニティが開 発
  6. © GO Inc. 19 マップライブラリを選ぶときの注意点(1) マップライブラリ 利用可能なベースマップ LeafLet, deck.gl Google

    Maps Mapbox OpenStreetMap ArcGIS Maps JavaScript API Google Maps Mapbox GL JS Mapbox OpenStreetMap ArcGIS マップライブラリごとに選択可能なベースマップがある
  7. © GO Inc. 21 Reactラッパー マップライブラリ Reactラッパー LeafLet PaulLeCam/react-leaflet Maps

    JavaScript API googlemaps/react-wrapper JustFly1984/react-google-maps-api Mapbox GL JS visgl/react-map-gl alex3165/react-mapbox-gl deck.gl 公式にReactフレンドリーを謳おり、マップライブラリ にReactラッパーが同梱
  8. © GO Inc. 22 Reactラッパーを選ぶときの注意点 ▪ Reactラッパーを最初に選ぶとベースマップの選択が不可 ▪ 「Reactラッパーを選ぶ」=「マップライブラリを選ぶ」なの で、その時点で選択可能なベースマップが確定

    ▪ 「React 地図」でGoogle検索すると、Reactラッパーを導入しよ う。から始まる記事があるので注意 ▪ 個人運営か企業運営かは確認 ▪ deck.glやreact-map-glはvisglというコミュニティによってメン テ ▪ 企業運営ならば良いというわけではない ▪ TypeScriptサポートがあるか確認
  9. © GO Inc. 23 極論するとReactラッパーはなくてもよいが ▪ Reactラッパーを使わず直接マップライブラリを使う手も ある ▪ Mapbox

    GL JSは公式サイトでReactから直接利用するチュート リアルを公開 ▪ ReactアプリでMapbox GL JSを使う ▪ 直接利用しても、結局自前でReactコンポーネント化する ことになる。メンテナンスされているReactラッパーがあ 場合、利用するほうが無難
  10. © GO Inc. 24 「GO管理画面」の技術選定は? 種類 選択 採用理由 ベースレイヤー Mapbox

    Mapbox GL JSにした結果、Mapboxほぼ一択。会社全 体だとGoogle Mapsも使っているので、Mapbox GL JS採用しなければ選ぶのは可能だった。 マップライブラリ Mapbox GL JS Leafletと比較してWebGLによる描画速度が大きな要 因。当時deck.glを知らないため比較検討していない。 今なら有力な選択肢。 Reactラッパー visgl/react-map-gl サポートにMapbox公式がクレジットされている (visglにはMapboxも参画している)かつ使いやすい ため、現状MapboxのReactラッパーならばかなり有力 な選択肢。
  11. © GO Inc. 26 描画を軽くするためのポイント 1. 描画の方式を高速なものにする 1.1. DOM操作を伴わない描画をする 1.2.

    WebGLを用いた高速な描画をする 2. 描画の回数を減らす 1.描画の方式を高速なものにする 2.描画の回数を減らす 時間軸
  12. © GO Inc. 31 マーカーとレイヤー(メリット・デメリット) 種別 マーカー レイヤー メリット •

    実装が簡単 ◦ クリックイベントの追加、 ポップアップの追加などが 容易 • HTMLなので見た目のカスタマイ ズをCSSでできる • 大量のデータの高速描画が可能 デメリット • 大量に配置するとパフォーマンス が悪化する • 実装が難しい ◦ 座標情報をGeoJSON形式に変換 するなど手間がかかる ◦ 画像を描画するならマップ側にロー ドが必要 ◦ クリックイベント追加などマップに独 自の方法で追加が必要
  13. © GO Inc. 33 「GO管理画面」のライブラリ選択は以前はこうだった 種類 選択 採用理由 ベースレイヤー Mapbox

    適当 マップライブラリ Leaflet 適当 Reactラッパー PaulLeCam/react-leaflet 適当
  14. © GO Inc. 34 マーカーを大量配置したら遅くなったので調査 「leaflet too many marker」のGoggle検索結果を3日眺めた 結果、マーカー描画の速度改善の解決策を見つけた

    1. DOM要素の変更があるマーカーではなくレイヤー (Vector Layers)に切り替える a. これで解消しなかった理由は次スライド 2. クラスター表示にする a. 一応これも導入している 3. 高速な描画を行うための外部プラグインを導入し、プラ グインの提供するレイヤー上で描画 a. 個人が提供するプラグインに依存するのは抵抗があった
  15. © GO Inc. 36 レイヤー描画にすれば、どのマップライブラリも早いのか ▪ Leafletのパフォーマンス問題の調査をするなかで一つの 記事と出会う ▪ Leaflet

    versus Mapbox GL performance ▪ Mapbox GL JSとLeafletの同一条件のパフォーマンステスト記事 • 唆るぜこれは
  16. © GO Inc. 37 『Leaflet versus Mapbox GL performance』要約 ▪

    地図上に大量のドットをアニメーションさせるサンプル プログラムを2018年の15インチMacBook Proで実行して 検証 ▪ LeafLetで300個のドットを動かしたらFPSは30まで落ち、700 個のドットを動かしたらFPSは1桁台になった ▪ Leafletには高速描画オプションがあるが、ONにしても1000個の ドットでFPSは1桁台になった ▪ Mapbox GL JSで2000個のドットを動かしたがFPSは安定して60 を維持していた
  17. © GO Inc. 39 車両を表示するためのタクシー位置情報の中身 state [ { "driver_app_kit_id": 1000536,

    "office_id": 1000673, "latitude": 33.627787102874215, "longitude": 130.41376251671505, "azimuth": 21.879079818725586, "timestamp": 1693517317, "datetime": "2023-08-31T21:28:37.741Z", "meter_status": "unladen", "active_status": "normal", "business_status": "no_signal", "speed": 0.5939096331596374 } ... ]
  18. © GO Inc. 40 タクシー位置情報の更新で再描画される対象 タクシー車両の現在地を 表示しているマップ 現在マップに 表示されている車両の一覧 選択車両の詳細

    state タクシー車両の現在地を 表示しているマップ タクシー車両の現在地を 表示しているマップ タクシー車両の現在地を 表示しているマップ タクシーの位置情報が更新 されると、同時に3つの ビューの再描画が走る
  19. © GO Inc. 41 何の対策もしない状態の描画回数 タクシー 車両 タクシー 車両 タクシー

    車両 「GO管理画面」 フロントエンド 1秒間に数回の再描画 数秒に1度、位置情報を送信 全体で25000RPS 上位30社14000RPS 位置情報収 集サーバー state 数秒に1度、位置情報を送信 全体で25000RPS 上位30社14000RPS 数秒に1度、位置情報を送信 全体で25000RPS 上位30社14000RPS フロントエンドとWebSocketで接 続し、位置情報を送信し続ける
  20. © GO Inc. 42 対策をした場合の描画回数 動態収集 サーバー Map state 1

    2 3 受け取った動態をID 別に格納し、常に最 新の動態だけを持つ Mapを作る 再描画が負荷になら ない程度のインター バルを設けて、定期 的に配列に変換 配列をstateとして、 更新すると再描画が走る
  21. © GO Inc. 44 まとめ(2. Reactで地図描画するときの技術選定) ▪ Reactで地図描画をするなら技術選定に注意 ▪ 最初にReactラッパーを選択すると、ベースマップを変更できな

    い ▪ 「Reactラッパーの選択」=「ベースマップの選択」 ▪ マップライブラリによってベースマップの選択肢が限られる ▪ マップライブラリによって高速な描画方式をサポートしていない ことがあるので注意
  22. © GO Inc. 45 まとめ(3. 地図に大量のマーカーを描画するためのTIPS) ▪ 地図上にアイコンを大量表示するなら描画方式に気をつ ける ▪

    各種イベントが容易に追加でき、見た目もいじりやすいマーカー か、高速描画できるが実装が難しいレイヤーかを考える ▪ ライブラリ次第では描画方式が古く、大量のアイコン表示がそも そも無理なものもある。大量のアイコン描画が必要になるかはよ く考える ▪ そもそも描画する回数を減らせば負荷は減る。バッファ リングして減らせるなら減らそう
  23. © GO Inc. 47 自己紹介 プロフィール写真 正方形にトリミングした写 真を「図形に合わせてトリ ミング」で円形にすると真 円になる

    GO株式会社 エンジニア / Suzuki Fumita 略歴 最初に入った受託系企業で官公庁のR&D案件を何回かやったのち、ス タートアップ業界に。2021年6月にGOに入社。現在はタクシー事業者向け の管理画面開発に注力。1児の父。趣味は船釣り。 @maikii_chan
  24. © GO Inc. 使用技術ーUI系ライブラリ 52 MUI(material-ui) v5 言わずと知れた大御所ライブラリ。デカい上に複雑なライブラリだが、管理 画面に必要なコンポーネントはほぼ全部揃っている。開発もそこそこ活発。 TypeScriptもサポートしている(当たり前か)。

    Emotion CSSinJS系のライブラリ。MUIは内部で使うスタイリングソリューションを 選択することができ、GO管理画面ではEmotionを使っている。 react-hook-form + yup フォームは全部react-hook-formとyupで書いてある。yup.InferTypeで schemaから型を作っている。
  25. © GO Inc. 使用技術ーテストツール 53 Vitest Jestと互換性のあるユニットテストツール。単純に速いJestというだけでは なく、Rust-likeなIn-source testingができたりする。 Cypress

    有名なE2Eテストツール。多機能で便利。CI側で落ちたりしてるとデバッグ がめんどくさい。今だったらPlaywrightも良さそう(並列テストがやりやす いらしい)。