HTML Animation Frame Request Limiter

Limits HTML animation frame request. Practically limits FPS of JavaScript controlled animation such as in canvas. Designed to lower CPU usage.

  1. // ==UserScript==
  2. // @name HTML Animation Frame Request Limiter
  3. // @namespace https://greasyfork.org/en/users/85671-jcunews
  4. // @version 1.0.1
  5. // @license AGPL v3
  6. // @author jcunews
  7. // @description Limits HTML animation frame request. Practically limits FPS of JavaScript controlled animation such as in canvas. Designed to lower CPU usage.
  8. // @match *://*/*
  9. // @include *:*
  10. // @grant GM_registerMenuCommand
  11. // @grant unsafeWindow
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (() => {
  16. var fps = 0, tfps, pt, raf = unsafeWindow.requestAnimationFrame;
  17. function nraf(f) {
  18. if (fps && !f.f_ujs) {
  19. var nf = function(t) {
  20. if ((t - pt) >= tfps) {
  21. pt = t;
  22. return nf.f_ujs.apply(this, arguments)
  23. } else setTimeout(() => raf(nf), tfps - (t - pt))
  24. };
  25. nf.f_ujs = f;
  26. f = nf;
  27. } else if (!fps && f.f_ujs) f = f.f_ujs;
  28. return raf.apply(this, arguments)
  29. }
  30. GM_registerMenuCommand("Set FPS", a => {
  31. a = fps;
  32. while (true) {
  33. a = prompt(`Context: [${window.top === window ? "Host" : "Frame"}]\n${location.href}\n\nFPS limiter is currently ${fps ? "set to: " + fps : "disabled"}.\nEnter new FPS rate (e.g.: 20), or zero to disable limiter.`, a);
  34. if (a === null) return;
  35. if (!isNaN(a = parseFloat(a.trim())) && (a >= 0)) {
  36. if (fps = a) {
  37. tfps = 1000 / fps;
  38. pt = 0;
  39. unsafeWindow.requestAnimationFrame = nraf
  40. } else unsafeWindow.requestAnimationFrame = raf;
  41. return
  42. }
  43. }
  44. })
  45. })()