I-loop in querySelector on sfgate.com
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr140 | --- | unaffected |
| firefox151 | --- | unaffected |
| firefox152 | --- | disabled |
| firefox153 | --- | fixed |
| firefox154 | --- | disabled |
People
(Reporter: jesup, Assigned: arai, NeedInfo)
References
(Blocks 1 open bug, Regression)
Details
(Keywords: regression)
Attachments
(3 files)
Repeatable i-loop at https://www.sfgate.com/local/article/golden-gate-park-leech-22270623.php?utm_source=firefox-newtab-en-us in querySelector.
Profile: https://share.firefox.dev/43BhJ6Y
Updated•3 months ago
|
Comment 1•3 months ago
|
||
I can't repro this, can you repro on a clean profile / without extensions / etc?
Any chance you could take a profile with JS script urls / function names? Otherwise it's hard to reason about what is be going on from the profile alone.
Comment 2•3 months ago
|
||
I can repro on both my main profile Firefox nightly, and also a nearly new profile of a local build.
Having a hard time collecting a profile since it's locking up. (MacOS)
Loads fine in Firefox Release, 150.
Comment 3•3 months ago
|
||
(In reply to Emilio Cobos Álvarez [:emilio] from comment #1)
I can't repro this, can you repro on a clean profile / without extensions / etc?
Any chance you could take a profile with JS script urls / function names? Otherwise it's hard to reason about what is be going on from the profile alone.
This one, local build, nearly new user profile, has Javascript Sources enabled in the profiler
https://share.firefox.dev/4dwbcR2
Comment 4•3 months ago
|
||
It seems from that profile that they're trying to load a script and then loading https://snap.licdn.com/li.lms-analytics/insight.old.min.js when that fails or so... And when they do this they somehow trigger a document.querySelector("script[nonce]") which basically scans the whole DOM, and it happens over and over.
Oh, I can repro on a clean build, mozregression points to bug 2027803 which is believable given the above... Maybe when loading a dupe script we're firing the load event sync or so when we shouldn't, or something along those lines?
Command:
$ ./mach mozregression --good 150 -a "https://www.sfgate.com/local/article/golden-gate-park-leech-22270623.php?utm_source=firefox-newtab-en-us"
Comment 5•3 months ago
|
||
Set release status flags based on info from the regressing bug 2027803
| Assignee | ||
Comment 6•3 months ago
|
||
I can reproduce the issue,
but even with the dom.script_loader.experimental.navigation_cache pref disabled, I'm seeing similar/suspicious behavior on the website.
The network monitor shows that website loads insight.min.js and insight.old.min.js three times (in addition to a crazy amount of continuous requests).
insight.min.js is loaded from gtm.js, and insight.old.min.js is loaded from insight.min.js.
The Inspector shows that there are multiple script elements with the same URLs.
If the pref is enabled, those scripts are continuously loaded forever, like 1000+ in ~10 seconds.
So, the question would be, why the website loads the same script multiple times in the first place, and how it stops at three, and how it doesn't.
Then, as a possible fix, I'll see if delaying the load event by 1 tick for cached scripts helps.
| Assignee | ||
Updated•3 months ago
|
| Assignee | ||
Comment 7•3 months ago
|
||
(In reply to Tooru Fujisawa [:arai] from comment #6)
Then, as a possible fix, I'll see if delaying the load event by 1 tick for cached scripts helps.
Almost same experiment has been done in bug 1999884. It was to avoid a performance regression.
Applying the same change, where the cached script becomes available only after one tick, doesn't resolve the issue.
So, it's not likely about simply sync vs async.
I'll look into how the script is loaded repeatedly.
| Assignee | ||
Comment 8•3 months ago
|
||
I'm seeing that the insight.min.js script is loaded from the onload event handler for the insight.min.js script (or perhaps something else in some case?), in gtm.js, and the nesting is increased by 20 calls for each load.
This is happening regardless of the navigation cache pref.
Still not yet sure why it stops at 3 with the pref disabled tho.
| Assignee | ||
Comment 9•3 months ago
|
||
I cannot handle this shortly.
forwarding to nbp.
Comment 10•2 months ago
|
||
(In reply to Tooru Fujisawa [:arai] from comment #7)
Applying the same change, where the cached script becomes available only after one tick, doesn't resolve the issue.
I tried the same thing, with a minimal reproducing test case, and the change that made it work was to replace the NS_DispatchToCurrentThread by:
if (mDocument) {
mDocument->Dispatch(runnable.forget());
} else {
NS_DispatchToCurrentThread(runnable.forget());
}
Surprisingly this seems to work, but I have no idea why given that the document dispatch should delegate to NS_DispatchToCurrentThread.
Comment 11•2 months ago
|
||
| Comment hidden (obsolete) |
Comment 13•2 months ago
|
||
The problem seems to be a race between the network and the cache.
In the current test case a.js keeps on being loaded first because it is already cached, while b.js is still being fetched by the network and relatively speaking we can iterate as many times over a.js while waiting for b.js.
So, this is not an infinite loop, just a slow network compared to loading resources from our in-memory cache.
I do not know how to fix this properly. One simple idea would be to avoid repeated loads of identical resources from the same document. Thus having a counter associated with the document, and using this counter to prevent matching cache entries introduced by the same document.
However, the same problem could be made to work with 2 pages, one first loading a.js, and a second page loading a.js repeatedly until b.js gets loaded … which would result in the same loading loop.
At this point I would recommend some advocacy to tell Developers not to use this pattern, or to add an extra boolean to check whether the resource has already been loaded too many times, or to throttle their loads with a setTimeout / setInterval.
Updated•2 months ago
|
Comment 14•2 months ago
|
||
Checking locally with and without a delay as done in bug 1999884 yields the following results:
- Without: ~1559 reloads
- With: ~22 reloads
Comment 15•2 months ago
|
||
Maybe we can ship a webcompat intervention for this site otherwise if outreach doesn't work?
Comment 16•2 months ago
|
||
I'm not sure what an intervention could/should do, but if others make a suggestion I'll be happy to help implement one.
Comment 17•2 months ago
|
||
This might be the source of the issue:
https://github.com/linkedin/linkedin-gtm-community-template/blob/b27413acdce0edfd21b46e45f79b147f46c78cea/template.tpl#L210-L216
Updated•2 months ago
|
| Assignee | ||
Comment 18•2 months ago
|
||
(In reply to Nicolas B. Pierron [:nbp] {away} from comment #17)
This might be the source of the issue:
https://github.com/linkedin/linkedin-gtm-community-template/blob/b27413acdce0edfd21b46e45f79b147f46c78cea/template.tpl#L210-L216
The template is already fixed for the infinite loop
https://github.com/linkedin/linkedin-gtm-community-template/commit/d6d31ee6f8880ffd8037e4aea7146ccd7cbba27b
And the corresponding fix doesn't seem to be applied to sfgate's gtm.js
[50, "t", [46],
[22, ["n"],
[46, [53, [52, "u", ["i", "lintrk"]],
[52, "v", [8, "tmsource", "gtmv2"]],
[43, [15, "v"], "conversion_url", [15, "m"]],
[22, [1, [17, [15, "k"], "length"],
[24, [17, [15, "k"], "length"], 3]
],
[46, [2, [15, "k"], "forEach", [7, [51, "", [7, "w"],
[43, [15, "v"], "conversion_id", [15, "w"]],
["u", "track", [15, "v"]]
]]]],
[46, ["u", "track", [15, "v"]]]
]
]],
[46, ["f", "_already_called_lintrk", true, true],
["h", "https://snap.licdn.com/li.lms-analytics/insight.min.js", [15, "q"],
[15, "r"]
]
]
]
],
| Assignee | ||
Comment 19•2 months ago
|
||
Comment 20•2 months ago
|
||
Tooru, why doesn't Chrome have the same problem?
| Assignee | ||
Comment 21•2 months ago
|
||
All browsers are having similar problem, where the same script is loaded multiple times, depending on the time taken by the script load and the event handler call.
The navigation cache makes the situation extremely worse, given that the "load script => onload handler" turnaround time becomes almost immediate, which allows loading the script infinitely.
| Assignee | ||
Comment 22•2 months ago
|
||
I'll apply another patch in bug 2043993 to make the infinite loop less severe (but it will still hang without this bug 's patch)
Updated•2 months ago
|
Comment 24•2 months ago
|
||
Comment 25•2 months ago
|
||
| bugherder | ||
| Assignee | ||
Comment 26•2 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D305776
Updated•2 months ago
|
Comment 27•2 months ago
|
||
firefox-beta Uplift Approval Request
- User impact if declined/Reason for urgency: The content process hangs when the stencil navigation cache pref is enabled and the user visits certain website which uses google tag manager with an outdated linked in template.
The pref is disabled by default, but we're planning to perform an experiment there. - Code covered by automated testing?: no
- Fix verified in Nightly?: yes
- Needs manual QE testing?: no
- Steps to reproduce for manual QE testing: none
- Risk associated with taking this patch: low
- Explanation of risk level: This just excludes certain file from the caching.
The file keeps the current behavior. - String changes made/needed?: none
- Is Android affected?: yes
Updated•2 months ago
|
Updated•2 months ago
|
Comment 28•2 months ago
|
||
| uplift | ||
Updated•1 month ago
|
Description
•