Youtube Player perf

Optimizes animation calls for lower GPU/CPU consumption

Author
nopeless
Daily installs
1
Total installs
643
Ratings
2 2 0
Version
0.7
Created
2023-07-23
Updated
2023-08-09
License
MIT
Applies to

Currently the youtube player issues an animation frame for every frame the mouse is hovering the player. This puts a lot of pressure on CPU and GPU. This script somewhat prevents style recalculations and requestAnimationFrame calls

Before:

before

After:

after

Constantly hovering without moving mouse is achieved by hovering the mouse above the volume button

Here are the results using Chrome, 1920x1080@30fps

Specs: Ryzen 5600X, RTX 3080, 2666Mhz 8gb x 4, Windows 10 22H2

Mode proc CPU proc GPU total GPU Additional GPU usage by Desktop Window Manager
IDLE 0.3% 6.4% 6.5% ~x0.02
Default hovering 2.9% 20.5% 36.7% ~x0.8
Perf fix 0.7% 6.5% 7.0% ~x0.1

How is this different from YouTube CPU Tamer?

Different ideologies and different goals

YouTube CPU Tamer is much more intrusive than my script. It changes global setInterval and adjust global requestAnimationFrame calls. In simple terms, the performance optimization they do isn't specific to YouTube. Still, it will give a performance boost over some minor visual artifacts and unexpected behaviors.

On the other hand, my script specifically targets the progress bar updating mechanism

Currently, YouTube will update the progress bar at whatever framerate your monitor is in. I am using a 120hz monitor, so it would be every 8.3ms. Considering that a 30 minute long video has 1800 seconds and there are around 1920 (approx 1800) pixels across the screen, thats 1 pixels per second. And your browser will calculate whatever the refresh rate of your monitor's amount of cpu to update the browser's style and dom (terrible, smelly code)

So the user script here limits the amount of progress bar updates only when a full second changes

Technical Specifications

g: the youtube player object

g.update calls g.updateValue and this is used to change aria-* for the progress bar (as well as other things)

My script adds a cache to this to check for changing values. It marks dirty=true if a value is changed. For example, if you are watching at 1:30 mark, then this value is updated to the same value, "1:30" every time you have a new frame. If you get 1:31, a variable is marked dirty and the userscript considers updating the progress bar.

g.Un is used to change the progress bar's transform (which is both a css and dom reflow, Yuck!) so this is suppressed until dirty is true. There are exactly 4 transforms used for the progress bar update, and its sequential. We can shave a few more cpu resources by checking the count of this function call instead of checking the names.

This has an effect of updating the progress bar every 1 second. As a great side effect of my amazing code the progress bar is updated on the same frame as the timestamp is updated, so it updates EXACTLY once per second, nice!

Other notes

most of the javascript overhead is still run when the mouse is over the player, which would explain the cpu still being high.