Skip to content

Fix observe styles piling up on React navigations - #10312

Open
jakeonrails wants to merge 3 commits into
refined-github:mainfrom
jakeonrails:fix-selector-observer-style-leak
Open

jakeonrails wants to merge 3 commits into
refined-github:mainfrom
jakeonrails:fix-selector-observer-style-leak

Conversation

@jakeonrails

@jakeonrails jakeonrails commented Oct 21, 2026 •

Copy link
Copy Markdown

Closes #10311

Two leaks made the observe <style> elements pile up in a long-lived tab, slowing every style recalculation (and so typing in comment boxes on large PRs).

  1. Features from the previous page were never stopped on React navigations. Since Detect React navigation and re-apply features #9830, features re-run on soft-nav:react-done, but those navigations don't fire the Turbo events that call unloadAll, so the previous run's AbortController was never aborted. Each feature's loop now aborts its own previous run when it wakes up, before any check that could skip the new run. On Turbo navigations the extra abort is a no-op.
  2. waitForPrMerge called observe() without its signal, so its style was never removed, regardless of navigation type.

Added a feature-manager test that fires soft-nav:react-done three times and checks that only the latest run stays active and only one observer <style> exists. It fails without the fix.

Test URLs

https://github.com/crmne/spotifast/pull/961/changes

Switch Conversation ⇄ Files changed 10 times, then count:

[...document.querySelectorAll('style')].filter(s => s.textContent.includes('rgh-selector-observer')).length
Build <style> count, fresh → after 10 round trips Forced style recalc
Store version 52 → 992 46 → 232 ms
This PR 52 → 52 47 → 50 ms

Screenshot

Dev build after 10 round trips (the label is a temporary overlay injected to show the live counts):

After 10 soft navigations the count stays at 52

Since refined-github#9830, features re-run on `soft-nav:react-done`, but React
navigations don't fire the Turbo events that call `unloadAll`. The
previous run was never aborted, so every navigation added another set of
`observe` styles and `animationstart` listeners.

Fixes refined-github#10311
Without the signal, the observer's style was never removed, so every run
of a feature that waits for a merge left another one behind.

Refs refined-github#10311
@github-actions github-actions Bot added the bug label Oct 21, 2026
@jakeonrails

Copy link
Copy Markdown
Author

To add some context the real bug this fixes is that typing into code comments on PRs was getting painfully slow. I would type, and characters wouldn't appear for multiple seconds.

I am now running this fork of the extension and so far I have not experienced the slowdown while typing code comments. This had been happening regularly for about a week (since I noticed) and now it is not happening.

@jakeonrails
jakeonrails marked this pull request as ready for review October 23, 2026 02:43
@fregante

fregante commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Thanks for your report and PR! I merged #10318 to address this via stylesheet deduplication.

I'm still interested in this PR, which solves the issue higher up in the chain. I am only concerned that aborting the signal this way may cause unwanted side effects when navigating back and forth specifically on React pages (components/event listeners might not work anymore)

Have you been using Refined GitHub from this PR?


Tangentially related:

@fregante

Copy link
Copy Markdown
Member

Added a feature-manager test

That file has a lot of global state, as can be seen by the numerous mocks. We don't add tests that have to mock everything.

@jakeonrails

Copy link
Copy Markdown
Author

Have you been using Refined GitHub from this PR?

Yes I have and I have not noticed any issues, but I'm not a heavy refined Github user so I'm not sure that I would notice anything not working. Or maybe let's put it another way: I have had this extension installed for so long I don't even remember what stock Github looks like so I would just think "Oh, Github is broken", and I haven't noticed that.

I'm happy to keep working off my patched PR and report back in a week or so to give me time to notice any issues.

@jakeonrails

Copy link
Copy Markdown
Author

That file has a lot of global state, as can be seen by the numerous mocks. We don't add tests that have to mock everything.

Would you like me to remove that spec? Happy to do so.

@jakeonrails

Copy link
Copy Markdown
Author

I've been using the PR version of the extension for over two weeks now (since this PR was opened) and it's been running great with no issues.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

selector-observer <style> rules pile up on every soft navigation, slowing typing on PR pages

2 participants