Open Bug 1393977 Opened 7 years ago Updated 2 years ago

Compiling the same script again and again for each embedded YouTube video

Categories

(Core :: JavaScript Engine, enhancement, P3)

enhancement

Tracking

()

Performance Impact medium
Tracking Status
firefox57 --- affected

People

(Reporter: mstange, Unassigned)

References

Details

(Keywords: perf)

Steps to reproduce: 1. Go to http://www.rollingstone.com/tv/lists/100-greatest-tv-shows-of-all-time-w439520 2. Scroll down a bit, in order to trigger more YouTube embedded frames to load. Here's a profile, filtered to only show callstacks that include "js::Compile(": http://bit.ly/2xzZiP0 It seems like we're compiling some script for each embedded youtube video, and each compilation takes over 50ms. The "call stack shape" of these compilations look very similar to each other. We don't emit the URL of the script that's being compiled, but I'm guessing that it's https://www.youtube.com/yts/jsbin/player-vflyJ3OmM/en_US/base.js for all of them, because that's the script that starts executing after the compilation is finished.
Whiteboard: [qf]
The JS bytecode cache (Bug 900784) does address this. It is currently disabled behind pref: dom.script_loader.bytecode_cache.enabled
The profile looks the same with that pref enabled: http://bit.ly/2wFkw1L
Hmm.. I might have mixed up my profiles when they started crashing.
Ted, could you take a further look at this and see what can be done here, if anything? (Or suggest someone who could) (It'd be great if the bug 900784 pref-flip helps, but per comment 2 it sounds like it doesn't; and it'd be great to avoid recompiling the same script over and over, if we can.)
Flags: needinfo?(tcampbell)
I took a look at it. The parsing time all seems to be in short <script> tags in the new frames which is why bytecode cache doesn't impact. It looks mostly like various tracking scripts and setting variables for later scripts to use. The reason it seems to come in bursts in the profile is do to a DOM ScriptBlocker while the frame is loaded. Once it is cleared, all the little pieces of JS seem to run. The bytecode cache doesn't apply in this case because the scripts are inline (as well as too small). The perf doesn't look very different in Chrome and I see a lot of Compile Script in their profile. I'm not sure this is very actionable.
Flags: needinfo?(tcampbell)
(In reply to Ted Campbell [:tcampbell] from comment #5) > I'm not sure this is very actionable. In bug 679940, we introduced runtime bytecode sharing. Right now, this is based on hashing the bytecode itself, so it only happens after bytecode compilation and is strictly useful for memory efficiency, not performance improvements. Perhaps one approach would be to change the lookup for the shared bytecode to be keyed on something like http cache entry + file offset, and do the lookup before compiling? For cases like comment 0, this should work just as well as an actual cache.
Flags: needinfo?(tcampbell)
Whiteboard: [qf] → [qf:p2]
Priority: -- → P3
Keywords: perf
See Also: → 1416002
Clearing stale needinfo. Bug 1456220 aims to clean-up Compile APIs in SpiderMonkey which should make it easier to reason about the sort of caches proposed in Comment 6.
Depends on: 1456220
Flags: needinfo?(tcampbell)
This reared its head again (in particularly painful way) in bug 1503620 where we've got a page that tries to load 75 youtube embeds at once.
One thing I'm noticing with Bug 1503620 is that it *seems* the bytecode cache doesn't do anything until document is idle. If you wait a very long time for the first load, it actually significantly faster the second time and the bytecode cache seems to apply.
See Also: → 1503620
Performance Impact: --- → P2
Whiteboard: [qf:p2]
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.