Yo siempre he tenido un problema con los navegadores cuando uso computadoras de gama baja o media y a medida que voy de mal en peor eligiendo una, con limitaciones de hardware cada vez más rastreras y viles, tuve que recurrir a tácticas como desinstalar software inútil por defecto que consuma recursos de sistema, pero como eso no bastó (teniendo que cargar con la cruz de que la ram está premontada y aún usar un disco duro mecánico, para más INRI), vi una solución que si bien no resuelve mis problemas de rendimiento enteramente, supo ser un alivio parcial que me ha sido de ayuda hasta el momento en que pueda comprar un disco duro SSD. Retomando el punto, muchos navegadores a pesar de su potencia y sus capacidades actuales para ayudar a mejorar su rendimiento para las "tostadoras" modernas, también adolecen de factores externos de programación en los sitios web que opacan sus cualidades...es aquí dónde entra en juego el "script" y cómo me ayudó a mí.
Pero los scripts no funcionan solos, ya que los navegadores tienen extensiones que permiten añadir y gestionarlos para ayudar a mejorar la experiencia de navegación como Tampermonkey, Violent Monkey y otros, aquí voy a compartir algunos que me salvaron el cuello y otros que pueden ser útiles en combinación con algunas extensiones. Primero que nada, las extensiones de navegador para inyectar los scripts son prioritarios, ya mencioné 2 y sitios como greasyfork.org contienen una enorme variedad de scripts de estos que pueden ayudar a marcar una diferencia, sea que tengas una computadora potente o una tostadora:
1.- Reproductores MPV independientes: estos scripts son geniales cuando tienes problemas con un reproductor en línea que de pronto pierde el audio, siempre me molestó que hubiera reproductores con la programación de html5 que fueran insufribles, hasta que los conocí. Este tiene la peculiaridad de que permite descargar el archivo de video con solo dar click derecho, lo que viene bien para descargar videos, películas y series dónde no se puede, aunque esto no funciona con youtube (para eso, existe JDownloader). Copiar y pegar el código en el inyector de scripts de confianza es suficiente, aunque para sacar el verdadero potencial de este script, yo recomiendo encarecidamente tener instalada una extensión de navegador llamada "Open in VLC Media Player", dar click derecho en la misma y elegir que el link se copie al portapapeles, para así pegarlo en una pestaña aparte y disfrutarlo, aunque no funciona en todos los sitios, es cuestión de ensayo y error.
Este otro, aunque no lo he probado, se supone que permite hacer lo mismo en una mayor escala:
2.- ¿Problemas de rendimiento con You Tube? Inyecten cualquiera de estos a su criterio:
3.- ¿Odias la insufrible espera de carga de un archivo PDF? Este script es para tí:
4.- Ante los problemas de rendimiento generales del navegador, esta es la gama de scripts de anuladores de animaciones que tengo:
Esto es todo lo que tengo de scripts por ahora (ya que el sitio no me deja poner el siguiente, por ser pesadísimo), pero recomiendo visitar la biblioteca de Greasy Fork para buscar más, en caso de que quieran mejorar la experiencia de navegación, aún cuando no sea la panacea que están esperando. Un saludo a todos.
Pero los scripts no funcionan solos, ya que los navegadores tienen extensiones que permiten añadir y gestionarlos para ayudar a mejorar la experiencia de navegación como Tampermonkey, Violent Monkey y otros, aquí voy a compartir algunos que me salvaron el cuello y otros que pueden ser útiles en combinación con algunas extensiones. Primero que nada, las extensiones de navegador para inyectar los scripts son prioritarios, ya mencioné 2 y sitios como greasyfork.org contienen una enorme variedad de scripts de estos que pueden ayudar a marcar una diferencia, sea que tengas una computadora potente o una tostadora:
1.- Reproductores MPV independientes: estos scripts son geniales cuando tienes problemas con un reproductor en línea que de pronto pierde el audio, siempre me molestó que hubiera reproductores con la programación de html5 que fueran insufribles, hasta que los conocí. Este tiene la peculiaridad de que permite descargar el archivo de video con solo dar click derecho, lo que viene bien para descargar videos, películas y series dónde no se puede, aunque esto no funciona con youtube (para eso, existe JDownloader). Copiar y pegar el código en el inyector de scripts de confianza es suficiente, aunque para sacar el verdadero potencial de este script, yo recomiendo encarecidamente tener instalada una extensión de navegador llamada "Open in VLC Media Player", dar click derecho en la misma y elegir que el link se copie al portapapeles, para así pegarlo en una pestaña aparte y disfrutarlo, aunque no funciona en todos los sitios, es cuestión de ensayo y error.
- Simple HTML5 Player:
- // ==UserScript==
// @name Simple HTML5 video player
// @description Replaces any default HTML5 player with custom controls
// @grant GM_addStyle
// @include *
// @run-at document-load
// @version 7
// @namespace [Tienes que estar registrado y conectado para ver este vínculo]
// @license MIT
// ==/UserScript==
var videowrapper_init = false;
function HHMMSS(num) {
num = num || 0;
var sec_num = Math.floor(num);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
if (hours<1) {
return minutes+':'+seconds;
}
return hours+':'+minutes+':'+seconds;
}
function fs_status() {
if (document.fullscreenElement) {
return 1;
}
else if (document.webkitFullscreenElement) {
return 1;
}
else if (document.mozFullScreenElement) {
return 1;
}
else return -1;
}
function init_videowrapper() {
var videos = document.getElementsByTagName('video');
for (var i=0; i<videos.length; i++) {
(function(video) {
if (video.controls==true && !video.iswrapped) {
var spacing = 4;
var computedStyle = window.getComputedStyle(video);
video.controls_timeout=false;
video.controls=false;
video.iswrapped=true;
var videowrapper = document.createElement('videowrapper');
videowrapper.className=video.className;
var showui = function() {
videowrapper.classList.add("showui");
}
var hideui = function() {
videowrapper.classList.remove("showui");
}
var peekui = function(duration) {
duration = duration || 1000;
showui();
if (video.controls_timeout) {
clearTimeout(video.controls_timeout);
}
video.controls_timeout = setTimeout(hideui, duration);
}
var showosd = function() {
videowrapper.classList.add("showosd");
}
var hideosd = function() {
videowrapper.classList.remove("showosd");
}
var peekosd = function(duration) {
duration = duration || 1000;
showosd();
if (video.osd_timeout) {
clearTimeout(video.osd_timeout);
}
video.osd_timeout = setTimeout(hideosd, duration);
}
var setosd = function(content) {
videowrapper.setAttribute("data-osd", content)
}
setosd('Loading');
if (computedStyle.position == "absolute") {
videowrapper.className="absolute";
} else {
videowrapper.className="relative";
}
if (video.height>0) {
videowrapper.style.height=video.height;
}
if (video.width>0) {
videowrapper.style.width=video.width;
}
video.className = "iswrapped";
if (video.parentNode==document.body && document.body.childNodes.length==1) {
//document.body.style.display="flex";
//document.body.style.alignItems="center";
//document.body.style.justifyContent="center";
//document.body.style.margin="auto";
//document.body.style.height="100vh";
document.body.className="videobody";
}
if (video.parentNode!=videowrapper) {
video.parentNode.insertBefore(videowrapper, video);
videowrapper.appendChild(video);
}
var controls = document.createElement('controls');
video.parentNode.insertBefore(controls, video.nextSibling);
var playbutton = document.createElement('button');
controls.appendChild(playbutton);
playbutton.innerHTML="";
playbutton.style.left = spacing + "px";
var timestamp = document.createElement('span');
controls.appendChild(timestamp);
timestamp.innerHTML="0:00/0:00";
timestamp.style.left = (spacing + playbutton.clientWidth + spacing) + "px";
var fsbutton = document.createElement('button');
controls.appendChild(fsbutton);
fsbutton.innerHTML="□";
fsbutton.style.right = spacing + "px";
var volumebar = document.createElement('input');
controls.appendChild(volumebar);
volumebar.type="range";
volumebar.min=0;
volumebar.max=1;
volumebar.step=0.01;
volumebar.value=0.5;
volumebar.innerHTML="";
volumebar.style.width="50px";
volumebar.style.right= (spacing + fsbutton.clientWidth + spacing) + "px";
var mutebutton = document.createElement('button');
controls.appendChild(mutebutton);
mutebutton.innerHTML="";
mutebutton.style.right=(spacing + volumebar.clientWidth + spacing + fsbutton.clientWidth + spacing) + "px";
var seekbar = document.createElement('input');
controls.appendChild(seekbar);
seekbar.type="range";
seekbar.value=0;
seekbar.step=0.01;
seekbar.innerHTML="";
seekbar.hidden = true;
var header = document.createElement('header');
video.parentNode.insertBefore(header, video.nextSibling);
var label = document.createElement('label');
header.appendChild(label);
label.innerHTML="Loading...";
/*
var savebutton = document.createElement('a');
controls.appendChild(savebutton);
savebutton.innerHTML="🡇";
savebutton.style.lineHeight="32px";
savebutton.style.position="absolute";
savebutton.style.right="8px";
savebutton.style.bottom="0";
savebutton.style.border="none";
savebutton.style.paddingTop="0";
savebutton.style.paddingBottom="0";
savebutton.style.paddingLeft="4px";
savebutton.style.paddingRight="4px";
savebutton.style.background="none";
savebutton.style.fontFamily="Segoe UI Symbol";
savebutton.style.fontSize="18px";
savebutton.style.margin="0";
savebutton.style.height="32px";
savebutton.href=video.currentSrc;
savebutton.download="";
*/
var playvideo = function() {
video.play();
if (video.livemode) {
video.currentTime = video.duration - 3;
}
}
playbutton.addEventListener("click", function() {
if (video.paused == true) {
playvideo();
} else {
video.pause();
}
peekui(3000);
});
video.addEventListener("click", function() {
if (video.paused == true) {
playvideo();
} else {
if (!video.livemode) {
video.pause();
}
}
peekui(3000);
});
video.addEventListener("play", function() {
setosd(playbutton.innerHTML);
peekosd(1000);
playbutton.innerHTML = "❚❚";
//controls.className="playing";
videowrapper.classList.remove("paused");
videowrapper.classList.add("playing");
});
video.addEventListener("pause", function() {
setosd(playbutton.innerHTML);
peekosd(3000);
playbutton.innerHTML = "";
//controls.className="paused";
videowrapper.classList.remove("playing");
videowrapper.classList.add("paused");
});
var updatetimestamp = function() {
if (video.livemode) {
var buffer = Math.round(video.duration - video.currentTime);
timestamp.innerHTML = "Buffer: " + buffer + "s";
} else {
timestamp.innerHTML = HHMMSS(video.currentTime) + "/" + HHMMSS(video.duration);
}
}
video.addEventListener("timeupdate", function() {
updatetimestamp();
});
video.addEventListener("durationchange", function() {
updatetimestamp();
});
mutebutton.addEventListener("click", function() {
if (video.muted == false) {
video.muted = true;
} else {
video.muted = false;
}
});
var togglefs = function() {
if (fs_status()>0) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
else {
if (videowrapper.requestFullscreen) {
videowrapper.requestFullscreen();
} else if (videowrapper.mozRequestFullScreen) {
videowrapper.mozRequestFullScreen(); // Firefox
} else if (videowrapper.webkitRequestFullscreen) {
videowrapper.webkitRequestFullscreen(); // Chrome and Safari
}
}
};
fsbutton.addEventListener("click", togglefs);
videowrapper.addEventListener("dblclick", togglefs);
seekbar.addEventListener("input", function() {
var time = video.duration * (seekbar.value / 100);
video.currentTime = time;
});
video.addEventListener("timeupdate", function() {
var value = (100 / video.duration) * video.currentTime;
var progress = (video.currentTime / video.duration);
seekbar.value = value;
//seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + progress + ', var(--range-progress-color)), color-stop(' + progress + ', var(--range-background-color)))';
});
var updatebuffer = function() {
if (video.duration == Infinity || video.hls || video.livemode) {
video.livemode = true;
}
if (video.livemode) {
seekbar.hidden = true;
label.innerHTML = "Live";
} else {
var start = video.buffered.length>0 ? ( video.buffered.start(0) / video.duration) : 0;
var end = video.buffered.length>0 ? (video.buffered.end(0) / video.duration) : 0;
seekbar.hidden = false;
seekbar.style.left = (spacing + playbutton.clientWidth + spacing + timestamp.clientWidth + spacing) + "px";
seekbar.style.right= (spacing + mutebutton.clientWidth + spacing + volumebar.clientWidth + spacing + fsbutton.clientWidth + spacing) + "px";
seekbar.style.width='calc(100% - ' + seekbar.style.left + ' - ' + seekbar.style.right + ')';
seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + start + ', var(--range-background-color)), color-stop(' + start + ', var(--range-progress-color)), color-stop(' + end + ', var(--range-progress-color)), color-stop(' + end + ', var(--range-background-color)))';
if (video.currentSrc && video.currentSrc.length>0) {
label.innerHTML = decodeURIComponent(video.currentSrc.split("/").pop());
}
}
if (video.videoHeight>0) {
videowrapper.classList.remove("audiomode");
videowrapper.classList.add("videomode");
} else {
videowrapper.classList.remove("videomode");
videowrapper.classList.add("audiomode");
}
};
video.addEventListener("timeupdate", updatebuffer);
video.addEventListener("canplay", updatebuffer);
video.addEventListener("progress", updatebuffer);
video.addEventListener("canplaythrough", updatebuffer);
seekbar.addEventListener("mousedown", function() {
seekbar.paused = video.paused;
video.pause();
});
// Play the video when the slider handle is dropped
seekbar.addEventListener("mouseup", function() {
if (!seekbar.paused) {
video.play();
}
});
volumebar.addEventListener("input", function() {
video.volume = volumebar.value;
});
video.addEventListener('wheel', function(e) {
e.preventDefault();
var volumedelta = 0.10;
if (e.deltaY < 0) {
video.volume = Math.min(video.volume+volumedelta, 1);
}
if (e.deltaY > 0) {
video.volume = Math.max(video.volume-volumedelta, 0);
}
volumebar.value = video.volume;
var volumedata = Math.round(video.volume*100) + "%";
setosd(volumedata);
peekosd(1000);
});
var updatevolume = function() {
if (video.muted || video.volume==0) {
mutebutton.innerHTML = "";
} else {
mutebutton.innerHTML = "";
}
volumebar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + video.volume + ', var(--range-progress-color)), color-stop(' + video.volume + ', var(--range-background-color)))';
localStorage.setItem("videovolume", video.volume);
}
video.addEventListener("volumechange", updatevolume);
volumebar.value = localStorage.getItem("videovolume", video.volume);
video.volume = volumebar.value;
videowrapper.addEventListener("mousemove", function() {
peekui(1000);
//seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + progress + ', var(--range-progress-color)), color-stop(' + progress + ', var(--range-background-color)))';
});
updatebuffer();
updatevolume();
//seekbar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + seekbar.value / 100 + ', var(--range-progress-color)), color-stop(' + seekbar.value / 100 + ', var(--range-background-color)))';
//volumebar.style.background = '-webkit-gradient( linear, left top, right top, color-stop(' + video.volume + ', var(--range-progress-color)), color-stop(' + video.volume + ', var(--range-background-color)))';
}
})(videos[i])
}
}
var stylesheet = `
body.videobody {
height: 100vh;
margin: 0;
padding: 0;
display: flex;
}
videowrapper button {
font-family: "Segoe UI Symbol", system-ui, sans-serif !important;
}
videowrapper label, videowrapper:before {
font-family: system-ui, sans-serif !important;
}
videowrapper {
--background-color: rgba(0, 0, 0, 0.5);
--controls-color: [Tienes que estar registrado y conectado para ver este vínculo];
--range-progress-color: [Tienes que estar registrado y conectado para ver este vínculo];
--range-background-color: [Tienes que estar registrado y conectado para ver este vínculo];
display: block;
font-size: 0px;
position: relative;
width: auto;
height: auto;
background: inherit;
}
videowrapper.absolute {
display: flex;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
.videobody videowrapper.absolute {
position: relative;
}
videowrapper video.iswrapped {
position: relative;
max-height: 100vh;
}
videowrapper:-webkit-full-page-media {
width: auto;
height: auto;
}
videowrapper:-webkit-full-screen {
width: 100%;
height: 100%;
}
videowrapper video::-webkit-media-controls-enclosure {
display:none !important;
}
videowrapper:-webkit-full-screen controls,
videowrapper:-webkit-full-screen header {
z-index: 2147483647;
}
videowrapper controls > *,
videowrapper header > * {
color: var(--controls-color);
/* mix-blend-mode: difference; */
background: none;
outline: none;
line-height: 32px;
position: absolute;
font-family: monospace;
}
videowrapper controls,
videowrapper header {
overflow: hidden;
white-space: nowrap;
transition: all 0.5s ease !important;
background-color: var(--background-color) !important;
height: 32px !important;
width: 100% !important;
display: block !important;
position: absolute !important;
cursor: default !important;
font-size: 18px !important;
user-select: none;
}
videowrapper controls {
bottom: 0px !important;
}
videowrapper header {
top: 0px !important;
}
videowrapper controls,
videowrapper header {
opacity: 1;
}
videowrapper.playing controls,
videowrapper.playing header {
opacity: 0;
}
videowrapper controls:hover, videowrapper.showui controls, videowrapper.paused controls, videowrapper.audiomode controls,
videowrapper header:hover, videowrapper.showui header, videowrapper.paused header, videowrapper.audiomode header {
opacity: 1;
}
videowrapper button, videowrapper label {
line-height: 32px !important;
position: absolute !important;
bottom: 0px !important;
background-color: none !important;
font-size: 18px !important;
height: 32px !important;
border: none !important;
margin: 0 !important;
}
videowrapper button {
width: 32px !important;
padding: 0 !important;
}
videowrapper input[type=range] {
line-height: 32px !important;
position: absolute !important;
background-color: var(--range-background-color) !important;
bottom: 10px !important;
height: 10px !important;
border: none !important;
margin: 0px !important;
border-radius: 6px !important;
-webkit-appearance: none !important;
}
videowrapper input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none !important;
background-color: var(--controls-color);
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
}
videowrapper.audiomode video:-webkit-full-page-media {
width: 600px;
}
videowrapper:before {
content: attr(data-osd);
position: absolute;
left: 50%;
top: calc(50%);
color: white;
-webkit-text-stroke: 3px [Tienes que estar registrado y conectado para ver este vínculo];
font-size: 64px;
font-weight: bold;
font-style: normal;
z-index: 1;
transform: translate(-50%, -50%);
pointer-events: none;
opacity: 0;
}
videowrapper.audiomode:before,
videowrapper.showosd:before,
videowrapper.paused:before {
opacity: 1;
}
videowrapper label {
right: 0;
min-width: 100%;
text-align: left;
box-sizing: border-box;
width: 100% !important;
padding: 0px 8px !important;
}
`;
function init() {
if (videowrapper_init) {
console.log("Cannot init_videowrapper twice!");
return;
}
videowrapper_init = true;
if (typeof GM_addStyle != "undefined") {
GM_addStyle (stylesheet);
} else {
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = stylesheet;
document.head.appendChild(css);
}
init_videowrapper();
if (typeof unsafeWindow != "undefined") {
unsafeWindow.init_videowrapper = init_videowrapper;
}
}
init();
Este otro, aunque no lo he probado, se supone que permite hacer lo mismo en una mayor escala:
- Click on video thumbnail to play in MPV:
- // ==UserScript==
// @name Click on video thumbnail to play in MPV
// @name:ru Нажми на митиатюру для проигрывания в MPV
// @namespace nsinister.scripts.videothumb2mpv
// @match [Tienes que estar registrado y conectado para ver este vínculo]
// @match [Tienes que estar registrado y conectado para ver este vínculo]
// @grant none
// @version 0.1
// @author nSinister
// @license MIT
// @description Opens videos in external player (mpv) by simply clicking on a thumbnail.
// @description:ru Проигрывает ролики во внешнем плеере (mpv) по нажатию на миниатюру
//
// ==/UserScript==
"use strict";
let observer;
let listeners = [];
let sites = {
"youtube.com": { sel: "a.ytd-thumbnail", url: "https://www.youtube.com", needsFullUrl: true },
"vimeo.com": { sel: "a.iris_video-vital__overlay", url: "https://vimeo.com", needsFullUrl: false },
};
// Watches for new elements based on selector to appear on page and assigns a function to them
function ready(selector, func) {
listeners.push({ selector: selector, func: func });
if (!observer) {
observer = new MutationObserver(checkDOM);
observer.observe(document.documentElement, { childList: true, subtree: true });
}
checkDOM();
}
function checkDOM() {
for (let i = 0, len = listeners.length, listener, elements; i < len; i++) {
listener = listeners[i];
elements = document.querySelectorAll(listener.selector);
for (let j = 0, jlen = elements.length, element; j < jlen; j++) {
element = elements[j];
if (!element.ready) {
element.ready = true;
listener.func.call(element, element);
}
}
}
}
// Replaces [Tienes que estar registrado y conectado para ver este vínculo] hyperlinks with [Tienes que estar registrado y conectado para ver este vínculo] and overrides click event
function replaceLink(node, site) {
if(node) {
let hrefval = node.getAttribute('href');
if (hrefval == null || hrefval.startsWith("mpv"))
return;
let newval = "mpv://" + btoa( (site.needsFullUrl ? site.url : "") + hrefval);
node.setAttribute('href', newval);
node.addEventListener('click', function(event){
event.preventDefault();
event.stopPropagation();
location.href = newval;
});
}
}
// Detects and returns current site from the list of known websites
function detectSite(sites) {
let site;
for (let s in sites) {
site = sites[s];
if (location.href.includes(s)) {
return site;
}
}
return null;
}
let site = detectSite(sites)
if (site) {
ready(site.sel, function(element) {
replaceLink(element, site);
});
}
2.- ¿Problemas de rendimiento con You Tube? Inyecten cualquiera de estos a su criterio:
- You Tube CPU Tamer:
- // ==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 [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @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);
})();
- Youtube Tamer by Animation Frame:
- // ==UserScript==
// @name YouTube CPU Tamer by AnimationFrame
// @name:en YouTube CPU Tamer by AnimationFrame
// @name:jp YouTube CPU Tamer by AnimationFrame
// @name:zh-tw YouTube CPU Tamer by AnimationFrame
// @name:zh-cn YouTube CPU Tamer by AnimationFrame
// @namespace http://tampermonkey.net/
// @version 2021.09.30
// @license MIT License
// @description Reduce Browser's Energy Impact for playing YouTube Video
// @description:en Reduce Browser's Energy Impact for playing YouTube Video
// @description:jp YouTubeビデオのエネルギーインパクトを減らす
// @description:zh-tw 減少YouTube影片所致的能源消耗
// @description:zh-cn 减少YouTube影片所致的能源消耗
// @author CY Fung
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @icon [Tienes que estar registrado y conectado para ver este vínculo]
// @run-at document-start
// @grant none
// ==/UserScript==
(function $$() {
'use strict';
const [window, document] = new Function('return [window, document];')(); // real window & document object
const hkey_script = 'nzsxclvflluv';
if (window[hkey_script]) return; // avoid duplicated scripting
window[hkey_script] = true;
//if (!document.documentElement) return window.requestAnimationFrame($$); // not required to check documentElement ready or not
// copies of native functions
const $$requestAnimationFrame = window.requestAnimationFrame.bind(window); // core looping
const $$setTimeout = window.setTimeout.bind(window); // for race
const $$setInterval = window.setInterval.bind(window); // for background execution
const $$clearTimeout = window.clearTimeout.bind(window); // for native clearTimeout
const $$clearInterval = window.clearInterval.bind(window); // for native clearInterval
const $busy = Symbol('$busy');
// Number.MAX_SAFE_INTEGER = 9007199254740991
const INT_INITIAL_VALUE = 8192; // 1 ~ {INT_INITIAL_VALUE} are reserved for native setTimeout/setInterval
const SAFE_INT_LIMIT = 2251799813685248; // in case cid would be used for multiplying
const SAFE_INT_REDUCED = 67108864; // avoid persistent interval handlers with cids between {INT_INITIAL_VALUE + 1} and {SAFE_INT_REDUCED - 1}
let mi = INT_INITIAL_VALUE; // skip first {INT_INITIAL_VALUE} cids to avoid browser not yet initialized
const sb = {};
const sFunc = (prop) => {
return (func, ms, ...args) => {
mi++; // start at {INT_INITIAL_VALUE + 1}
if( mi > SAFE_INT_LIMIT ) mi = SAFE_INT_REDUCED; // just in case
let handler = args.length > 0 ? func.bind(null, ...args) : func; // original func if no extra argument
handler[$busy] || ( handler[$busy] = 0 );
sb[mi] = {
handler,
[prop]: ms, // timeout / interval; value can be undefined
nextAt: Date.now() + (ms > 0 ? ms : 0) // overload for setTimeout(func);
};
return mi;
};
};
const rm = function (jd) {
if (!jd) return; // native setInterval & setTimeout start from 1
let o = sb[jd];
if (typeof o != 'object'){ // to clear the same cid is unlikely to happen || requiring nativeFn is unlikely to happen
if (jd <= INT_INITIAL_VALUE) this.nativeFn(jd); // only for clearTimeout & clearInterval
return;
}
for (let k in o) o[k] = null;
o = null;
sb[jd] = null;
delete sb[jd];
};
window.setTimeout = sFunc('timeout');
window.setInterval = sFunc('interval');
window.clearTimeout = rm.bind({nativeFn: $$clearTimeout});
window.clearInterval = rm.bind({nativeFn: $$clearInterval});
// window.clearInterval = window.clearTimeout = rm;
const delay16ms = ( resolve => $$setTimeout(resolve, 16) );
const pf = (
handler => new Promise(resolve => {
// try catch is not required - no further execution on the handler
// For function handler with high energy impact, discard 1st, 2nd, ... (n-1)th calling: (a,b,c,a,b,d,e,f) => (c,a,b,d,e,f)
// For function handler with low energy impact, discard or not discard depends on system performance
if (handler[$busy] == 1) handler();
handler[$busy]--;
handler = null; // remove the reference of `handler`
resolve();
resolve = null; // remove the reference of `resolve`
})
);
let jf, tf, toResetFuncHandlers = false;
let bgExecutionAt = 0; // set at 0 to trigger tf in background startup when requestAnimationFrame is not responsive
tf = () => {
if (toResetFuncHandlers) {
toResetFuncHandlers = false;
for (let jb in sb) sb[jb].handler[$busy] = 0; // including the functions with error
}
new Promise(resolveApp1 => {
// microTask [Tienes que estar registrado y conectado para ver este vínculo]
let now = Date.now();
bgExecutionAt = now + 160; // if requestAnimationFrame is not responsive (e.g. background running)
let promisesF = [];
for (let jb in sb) {
const o = sb[jb];
let {
handler,
// timeout,
interval,
nextAt
} = o;
if (now < nextAt) continue;
handler[$busy]++;
promisesF.push(handler);
if (interval > 0) { // prevent undefined, zero, negative values
const _interval = +interval; // convertion from string to number if necessary; decimal is acceptable
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;
} else {
// jb in sb must > INT_INITIAL_VALUE
rm(jb); // remove timeout
}
}
resolveApp1(promisesF);
}).then(promisesF => {
// microTask [Tienes que estar registrado y conectado para ver este vínculo]
bgExecutionAt = Date.now() + 160; // if requestAnimationFrame is not responsive (e.g. background running)
let hidden = document.hidden; // background running would not call requestAnimationFrame
if (promisesF.length == 0) { // no handler functions
// requestAnimationFrame when the page is active
// execution interval is no less than AnimationFrame
return hidden || jf();
}
if (!hidden) {
let ret2 = new Promise(delay16ms);
let promises = promisesF.map(pf); //microTasks
let ret1 = Promise.all(promises);
let race = Promise.race([ret1, ret2]);
// ensure jf must be called after 16ms to maintain visual changes in high fps.
// >16ms examples: repaint/reflow, change of style/content
race.then(jf);
promises.length = 0;
} else {
promisesF.forEach(pf);
}
promisesF.length = 0;
});
};
(jf = $$requestAnimationFrame.bind(window, tf))();
$$setInterval(() => {
// no response of requestAnimationFrame; e.g. running in background
// toResetFuncHandlers = true;
if (Date.now() > bgExecutionAt) {
toResetFuncHandlers = true;
tf();
}
}, 250);
// i.e. 4 times per second for background execution - to keep YouTube application functional
// if there is Timer Throttling for background running, the execution become the same as native setTimeout & setInterval.
window.addEventListener("yt-navigate-finish", () => {
toResetFuncHandlers = true; // ensure all function handlers can be executed after YouTube navigation.
}, true); // capturing event - to let it runs before all everything else.
// Your code here...
})();
- Youtube Auto-Quick Buffer:
- // ==UserScript==
// @name Youtube Auto Quick Buffer
// @namespace https://greasyfork.org/en/users/8935-daniel-jochem?sort=ratings
// @description Quickens the bufferer on all Youtube videos
// @include https://www.youtube.com/watch?*
// @grant none
// @run-at document-end
// @version 1.4
// ==/UserScript==
// reload script on page change using spf events (normal youtube)
window.addEventListener("spfdone", function() {
main();
});
// reload script on page change using youtube polymer fire events (material youtube)
window.addEventListener("yt-page-data-updated", function() {
main();
});
main();
function main() {
if (isPlayerAvailable()) {
if (document.URL.indexOf("&gl=CA") === -1) {
window.location = document.URL + "&gl=CA";
}
}
}
function isPlayerAvailable() { // true if a youtube video is available ( false if live video)
return /https:\/\/www\.youtube\.com\/watch\?v=.*/.test(document.location.href) && document.getElementById('live-chat-iframe') === null;
}
- YouTube Live CPU Tamer:
- // ==UserScript==
// @name YouTube Live CPU Tamer
// @name:ja YouTube Live CPU Tamer
// @name:zh-CN YouTube Live CPU Tamer
// @description It reduces the high CPU usage on Super Chats with nothing to lose.
// @description:ja スーパーチャットによる高いCPU使用率を削減します。見た目は何も変わりません。
// @description:zh-CN 降低超级聊天的高CPU利用率。外观完全没有变化。
// @namespace knoa.jp
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @include [Tienes que estar registrado y conectado para ver este vínculo]
// @version 2.0.6
// @grant none
// ==/UserScript==
(function(){
const SCRIPTID = 'YouTubeLiveCpuTamer';
const SCRIPTNAME = 'YouTube Live CPU Tamer';
const DEBUG = false;/*
[update] 2.0.6
No updates on code. Just confirmed to work.
[bug]
[todo]
[possible]
[research]
Proxyを使うとbackgroundトリック不要?CPU使用に対する効果はある?
放送開始前の待機画面でもHelper(GPU)が食ってる件
リアルタイム視聴時のほうがHelper(GPU)が消費する件は新着確認js処理のせいか
[memo]
none:80+30=110 => tame:50+20=70 => remove:30+15=45
*/
if(console.time) console.time(SCRIPTID);
const MS = 1, SECOND = 1000*MS, MINUTE = 60*SECOND, HOUR = 60*MINUTE, DAY = 24*HOUR, WEEK = 7*DAY, MONTH = 30*DAY, YEAR = 365*DAY;
const THROTTLE = 1000*MS;
const site = {
targets: {
itemsNode: () => $('yt-live-chat-ticker-renderer [Tienes que estar registrado y conectado para ver este vínculo]'),
},
get: {
tickerItemInsideContainers: (items) => items.querySelectorAll('.yt-live-chat-ticker-renderer[role="button"] [Tienes que estar registrado y conectado para ver este vínculo]'),/* existing items */
tickerItemInsideContainer: (node) => node.querySelector('.yt-live-chat-ticker-renderer[role="button"] [Tienes que estar registrado y conectado para ver este vínculo]'),/* for observer */
},
};
let elements = {};
const core = {
initialize: function(){
elements.html = document.documentElement;
elements.html.classList.add(SCRIPTID);
text.setup(texts, top.document.documentElement.lang);
core.ready();
core.addStyle('style');
},
ready: function(){
core.getTargets(site.targets).then(() => {
log("I'm ready.");
core.observeTickerItems();
core.prepareRemoveTickersButton();
});
},
observeTickerItems: function(){
let containers = site.get.tickerItemInsideContainers(elements.itemsNode);
Array.from(containers).forEach(container => {
core.observeTickerItemInsideContainer(container);
});
observe(elements.itemsNode, function(records){
records.forEach(r => r.addedNodes.forEach(node => {
let container = site.get.tickerItemInsideContainer(node);
if(container) core.observeTickerItemInsideContainer(container);
}));
});
},
observeTickerItemInsideContainer: function(container){
container.parentNode.style.background = container.style.background;
let lastUpdated = Date.now();
observe(container, function(records){
let now = Date.now();
if(now - lastUpdated < THROTTLE) return;
lastUpdated = now;
container.parentNode.style.background = container.style.background;
}, {attributes: true, attributeFilter: ['style']});
},
prepareRemoveTickersButton: function(){
let button = createElement(html.removeTickersButton());
button.addEventListener('click', function(e){
elements.itemsNode.parentNode.removeChild(elements.itemsNode);
});
elements.itemsNode.parentNode.appendChild(button);
},
getTarget: function(selector, retry = 10){
const key = selector.name;
const get = function(resolve, reject, retry){
let selected = selector();
if(selected && selected.length > 0) selected.forEach((s) => s.dataset.selector = key);/* elements */
else if(selected instanceof HTMLElement) selected.dataset.selector = key;/* element */
else if(--retry) return log(`Not found: ${key}, retrying... (${retry})`), setTimeout(get, 1000, resolve, reject, retry);
else return reject(selector);
elements[key] = selected;
resolve(selected);
};
return new Promise(function(resolve, reject){
get(resolve, reject, retry);
}).catch(selector => {
log(`Not found: ${key}, I give up.`);
});
},
getTargets: function(selectors, retry = 10){
return Promise.all(Object.values(selectors).map(selector => core.getTarget(selector, retry)));
},
addStyle: function(name = 'style'){
if(html[name] === undefined) return;
let style = createElement(html[name]());
document.head.appendChild(style);
if(elements[name] && elements[name].isConnected) document.head.removeChild(elements[name]);
elements[name] = style;
},
};
const texts = {
'remove tickers by ${SCRIPTNAME}': {
en: () => `remove tickers by ${SCRIPTNAME}`,
ja: () => `履歴欄を削除 by ${SCRIPTNAME}`,
zh: () => `删除历史记录栏 by ${SCRIPTNAME}`,
},
};
const html = {
removeTickersButton: () => `<button id="${SCRIPTID}-removeTickers" title="${text('remove tickers by ${SCRIPTNAME}')}">╳</button>`,
style: () => `
<style type="text/css">
yt-live-chat-ticker-renderer [Tienes que estar registrado y conectado para ver este vínculo] > *{
border-radius: 999px;
}
yt-live-chat-ticker-renderer [Tienes que estar registrado y conectado para ver este vínculo] > * > [Tienes que estar registrado y conectado para ver este vínculo]{
background: none !important;
}
yt-live-chat-ticker-renderer #${SCRIPTID}-removeTickers{
cursor: pointer;
position: absolute;
top: 50%;
left: 5px;
transform: translateY(-50%);
border-radius: 100vmax;
border: none;
background: white;
filter: drop-shadow(0px 0px 1px rgba(0,0,0,.25));
height: 20px;
width: 20px;
padding: 0 !important;
opacity: 0;
transition: opacity 250ms;
pointer-events: none;
}
yt-live-chat-ticker-renderer:hover [Tienes que estar registrado y conectado para ver este vínculo][hidden] ~ #${SCRIPTID}-removeTickers{
opacity: 1;
pointer-events: auto;
}
yt-live-chat-ticker-renderer [Tienes que estar registrado y conectado para ver este vínculo] > *{
transition: transform 250ms;
}
yt-live-chat-ticker-renderer:hover [Tienes que estar registrado y conectado para ver este vínculo] > *{
transform: translateX(5px);
}
</style>
`,
};
const text = function(key, ...args){
if(text.texts[key] === undefined){
log('Not found text key:', key);
return key;
}else return text.texts[key](args);
};
text.setup = function(texts, language){
let languages = [...window.navigator.languages];
if(language) languages.unshift(...String(language).split('-').map((p,i,a) => a.slice(0,1+i).join('-')).reverse());
if(!languages.includes('en')) languages.push('en');
languages = languages.map(l => l.toLowerCase());
Object.keys(texts).forEach(key => {
Object.keys(texts[key]).forEach(l => texts[key][l.toLowerCase()] = texts[key][l]);
texts[key] = texts[key][languages.find(l => texts[key][l] !== undefined)] || (() => key);
});
text.texts = texts;
};
const $ = function(s, f){
let target = document.querySelector(s);
if(target === null) return null;
return f ? f(target) : target;
};
const $$ = function(s, f){
let targets = document.querySelectorAll(s);
return f ? Array.from(targets).map(t => f(t)) : targets;
};
const createElement = function(html = '<span></span>'){
let outer = document.createElement('div');
outer.innerHTML = html;
return outer.firstElementChild;
};
const observe = function(element, callback, options = {childList: true, attributes: false, characterData: false, subtree: false}){
let observer = new MutationObserver(callback.bind(element));
observer.observe(element, options);
return observer;
};
const log = function(){
if(!DEBUG) return;
let l = log.last = log.now || new Date(), n = log.now = new Date();
let error = new Error(), line = log.format.getLine(error), callers = log.format.getCallers(error);
//console.log(error.stack);
console.log(
SCRIPTID + ':',
/* 00:00:00.000 */ n.toLocaleTimeString() + '.' + n.getTime().toString().slice(-3),
/* +0.000s */ '+' + ((n-l)/1000).toFixed(3) + 's',
/* :00 */ ':' + line,
/* caller.caller */ (callers[2] ? callers[2] + '() => ' : '') +
/* caller */ (callers[1] || '') + '()',
...arguments
);
};
log.formats = [{
name: 'Firefox Scratchpad',
detector: /MARKER@Scratchpad/,
getLine: (e) => e.stack.split('\n')[1].match(/([0-9]+):[0-9]+$/)[1],
getCallers: (e) => e.stack.match(/^[^@]*(?=@)/gm),
}, {
name: 'Firefox Console',
detector: /MARKER@debugger/,
getLine: (e) => e.stack.split('\n')[1].match(/([0-9]+):[0-9]+$/)[1],
getCallers: (e) => e.stack.match(/^[^@]*(?=@)/gm),
}, {
name: 'Firefox Greasemonkey 3',
detector: /\/gm_scripts\//,
getLine: (e) => e.stack.split('\n')[1].match(/([0-9]+):[0-9]+$/)[1],
getCallers: (e) => e.stack.match(/^[^@]*(?=@)/gm),
}, {
name: 'Firefox Greasemonkey 4+',
detector: /MARKER@user-script:/,
getLine: (e) => e.stack.split('\n')[1].match(/([0-9]+):[0-9]+$/)[1] - 500,
getCallers: (e) => e.stack.match(/^[^@]*(?=@)/gm),
}, {
name: 'Firefox Tampermonkey',
detector: /MARKER@moz-extension:/,
getLine: (e) => e.stack.split('\n')[1].match(/([0-9]+):[0-9]+$/)[1] - 6,
getCallers: (e) => e.stack.match(/^[^@]*(?=@)/gm),
}, {
name: 'Chrome Console',
detector: /at MARKER \(<anonymous>/,
getLine: (e) => e.stack.split('\n')[2].match(/([0-9]+):[0-9]+\)?$/)[1],
getCallers: (e) => e.stack.match(/[^ ]+(?= \(<anonymous>)/gm),
}, {
name: 'Chrome Tampermonkey',
detector: /at MARKER \(chrome-extension:.*?\/userscript.html\?id=/,
getLine: (e) => e.stack.split('\n')[2].match(/([0-9]+):[0-9]+\)?$/)[1] - 5,
getCallers: (e) => e.stack.match(/[^ ]+(?= \(chrome-extension:)/gm),
}, {
name: 'Chrome Extension',
detector: /at MARKER \(chrome-extension:/,
getLine: (e) => e.stack.split('\n')[2].match(/([0-9]+):[0-9]+\)?$/)[1],
getCallers: (e) => e.stack.match(/[^ ]+(?= \(chrome-extension:)/gm),
}, {
name: 'Edge Console',
detector: /at MARKER \(eval/,
getLine: (e) => e.stack.split('\n')[2].match(/([0-9]+):[0-9]+\)$/)[1],
getCallers: (e) => e.stack.match(/[^ ]+(?= \(eval)/gm),
}, {
name: 'Edge Tampermonkey',
detector: /at MARKER \(Function/,
getLine: (e) => e.stack.split('\n')[2].match(/([0-9]+):[0-9]+\)$/)[1] - 4,
getCallers: (e) => e.stack.match(/[^ ]+(?= \(Function)/gm),
}, {
name: 'Safari',
detector: /^MARKER$/m,
getLine: (e) => 0,/*e.lineが用意されているが最終呼び出し位置のみ*/
getCallers: (e) => e.stack.split('\n'),
}, {
name: 'Default',
detector: /./,
getLine: (e) => 0,
getCallers: (e) => [],
}];
log.format = log.formats.find(function MARKER(f){
if(!f.detector.test(new Error().stack)) return false;
//console.log('////', f.name, 'wants', 0/*line*/, '\n' + new Error().stack);
return true;
});
core.initialize();
if(console.timeEnd) console.timeEnd(SCRIPTID);
})();
3.- ¿Odias la insufrible espera de carga de un archivo PDF? Este script es para tí:
- PDF Drive direct download:
- // ==UserScript==
// @name PDF Drive direct download
// @namespace http://tampermonkey.net/
// @version 0.1
// @description to skip the annoying wait before download.
// @author Kiwi Poon
// @match *://www.pdfdrive.com/*.html
// @match *://pdfdrive.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Get current url:
console.log("Current URL: " + window.location.href);
let url = window.location.href;
// Check the url whether in download page current.
if(url.match(/d[0-9]{3,11}.html/g)){
console.log("This is a download page");
// to show the download link
document.getElementById("alternatives").style.display = "";
document.getElementById("alternatives").style.textalign = "left";
// hide the timer
document.getElementById("broken").style.display = "none";
// if the url isn't download page
}else if(url.match(/e[0-9]{3,11}.html/g)){
console.log("This is not a download page");
// click the button automatically
document.getElementById("download-button-link").click();
}
})();
4.- Ante los problemas de rendimiento generales del navegador, esta es la gama de scripts de anuladores de animaciones que tengo:
- DisableAnimation:
- // ==UserScript==
// @name DisableAnimation
// @name:zh-CN 禁用动画
// @description Disable animation on page
// @description:zh-CN 禁用网页上的动画效果
// @namespace https://greasyfork.org/users/197529
// @version 0.7.2
// @author kkocdko
// @license Unlicense
// @match *://*/*
// @run-at document-start
// ==/UserScript==
'use strict'
runInGrobal(() => {
window.requestAnimationFrame = callback => setTimeout(callback, 200)
})
document.head.insertAdjacentHTML('beforeend', `<style>
*,
*::before,
*::after {
animation: none !important;
transition: none !important;
}
</style>`)
function runInGrobal (callback) {
const scriptEl = document.createElement('script')
scriptEl.textContent = callback.toString()
document.head.appendChild(scriptEl)
}
- AnimalQuery:
- // ==UserScript==
// @name AnimalQuery
// @description Tries to speedup browsing by disabling CSS content animations
// @license WTFPLv2, no warranty
// @version 2019.09.18.2157
// @namespace [Tienes que estar registrado y conectado para ver este vínculo]
// @grant none
// @inject-into auto
// @run-at document-start
// @include *
// ==/UserScript==
/* jshint esversion: 6 */
(function(){
let style = document.createElement('style');
style.textContent = `*,*::before,*::after{
/*animation-delay: 0ms !important;
animation-duration: 0ms !important;*/
animation-timing-function: step-start !important;
/*transition-delay: 0.1ms !important;
transition-duration: 0.1ms !important;*/
transition-timing-function: step-start !important;
scroll-behavior: auto !important;
}`;
try{
if(document.head){
document.head.appendChild(style);
} else {
document.documentElement.appendChild(style);
}
}catch(e){}
})();
- AnimalQueryJS:
- // ==UserScript==
// @name AnimalQueryJS
// @description Tries to speedup browsing by disabling JS (jQuery) animations
// @license WTFPLv2, no warranty
// @version 2019.09.15.1104
// @namespace [Tienes que estar registrado y conectado para ver este vínculo]
// @grant none
// @inject-into auto
// @run-at document-start
// @include *
// @exclude [Tienes que estar registrado y conectado para ver este vínculo]
// ==/UserScript==
/* jshint esversion: 6 */
(function(){
window.addEventListener('load', function(){
try{
if(window.jQuery && window.jQuery.fx){
window.jQuery.fx.off = true;
} else if (window.wrappedJSObject && window.wrappedJSObject.jQuery && window.wrappedJSObject.jQuery.fx ){
window.wrappedJSObject.jQuery.fx.off = true;
}
}catch(e){}
});
})();
Esto es todo lo que tengo de scripts por ahora (ya que el sitio no me deja poner el siguiente, por ser pesadísimo), pero recomiendo visitar la biblioteca de Greasy Fork para buscar más, en caso de que quieran mejorar la experiencia de navegación, aún cuando no sea la panacea que están esperando. Un saludo a todos.