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

巨大なSPAの技術的負債と向き合い続けるテクニック

 巨大なSPAの技術的負債と向き合い続けるテクニック

「フロントエンドの技術的負債 みんなで学ぶ Lunch LT 」の登壇資料です
https://findy.connpass.com/event/281811/

shibe23

May 17, 2023
Tweet

More Decks by shibe23

Other Decks in Technology

Transcript

  1.       
    © Chatwork
    巨大なSPAの技術的負債と
    向き合い続けるテクニック
    2023年05月17日
    フロントエンド開発部マネージャー 澁谷 哲也
    Chatwork株式会社

    View Slide

  2. 自己紹介
    2
    Chatwork株式会社
    澁谷 哲也 Tetsuya Shibutani
    フロントエンド開発部 マネージャー
    ビジネスチャットツールを作っています
    @shibe_23

    View Slide

  3. ChatworkのWebFrontendについて

    View Slide

  4. ChatworkのWebFrontendの特徴
    ● 巨大なSPA、かつ利用中ほとんどリロードされずに使われるアプリケーション
    ● 双方向性があり、ユーザーからのアクション以外で状態が変わる
    ● JavaScriptだけで16万行
    ● CSSも1万7千行
    ○ Styled-Componentを利
    用しているため、実際に
    はもっと多い
    巨大なコードベース
    ● ブラウザベースのアプリケー
    ションとしては珍しく、URL単
    位でアプリケーションとして分
    割されていない
    ● 再読み込みのない一枚のページ
    で全UIが動作している
    純粋なSinglePageApplication
    ● Webサイトベースの「入力 ->
    確認 -> 完了」と情報が一方向
    なWebアプリではない
    ● Google SpreadSheetのような
    GUIアプリとしての複雑さを持

    GUIアプリとしての複雑性
    4

    View Slide

  5. 技術的負債の状況
    ● jQuery -> React + DDD -> React + Reduxの3世代に渡るアーキテクチャ
    ● jQuery製のUIとReact製のUIが混在している
    ○ 全体のうち約2万4000行がjQuery製
    ● 認知的複雑度(Cognitive Complexity)の合計は、およそ9,000
    ○ jQuery世代はおよそ5,000
    ● 各世代ごとの詳細は下記を参照ください
    組織フェーズを見据えたWEBフロントエンドのアーキテクチャと変遷(JS Conf 2021)

    View Slide

  6. 技術的負債についての考え方
    ● 技術的負債は「アプリケーションのあるべき姿と現状との差分」
    ○ 現状からあるべき姿に到達するまでに掛かる時間(= リソース)と向き合っている
    ● あるべき姿は時代の変化によっても変わる
    ○ jQuery全盛期にReactの登場は予測できなかった
    ○ 現在のベストプラクティスも、新しい技術の登場によってあるべき姿から遠ざかる
    ● 負債は無くすものではなく、様々な要因を加味してコントロールするもの
    技術的負債と継続的に向き合う仕組みづくりが重要

    View Slide

  7. 技術的負債と継続的に向き合う方法
    7
    1. 段階的に返却するためのテクニック
    2. 安全にリリースするための仕組み
    今回は具体例をいくつかご紹介します

    View Slide

  8. 段階的に返済するテクニック

    View Slide

  9. jQueryの世界とReactの世界を分離する
    ● jQuery製のコードとReact製のコードの間に腐敗防止層を設ける
    ● interfaceをReact側から提供することで依存関係を制御する
    ● Reactの世界にjQueryが侵入することを防ぎ、古いコードを捨てやすくしている
    jQuery時代のアーキテクチャをReact化するために大切なACL層のお話

    View Slide

  10. jQuery製のUIとReact製のUIを混在させる
    ● 段階的にリファクタリングするためにUIごとにReact化したい
    ● ReactDOM.renderを使った時の課題
    ○ Context APIを全てのレンダリングツリーに流し込む必要性
    ○ デバッグ時にレンダリングツリーごとにしかプロファイルが取れない
    ● ReactDOM.createPortal で同一の親コンポーネントを指定してマウントするようにした
    ● 部分的な置き換えにおける注意点
    ○ イベントハンドラの多重登録
    ○ 再描画の度にjQueryで作成したDOMが残り続けることによるメモリリーク
    … React
    … jQuery

    View Slide

  11. TypeScriptのStrict modeを有効にする
    ● jQuery時代のコードはany型を一部許容している
    ○ 一方で、普段のコードを書く時に暗黙的なany型の混入を防ぎたい
    ● strictを有効にするために、TypeScript Compiler APIを使って型エラーが起きている箇所に
    @ts-expect-error を自動で追加した
    ○ 新規で@ts-expect-errorを書かないようにpre commit時にチェックしている
    ● 型エラーが隠蔽されるケースがあるので、トレードオフには注意

    View Slide

  12. 安全にリリースするための仕組み

    View Slide

  13. 技術的負債と継続的に向き合う = 小さく試して改善し続ける
    ● コードを適切に処理できれば確実に不具合を回避することはできるか?
    ○ できない
    ○ 負債の影響は積み重なって予期しない不具合として現れる
    ● リリースしなければ本当に問題がないかは確認できない
    ○ 失敗の影響を最小限に抑えなければ、リファクタリングは重たいプロセスになってしまう
    ● “どうコードをきれいにするか”も大事だが、 “小さく失敗できる体制をつくる“ことが最も重要

    View Slide

  14. リリースフローの全体像
    ● GitHub Flowを採用
    ● mainブランチにマージされるとすぐに社内検証ユーザーにデプロイされる
    ● 本番リリースされるのは、その時点のmainブランチの最新コミット
    ● 先行して自分たちが触ることで、ユーザーにとって致命的な不具合がリリースされることを回避
    社内検証ユーザーにリリー

    main
    feature-x
    社内検証されたものが
    本番リリース

    View Slide

  15. コミットハッシュごとのスナップショットを生成する
    ● PR作成時 / 更新時 / mainブランチへのマージ時にビルドしたjsファイルをS3にアップロードする
    ● コミットハッシュをURLにパラメータとして付与することで、指定したバージョンでアプリを開いて
    検証できる仕組みがある
    ○ バージョンごとの現象確認が容易
    ● リリースブランチへマージされた履歴がjsファイルとして既に生成されている、というのがポイント
    commit hash:
    c63df1b164b73d71…
    main
    commit hash:
    f632892477af9be29…
    commit hash:
    ebbd2436080a165c…
    commit hash:
    8238f9b315116c5c0…

    View Slide

  16. 自前のリリースシステムで高速なリリース / 切り戻しを実現する
    ● リリースは生成済のjsファイルを本番環境にコピーするだけ
    ● mainブランチの過去の状態も保存されているため、切り戻しも容易
    ● 緊急時の切り戻しは実行 -> リリース完了で約3秒
    ※ 切り戻しの判断も必要なので、障害対応自体はもう少しかかります

    View Slide

  17. Feature Toggleで安全にリリース内容を制御する
    ● Feature Toggleで社内検証ユーザーにのみリリースすることができる
    ● 大きめのリファクタリングなど、本番環境へのリリースを阻害することなく検証期間を設けることが
    できる
    ● 非公開の制御もFeature Toggleをオフにするだけ
    ● Feature Toggleによって分岐が増えて複雑化する場合もあるため要注意

    View Slide

  18. まとめ

    View Slide

  19. 技術的負債と現実的に向き合うために
    ● 技術的負債を解消するより、どのように距離を保つか
    ○ 段階的に負債を返却するためのテクニック
    ○ 安全にリリースするための仕組み
    ● 未来は誰にも予測できない。だからこそ小さく試して改善し続ける
    ○ “小さく失敗できる”体制が重要

    View Slide

  20. 今回の話に興味を持っていただいた方へ
    ● エンジニアHub様掲載の記事もご覧ください
    React+Reduxによる状態管理とフロントエンドの技術的負債 ─ 長く継続するサービスのアプリケーション設計

    View Slide

  21. 最後に
    ● Chatworkではフロントエンドエンジニアを募集しています
    ● 巨大なSPAと一緒に向きあい改善し続けてくださる方、ぜひご応募ください!
    採用ページはこちら

    View Slide

  22. 働くをもっと楽しく、創造的に

    View Slide