-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf: (rc, stay behavior) uBO scriptlet infinitely spamming MutationObserver attributes
events triggered by itself
#3215
Comments
Thanks for the report/investigation. I didn't expect the browser to generate mutation events when no actual change occurs. By the way, in uBO lists we wouldn't use a filter such as:
We would use:
Which doesn't suffer the issue. I see the filter originates from EasyList Notifications, this should be modified to use the second form above. cc @ryanbr |
Thanks for fast response. I also agree that 'stay' behavior should not happen in common. |
I saw the fix for |
It starts here? |
No, I mean in |
The classes are removed all at once for The fix is that only elements with class(es) to remove are looked up: gorhill/uBlock@91dfcbe#diff-30b28769623e5478a0f68519eda037164484cfb444cb5a8e48518fa7bb32e658R2267. |
I must have misunderstood something previously, apologies. |
Prerequisites
I tried to reproduce the issue when...
Description
In uBlock Origin scriptlets involving DOM attribute modifications (calling
DOMTokenList
orElement.prototype.(set|remove)Attribute
) may cause an infinite loop issue when it's used withMutationObserver
. In this case, I'm handlingremove-class
scriptlet withstay
behavior.This is happening because the attribute modification event in mutation observer does contain cases the actual value haven't changed. However, uBO scriptlet does call attribute modifier methods even there's no class name in the element. Thus the handle of the
MutationObserver
in the script is called again and the same process happens infinitely.Suggested solution
I suggest adding a simple check to avoid calling attribute modification methods meaninglessly. We also need to check if a similar problem happens in other scriptlets involving attribute modification.
Credits to @philipp-classen who found the point of performance issue is happening at
MutationObserver
.refs ghostery/adblocker#3913
refs ghostery/ghostery-extension#757 (comment)
A specific URL where the issue occurs.
https://www.reddit.com/
Steps to Reproduce
My Filters
tab.reddit.com
and set breakpoint to attribute modification onbody
element.In case of Chrome, you can do this by right clicking body element -> Break on -> attribute modifications.
Otherwise, you may put a simple logger in the scriptlet content to see if it actually does infinite loop.
Expected behavior
uBO does stop catching the classes in element if there's nothing to catch.
Actual behavior
MutationObserver
getsMutationRecords
, it callsrmclass
function.https://github.com/gorhill/uBlock/blob/5de19ace916d940c19cfbdfd792e001f174b2085/assets/resources/scriptlets.js#L2287
rmclass
function, it callsDOMTokenList.prototype.remove
function without checking explicitly.https://github.com/gorhill/uBlock/blob/5de19ace916d940c19cfbdfd792e001f174b2085/assets/resources/scriptlets.js#L2265
However, the behavior argument orders the observer to
stay
on the page. In this case, the handler of the livingMutationObserver
is called again and the infinite process starts.uBO version
1.56.0
Browser name and version
Version 118.0.5993.117 (Official Build, ungoogled-chromium) (arm64)
Operating System and version
macOS arm 14.4.1 (23E224)
The text was updated successfully, but these errors were encountered: