Slide 1

Slide 1 text

GraphQL でネストしたクエリを書いたら Apollo Client が無限に計算し続けるようになった話 @whatasoda

Slide 2

Slide 2 text

自己紹介 Shota Hatada (whatasoda) Digital Hollywood University (日本の大学) mercari (2020/04 - 2022/09) フロントエンドチーム dinii (2022/10 -) Platform Team フロントエンドの基盤部分の実装を触ったりたまにインフラを触ったり色々 趣味:スキー お酒 アニソン

Slide 3

Slide 3 text

Hasura の Relationship テーブルやビューを接続しておけばネストしたクエリを書くだけで複数のテーブル・ビューにまたがるデータを関 連に基づいた状態で取得できる機能 例えば… todos とそれに紐づく user を一度に取得することができる (リレーションシップ - Hasura GraphQLチュートリアル) 😆 設定もクエリも簡単でとても便利! 😮 ネストの深いクエリが増えがちに …

Slide 4

Slide 4 text

そのクエリ、実はフリーズの危険性があるかも …🥶

Slide 5

Slide 5 text

先に結論から… Apollo Client でキャッシュを利用しているとクエリの形状に基づいたキャッシュの書き込みを行うために レスポンスデータの検証を行う 検証はデータ取得の度に同期的に行われ、データの量やクエリの複雑度などによっては膨大な時間を要 する 一度に取得するデータの量を調整するかクエリの複雑度を調整することで改善は見込める どちらも難しい場合は Apollo Client にパッチを当てるなどして検証の処理を飛ばすようにするしかない

Slide 6

Slide 6 text

なにが起こるの…? https://apollo-client-heavy-validation-demo.whatasoda.me/ 内容が同じクエリが3つ クエリごとに返すデータの量を変える

Slide 7

Slide 7 text

なにが起こるの…? ボタンを押すとクエリを実行する ↓ 数字や色の更新が止まる ↓ React の状態更新の処理や要素の描画の処 理がブロックされている Sample01 → 普通 Sample02 → 数秒フリーズ Sample03 → 無限…

Slide 8

Slide 8 text

なにが起こるの…? キャッシュを無効にしていると特別フリーズはしない

Slide 9

Slide 9 text

なにが起こるの…? パフォーマンス計測をして何が起きているのか見てみよう!(Sample02 がおすすめ) かなりのループ処理! →詳しく見て調べてみると Apollo Client 内部での処理っぽい

Slide 10

Slide 10 text

なぜ起きるの…? ● 受け取ったデータを クエリの形状通りにキャッシュに書き込む ために検証っぽいことをしている ○ キャッシュを使わなければ特に計算しない ● クエリのフィールドの端の端までの丁寧な検証を 一つの同期処理上でやっている ○ 他のあらゆる処理をブロックしてしまってフリーズしていた ● 計算コストはざっくり『受け取るデータの数』 ×『クエリの複雑度』と言えそう ○ 今回 paragraph の中身には id と text があるので paragraph の数 × 2 回検証するイメージ 『GraphQL クエリの形状が複雑』 AND 『受け取るデータの数が多い』 THEN フリーズの危険性がある

Slide 11

Slide 11 text

対策は…? ● データを分割して取得する(ページネーションとか) ● クエリの複雑度を抑える(一部を JSON Text として返す…?) マスターデータを全部取っておきたいので全件取得のほうが楽 … Hasura の Relationship を使っているのでクエリの複雑度はなかなか抑えられない … というか、そもそもキャッシュの検証って必要? 実は必要ないのでは …?

Slide 12

Slide 12 text

👊飛ばしちゃおう!💥

Slide 13

Slide 13 text

🩹パッチを貼りました🩹

Slide 14

Slide 14 text

対策(ゴリ押し) https://github.com/whatasoda/apollo-client-heavy-validation-demo/blob/36f7f04cca40b4ce5f67c86edde3e0aa006dd 12e/patches/@apollo+client+3.8.6.patch キャッシュ書き込みの検証時に末端の フィールドと同じように扱う

Slide 15

Slide 15 text

まとめ Apollo Client でキャッシュを利用しているとクエリの形状に基づいたキャッシュの書き込みを行うために レスポンスデータの検証を行う 検証はデータ取得の度に同期的に行われ、データの量やクエリの複雑度などによっては膨大な時間を要 する 一度に取得するデータの量を調整するかクエリの複雑度を調整することで改善は見込める どちらも難しい場合は Apollo Client にパッチを当てるなどして検証の処理を飛ばすようにするしかない

Slide 16

Slide 16 text

ご清聴ありがとうございました