YouTube CPU Tamer by AnimationFrame

Reduce Browser's Energy Impact for playing YouTube Video

Install this script?
Author's suggested script

You may also like Tabview Youtube.

Install this script
Author
CY Fung
Daily installs
32
Total installs
8,929
Ratings
27 1 0
Version
2022.12.28.1
Created
2021-08-29
Updated
2022-12-28
License
MIT
Applies to

English | 日本語 | 中文

Inspired by kona's YouTube CPU Tamer

Specific Coding Implementation for Boosting Chatroom Message Refresh Perofrmance is provided in Tabview Youtube (v4.2.2 or above)

Compatible with TamperMonkey / Violentmonkey / FireMonkey

Suggested Related Scripts

If you are looking for the way to watch YouTube with least CPU resources in your old machine, please use YouTube Minimal on PC and YouTube Minimal Fixs

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 - Other energy saving measures (NOT RELATED TO THIS USERSCRIPT)

Disable cinematic effect
To disable the cinematic effect of darker dark theme, you can click the video toolbar setting and uncheck the "Ambient Mode"
Microsoft Edge - Efficiency Mode

Efficiency Mode is an active approach to reduce resources. It is useful for laptop.

If you turn on it, one major impact is that it will reduce your "animation" (including DOM rendering) refresh rate.

If you are watching videos with animated subtitles / captions, the effects will be affected especially for fullscreen playing.

Remarks - id

  1. Same as native API, setTimeout and setInterval use same set of nubmering.
  2. Different as native API, clearTimeout('123') / clearInterval('123') would not take effect. In YouTube, there is no such string type int issue.

Remarks - Calculation of nextAt

For the functions with little delayed schedule, they are less/medium energy functions, so just let them run in their own schedule (fixed time interval).

For some cases, we do not know what happen, but it seems cannot follow the schedule it requested. Usually the case is Background Page Timer Throtting.

Assume the call is "5 step behind schedule". i.e. now >= scheduled time + 5T.

Say Timer Throtting to 1s, checking can be just conducted per each 1s.
if the interval is less than 166.7ms, and we found it "5 step behind schedule", just arrange it to the next interval of the current animationframe time.

Imagine there is a heavy energy function with frequent calling per 45ms. If there is video playing and chatroom, it would fall into "5 step behind schedule". It would be still executed but further delayed to now + T (due to scheduling, rather than executing).
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.f1sB=setInterval(f2b1,5); window.f2sB=setInterval(f2b2, 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
The repeating functions are used for maintaining the webpage process in a continuous of usage. They should not be congested in the same time.

Just let video playing becomes the first priority, and let the tasks to insert between AnimationFrames.

This would keep all tasks are alive but not congested at the same instance.
  1. For the same function, repeated calling can be avoided.
  2. Due to the activity of browser, the number of AnimationFrames of the same duration will be reduced.
  3. All functions will be delayed due to reduced calling in AnimationFrames
  4. Priortiy is given to the video playing instead of repeating functions
  5. As all functions are delayed, there will be less total execution time of the heavy energy functions.
  6. In the same process / thread, less energy functions could have more chance to execute without waiting in a long queue with heavy energy functions.
Disclaimer: The suggested results and behaviors are for reference only. They are not guaranteed and depend on your OS and browser.

Remarks - Background Page

Please note that in modern browser, there are penalty mechanisms for the repeating functions running in background.
The calling will be reduced to per each 250ms (at least). Browser will control the Timer Throttling so that it can be as long as 1s, 2s, 5s, 10s, or more.

Remarks - Idle

This will be continously running at each AnimationFrame. It would be energy impact compared to "about:blank", but you would not expect it can be idle in YouTube environment.

For Idle mode, it just check the empty queue and then finish and wait for next AnimationFrame.

Please note that there is no Web Worker in this userscript. It is still under the browser control of the background running behavior.

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...