💻 システム開発

SCALE_CRM_リスト性能_残課題洗い出し_第2弾

最終更新 2026年07月06日 / 31_システム開発部/_SCALE_CRM_リスト性能_残課題洗い出し_第2弾.md

SCALE CRM 架電リスト性能 残課題洗い出し 第2弾

大串FB(2026-07-06)「重い原因で対処しきれてないことないか洗い出して。超高品質なCRMにしたい。架電はひたすら数こなすからちょっとのラグが凄いストレス」への回答。
前提: 第1弾(_SCALE_CRM_リスト性能_根本原因とHubSpot対比)の①仮想スクロール+HubSpot体制Phase1-3は本番LIVE済み。本ノートはその後も残っている未対処分をコード実証(3並列調査・ファイル:行番号つき)で洗い出したもの。

対処済みの確認(再発なし)

  • 仮想スクロール本体(calllist_core.js:1380-1420): RAF throttle・編集中の再描画抑止・行高キャッシュあり=堅牢
  • 検索入力の220ms debounce(calllist_core.js:577)
  • per-row 1行PUT(json_patch・UI非ブロック)・イベントリスナ(inline onclick=自動GC)
  • E1(per-row同期の毎分フリーズ・v11.5.78)/ E2(401無限スピナー・v11.5.79)

未対処の残課題(体感影響順)

A. 操作のたびのマイクロラグ(架電メンバーのストレス直撃・最優先)

# 課題 場所 何が起きるか
A1 🔴 getLatestCallSt メモ化なし lib/calllist_const.js:53-62 毎回5スロット走査。フィルタ・ソート・統計・モーダル等 計8箇所以上から重複呼び出し
A2 🔴 filterCL がプリセット/ソート/タブ切替のたび全件走査 lib/calllist_core.js:1486-1543 フィルタO(n×5)+ソートコンパレータ内で getLatestCallSt 再計算(6千行×log n≈8万回)。1操作で合計約14万スロット走査=200-500msの引っかかり
A3 🔴 _collectTodayStats がステータス変更のたび全行走査 lib/pagecore_report.js:8-46(呼出: pagecore_timer.js:743 / calllist_misc.js:639 / calllist_status.js:338) 架電1件入力するごとに6,134行×5スロット再スキャン。「数をこなす」動線に毎回乗る
A4 🟡 _migrateCallListV3 が renderCallList のたび全行forEach lib/calllist_core.js:11-37, 706 「一度だけ」のはずが毎render全行チェック(1回5-10ms・積算)

A1〜A3の連鎖が「ちょっとのラグ」の正体。仮想スクロールで描画はO(1)になったが、描画の前段の計算が全部O(n)のまま

B. 初期ロード・ページ再訪の重さ

# 課題 場所 何が起きるか
B1 🔴 全機能JS 約2.6MBを全員が初期ロード index.html:19-143 service.min.js 724KB(AI共創)・kickoff 91KB・ai 48KB・list_pool 50KB を架電メンバーにも強制DL+評価。lazy load なし
B2 🟡 JS/CSSが no-cache _headers ?v= 版付きなのに毎回再検証(304往復200-500ms)。immutable + max-age=31536000 にできる。SWが部分救済中
B3 🟡 _routes.json 不在 (ファイルなし) 静的アセットも認証middlewareを通過(regex×20/リクエスト・初回30-50リクエスト分)
B4 🟡 起動シーケンスが直列3往復 core.js:5620-5750 _initSupabase → _v2SyncBoot → clLoadRows が直列。並列化・集約の余地
B5 🟡 sessionMemberExists の isolate 60秒キャッシュ functions/_middleware.ts isolate 寿命が短く、ページ移動/プロジェクト切替で D1 member_rows 再読込(40-100ms/回)。KV昇格の余地

C. ネットワーク・データ量(弱回線メンバーに効く)

# 課題 場所 何が起きるか
C1 🟡 120秒 full reconcile の全件再DL が残存 core.js:3727 DOM/parse側は v11.5.78 で軽量化済みだが、5MB級のDL自体は2分ごとに発生(弱回線の帯域圧迫・第1弾#4の残り)
C2 🟡 リロード時の全件再DL core.js:3542(loadRows)+ calllist_core.js:715-765 v86スナップ即表示はUIのみ。裏で毎回 5.9MB DL+6千回JSON.parse。ページングなし(第1弾#2の残り)
C3 🟢 APIレスポンスの不要フィールド functions/api/calls/index.ts:68-80 全件GET時も updated_at/updated_by を全行送信(約100KB余分)

D. 掃除・将来リスク

# 課題 場所 何が起きるか
D1 🟡 旧chunked blob 7.92MB がD1に残骸 core.js:979-986(fire-and-forget削除のみ) 物理削除スクリプト未実装。第1弾#6が未実施のまま
D2 ⚠️ query.ts が「全行SELECT→JSで絞り込み」 functions/api/calls/query.ts:137-139 現在は _clServerMode OFF なので体感影響ゼロ。ただしPhase4をONにすると1リクエスト1-2秒=逆に遅くなる。ON前に c_* 物理列でのSQL絞り込み化が必須

対処パッケージ(効果順・実装するならこの単位)

  1. パック①: クライアント計算のO(n)撲滅(A1メモ化 → A2重複排除 → A3差分/キャッシュ化 → A4スキップ)=「操作のたびの引っかかり」根治。架電メンバーの体感に最も効く
  2. パック②: 配信最適化(B2 immutableキャッシュ → B3 _routes.json → B1 lazy load)=開く・戻るが速くなる
  3. パック③: ネットワーク削減(C1 full reconcileの軽量化 → B4 起動並列化 → C2 ページング)
  4. パック④: 掃除(D1 chunked blob削除スクリプト)
  5. (Phase4をONにする時)D2 query.tsのSQL化を先に

実装結果(2026-07-06 v11.6.3・本番LIVE・同日中に全部実装)

大串指示「全部実装して。完璧に超スピード感もった完璧なツールに」→ 同日実装・デプロイ・本番実バイト検証済み。

課題 結果
A1 getLatestCallStメモ化 ✅ WeakMap+キー検証(ステータス変化で自動再計算=無効化漏れゼロ)
A2 filterCLソート再計算 ✅ 事前計算(Schwartzian)化・安定ソートで順序完全同一
A3 統計の全行走査 ✅ 集計本体500msメモ化+_updateCallListStatsOnly冒頭で必ず無効化(編集経路の鮮度は従来同一)
A4 _migrateCallListV3 ✅ 案件ごとセッション内1回に(不要PSも排除)
B1 JS遅延ロード ⚠️ 縮小実施: preloadをcore+lib_bundleに付替のみ。フル遅延はrenderPageのRマップ(core.js:6196)がrenderService等を裸参照=ReferenceErrorリスクで見送り
B2 immutableキャッシュ ✅ 版付き9ファイルを1年immutable化。Pagesの_headersは同名ヘッダを結合する仕様(本番実測)→「! Cache-Control」で前段no-cacheを取り消してから設定。SW/HTMLはno-cache維持
B3 _routes.json ❌ 見送り: min.jsのAUTH_GUARD保護(未ログイン403)が外れる=認証姿勢の変更。効果もB2でほぼ吸収
B4 起動並列化 ❌ 見送り: ブート順序依存が深くPhase4とセットで設計すべき
C1 full reconcile全件DL ✅ /api/calls?digest=1新設(件数+MAX(updated_at)・数百バイト)→一致でDLスキップ。安全弁=失敗/不一致は従来full・連続スキップ15回上限(30分毎に本物full=保険維持)・digest基準はfull成功後確定。帯域最大1/15
C2 リロード全件DL ❌ 見送り: slimスナップを正データ化するとデータ消失リスク。真の解決はPhase4ページング
D1 chunked blob残骸 ✅ 36キー15.73MB削除(dump保存→DELETE→残存0検証・DB 653.7→633.6MB)
D2 query.ts SQL化 ✅ 実施: c_latest_status整合を本番実測(「ステータス有り×NULL」矛盾0行)で確認の上、st/cp/sg/presetを1次WHEREに押込(上位集合保証・early-return系preset除外・recentIds OR包み)。JS述語は最終判定に不変維持

重要な実測: 最大案件mnpg72の現役行は14,900行(6/24の6,134行から2.4倍に成長)。行数比例の設計が残っていたら近々再クラッシュだった。
観測: [CL-FULL-SKIP](digestスキップ)・[CL-FULL](full実測ms)・window._perfStats(longtask)。

関連