Inspired by kona's YouTube CPU Tamer
Description
This is for all kinds of YouTube applications, including main page, embedded video, live chat, and YouTube Music.
- Faster
- More Stable
- Lower Battery Consumption
Note1: This hijacks Web APIs: setTimeout
, setInterval
, clearTimeout
, and clearInterval
Note2: This uses setInterval(..., 250ms)
instead of requestAnimationFrame
for background running.
Note3: If Timer Throttling2 occurs in background running, the interval would be increased, say 1000ms.
Remarks - Calculation of nextAt
if(o.nextAt + _interval > now) o.nextAt += _interval;
else if(o.nextAt + 2*_interval > now) o.nextAt += 2*_interval;
else if(o.nextAt + 3*_interval > now) o.nextAt += 3*_interval;
else if(o.nextAt + 4*_interval > now) o.nextAt += 4*_interval;
else if(o.nextAt + 5*_interval > now) o.nextAt += 5*_interval;
else o.nextAt = now + _interval;
o.nextAt = now + _interval for now >= o.nextAt + 5*_interval
o.nextAt = now + _interval >= ( o.nextAt + 5*_interval ) + _interval
o.nextAt = o.nextAt + 6*_interval
t1 >= t0 + 6*T
t1 - t0 >= 6T
t1 - t0 <= 1000 (Timer Throtting)
1000 >= 6T
T <= 1000/6 = 166.7 ms
o.nextAt = now + _interval mostly for _interval < 167ms for background running with timer throtting
Remarks - Native Behavior Change
This userscript hijacks setTimeout & setInterval leading different browser behaviors as follows:
Reference Test Code
let baseDT = Date.now()-999999
let f1a=function(){console.log(Date.now()-baseDT, 'hello world f1a')};
let f1b=function(){console.log(Date.now()-baseDT, 'hello world f1b')};
let f1c=function(){console.log(Date.now()-baseDT, 'hello world f1c')};
setTimeout(f1a,100);setTimeout(f1a,100);setTimeout(f1a,100);
setTimeout(f1b,100);setTimeout(f1b,110);setTimeout(f1b,120);
setTimeout(f1c,100);setTimeout(f1c,200);setTimeout(f1c,300);
clearInterval(window.f1sA); clearInterval(window.f2sA);
let [f2a1,f2a2]=(()=>{let w1=0,w2=0;let f1 = ()=>{w1++}, f2= ()=>{w2++}; setTimeout(()=>{console.log(Date.now()-baseDT, '2A' ,w1,w2);},3000); return [f1, f2]; })();
window.f1sA=setInterval(f2a1,70); window.f2sA=setInterval(f2a2, 140);
clearInterval(window.f1sB); clearInterval(window.f2sB);
let [f2b1,f2b2]=(()=>{let w1=0,w2=0;let f1 = ()=>{w1++}, f2= ()=>{w2++}; setTimeout(()=>{console.log(Date.now()-baseDT, '2B', w1,w2);},3000); return [f1, f2]; })();
window.f1sA=setInterval(f2a1,5); window.f2sA=setInterval(f2a2, 10);
Without this userscript (Active Page)
Exceute the code while playing | Execute the code with paused video |
 |  |
With this script (Active Page)
Exceute the code while playing | Execute the code with paused video |
 |  |
- For the same function, repeated calling can be avoided.
- For calling mutliple functions, functions will be delayed due to the activity of browser. [Reduced AnimationFrames for the same amount of time]
- Priortiy is given to the video playing instead of repeating functions
- As functions are delayed, less energy functions would not have to wait a long queue and so can be performed better.
Disclaimer: The suggested results and behaviors are for reference only. They are not guaranteed and depend on your OS and browser.
Further Reading - Timer Throttling
What Happens to setTimeout() / setInterval() Timers Running on Inactive Browser Tabs ?
Heavy throttling of chained JS timers beginning in Chrome 88
Sample Testing Links
Also see...