Skip to content

fix: send sort_finish once when each board finishes - #69

Merged
shin4488 merged 1 commit into
mainfrom
fix/sort-finish-once
Oct 26, 2026
Merged

shin4488 merged 1 commit into
mainfrom
fix/sort-finish-once

Conversation

@shin4488

Copy link
Copy Markdown
Owner

GA4 の sort_finish が、1回の再生で同じアルゴリズムについて複数回送られていたのを、各ボードが完了したときに1回だけ送るように直しました。

原因

src/App.tsx の完了を扱う effect は、playing かいずれかのボードの finished が変わるたびに実行され、その時点で完了しているボードすべての sort_finish を送っていました。そのため、先に完了したアルゴリズムほど、ほかのボードが完了するたびに送り直されていました。一時停止・再開や、全ボードの完了後に再生を押したときも、完了済みの分をすべて送り直していました。

UIテストで window.gtag に渡ったイベントを数えた結果です(20本、テストで固定した乱数の並び)。

操作 quick_sort selection_sort bubble_sort merge_sort
1回の再生(修正前) 4 3 2 1
途中で一時停止・再開し、完了後にもう一度再生を押す(修正前) 6 4 3 2
上の2つ(修正後) 1 1 1 1

変更した仕様・設計

ボードごとに、finished が変わったときだけ実行される effect から送ります。速度・本数・言語は、useEffectEvent で送る時点の値を読みます(依存に入れると、完了後に速度を変えただけで送り直すため)。全ボードの完了で再生を止める処理は、これまでどおり別の effect に残しました。イベント名と引数(animation_speed・bar_size・algorithm_type・browser_language・translated_language)は変えていません。

flowchart LR
    subgraph before["修正前"]
        A1["playing か、いずれかの finished が変わる"] --> B1["完了済みのボードすべての sort_finish を送る"]
    end
    subgraph after["修正後"]
        A2["あるボードの finished が false から true になる"] --> B2["そのボードの sort_finish を1回送る"]
    end
Loading
場面 修正前 修正後
ボードが完了する 送る。ほかのボードが完了するたびに送り直す 1回送る
一部の完了後に一時停止・再開する 完了済みの分を送り直す 送らない
全ボードの完了後に再生を押す 4つとも送り直す 送らない(並べ替えは始まらず、すぐ止まる)
シャッフル・本数の変更の後に完了する 送る 送る
非表示のボードが完了する 送る 送る

送り直すかどうかは、次のとおり判断しました。

  • sort_finish は、AGENTS.md の約束では algorithm_type: '<kind>_sort' を持つ、アルゴリズムごとの並べ替えの完了を表すイベントです。一時停止・再開や、完了後に再生を押す操作では並べ替えが完了しない(完了済みのボードは進まず、再生はすぐ止まる)ため、送りません。
  • シャッフルと本数の変更は、新しい並びでボードを作り直します(ステップ数が0に戻り、README のとおり全アルゴリズムが同じ新しい並びを並べ替える)。その並びの完了は新しい完了なので、修正前と同じく送ります。
  • 非表示のボードは、README のとおり再生の状態を保って進むため、完了したら修正前と同じく送ります。

AGENTS.md と add-sort-algorithm の skill に、sort_finish は各ボードの完了時に1回送ることを書き足しました。

検証

  • src/__tests__/ui.spec.tsx に2件を加えました。window.gtag に渡ったイベントを記録します。
    • 1回の再生で、4つのアルゴリズムの sort_finish を1回ずつ、正しい引数で送る。
    • 一部の完了後の一時停止・再開や、全ボードの完了後の再生では送り直さず、シャッフル後の完了では改めて送る。ほかの計測イベント(play_click・pause_click・shuffle_click)は操作ごとに1回ずつ送る。
    • どちらも、修正前の src/App.tsx では落ち(回数は上の表)、修正後は通ることを確かめました。
  • Docker で yarn typecheck && yarn lint && yarn format && yarn test: 成功(46件)。
  • 開発サーバー(http://localhost:1234、StrictMode で動く)の /ja/ を、内蔵ブラウザで実際に操作しました。index.tsx が本番の測定IDで GA を初期化するため、本番の計測に送らないよう、同じオリジンの文書に localhost:1234 だけを許す Content-Security-Policy を置いてから、/ja/ のスクリプトを読み込みました。gtag.js の読み込みは CSP で止まり、Google への通信は0件でした。gtag に渡った引数は window.dataLayer で確かめました。
操作 結果
5本・10倍で再生し、完了後にもう一度再生を押す sort_finish は4つを1回ずつ(bar_size: 5、animation_speed: 10)。2回目の再生は play_click だけで、すぐ止まる。4パネルとも昇順で完了の表示
20本、マージソートを非表示にして再生し、完了後に再生を2回押す sort_finish は4つを1回ずつ(非表示の merge_sort も1回)。再生の2回は play_click だけ。マージソートを表示し直すと、1〜20の昇順と「並べ替えが終わりました。」を表示
シャッフル shuffle_click 1回。ステップ数が4パネルとも0に戻り、同じ新しい並びになる
50本で再生し、クイックソートの完了後に一時停止し、再開して完了まで再生する 一時停止中は2秒間、棒が変わらない。pause_click・play_click を1回ずつ送り、quick_sort を送り直さない。残りの3つは完了時に1回ずつ。4パネルとも昇順で、比較枠は残らない
速度を一段階遅くする 表示が アニメ速度: 9.95 になり、イベントは送らない

全体では、sort_finish は3回の再生(5本・20本・50本)で各アルゴリズム1回ずつ、play_click 7回・pause_click 1回・shuffle_click 1回で、押した回数と一致しました。

🤖 Generated with Claude Code

The completion effect in App ran whenever `playing` or any board's `finished` flag changed, and it sent `sort_finish` for every board that had already finished. One playback therefore sent the event several times for the algorithms that finished early (for example quick_sort 4 times), and pausing, resuming, or pressing play after every board had finished sent all of them again.

Send the event from one effect per board that runs when that board's `finished` flag changes, so it fires once when the board finishes. `useEffectEvent` reads the speed, bar count, and language at that moment without making them dependencies. A shuffle or a bar count change resets the boards, so the next completion is sent again. The event name and parameters are unchanged.

Add UI tests that record the calls to `window.gtag`, and note the rule in AGENTS.md and the add-sort-algorithm skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shin4488
shin4488 merged commit ccbaa87 into main Oct 26, 2026
5 checks passed
@shin4488
shin4488 deleted the fix/sort-finish-once branch October 26, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant