-
Notifications
You must be signed in to change notification settings - Fork 0
/
youtube-cpu-tamer.js
112 lines (109 loc) · 4.7 KB
/
youtube-cpu-tamer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// ==UserScript==
// @name YouTube CPU Tamer
// @name:ja YouTube CPU Tamer
// @name:zh-CN YouTube CPU Tamer
// @namespace knoa.jp
// @description It just reduces CPU usage on YouTube.
// @description:ja YouTubeでのCPU使用率を削減します。
// @description:zh-CN 减少YouTube页面上的CPU利用率。
// @include https://www.youtube.com/*
// @include https://www.youtube.com/embed/*
// @include https://www.youtube-nocookie.com/embed/*
// @version 1.2.0
// @run-at document-start
// @grant none
// ==/UserScript==
/*
[update]
Improved compatibility and fix the bug of not working properly.
[possible]
intervalかrequestAnimationframeをうまく扱えばスパチャ要素を削除しなくてもよくなる?
LIVEスクリプトでやるべきか、こちらでやるべきか。いずれにしても統一が可能かも。
[memo]
interval
interval 自体のインスタンスを減らすためにすべて1つの関数にまとめて実行する。
前面タブなら250msごとに頻度を落とす。
背面タブなら15秒ごとに頻度を落とす。
timeout
前面タブではユーザーインタラクションに関わる場合があるのでそのまま実行する。
背面タブなら interval の次回処理に託してしまう。(前面タブになるまでは15秒間隔)
背面タブの clearInterval は、仮にあったとしても煩雑化を避けるために無視する。
ただし、初期ロード後の10秒間のみ、背面タブでもそのまま実行させる。
@grant
@grant なし Tamer効果なし 背面でも正常
@grant none Tamer効果あり Chrome 背面でたまに起動せず、再生開始しても描画されない!
できればこれでいきたいので試行錯誤してみる
最初の10秒だけ通常起動させてみるとか,15秒をもっと緩めるとか
そもそもいまは他のスクリプトをオフにしてテストしているので注意
リロードじゃなくて新規タブにしないと、特にCMがある場合に再現しない場合も?
@grant none Tamer効果あり Firefox 背面でたまに起動しないが、再生開始すれば描画される?
@grant unsafeWindow Tamer効果あり Chrome 背面でたまに起動しないが、再生開始すれば描画される?
@grant unsafeWindow Tamer効果あり Firefox 正常ぽい
*/
(function(){
const SCRIPTID = 'YouTubeCpuTamer';
console.log(SCRIPTID, location.href);
const BUNDLEDINTERVAL = 250;/* the bundled interval */
const BACKGROUNDINTERVAL = 15*1000;/* take even longer interval on hidden tab */
const ITIALIZINGTIME = 10*1000;/* timeouts should be passed on initial load */
/*
[interval]
*/
/* integrate each of intervals */
/* bundle intervals */
const originalSetInterval = window.setInterval.bind(window);
window.setInterval = function(f, interval, ...args){
//console.log(SCRIPTID, 'original interval:', interval, location.href);
bundle[index] = {
f: f.bind(null, ...args),
interval: interval,
lastExecution: 0,
};
return index++;
};
window.clearInterval = function(id){
//console.log(SCRIPTID, 'clearInterval:', id, location.href);
delete bundle[id];
};
/*
[timeout]
*/
/* kill the background timeouts after initializing */
const originalSetTimeout = window.setTimeout.bind(window);
originalSetTimeout(() => {
window.setTimeout = function(f, timeout, ...args){
//console.log(SCRIPTID, 'timeout:', timeout, location.href);
if(document.hidden){
bundle[index] = {
f: f.bind(null, ...args),
timeout: timeout,
lastExecution: 0,
};
return index++;
}
return originalSetTimeout(f, timeout, ...args);
};
} , ITIALIZINGTIME);
/*
[bundled process]
*/
/* execute bundled intervals */
/* a bunch of intervals does cost so much even if the processes do nothing */
const bundle = {};/* {0: {f, interval, lastExecution}} */
let index = 1;/* use it instead of interval id */
let lastExecution = 0;
originalSetInterval(function(){
const now = Date.now();
if(document.hidden && now < lastExecution + BACKGROUNDINTERVAL) return true;
//console.log(SCRIPTID, 'bundle:', bundle, location.href);
Object.keys(bundle).forEach(id => {
const item = bundle[id];
if(item === undefined) return true;/* it could be occur on tiny deletion chance */
if(now < item.lastExecution + (item.interval || item.timeout)) return true;/* not yet */
item.f();
if(item.interval !== undefined) item.lastExecution = now;
else delete bundle[id];
});
lastExecution = now;
}, BUNDLEDINTERVAL);
})();