Performance monitor

Works on any website. Shows fps, frame time, used memory. Change modes by click

Versión del día 12/3/2021. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name            Performance monitor
// @description     Works on any website. Shows fps, frame time, used memory. Change modes by click
// @name:ru         Монитор производительности
// @description:ru  Работает на любом сайте. Отображает fps, время кадра, используемую память. Смена режимов по клику
// @version         1.1.1
// @author          Konf
// @namespace       https://greasyfork.org/users/424058
// @include         *
// @grant           none
// @noframes
// @require         https://cdn.jsdelivr.net/npm/[email protected]
// @require         https://cdn.jsdelivr.net/npm/[email protected]
// ==/UserScript==

/**
 * Hi! The last update was broken and the script could duplicate in your scripts manager
 * Please, reinstall it: https://greasyfork.org/scripts/408058
 * and make sure you have been installed only one copy of the script, to avoid errors
 * 
 * Привет! Последнее обновление было плохое и скрипт мог дублироваться в твоём менеджере скриптов
 * Пожалуйста, переустанови его: https://greasyfork.org/scripts/408058
 * и убедись что у тебя установлена только одна копия скрипта, чтобы избежать ошибок
 */

/* jshint esversion: 6 */
/* eslint-disable no-undef */

/**
 * In the code below I just try to make proper work of the two ready libraries:
 * One makes performance monitor, and second makes the monitor movable
 * It was not so easy, and seems it works now, but DON'T try to understand why
 * Most likely, even me already do not know it
 */

(function() {
  'use strict';

  const stats = new Stats();
  const statsParentNode = document.body;
  let statsIsHidden = false;
  let mouseOverParentNode = true;

  stats.dom.style.touchAction = 'none';
  stats.dom.style.width = '80px';
  stats.dom.style.height = '48px';
  stats.dom.style.padding = 0;
  stats.dom.style.margin = 0;

  statsParentNode.appendChild(stats.dom);

  const panelNum = {
    current: 0,
    max: 2
  };

  const listeners = {
    statsDragInteract: {
      // call this function on every dragmove event
      move(event) {
        const target = event.target;

        // keep the dragged position in the data-x/data-y attributes
        const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
        const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

        // translate the element
        target.style.transform = 'translate(' + x + 'px, ' + (y < 0 ? 0 : y) + 'px)';
        target.style.webkitTransform = target.style.transform;

        // update the position attributes
        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);
      },

      // bugfix...
      start(event) {
        const target = event.target;
        const targetTransform = target.style.transform;
        const transformY = (/,( |)*(\d*)/.exec(targetTransform) || [])[2];

        if (targetTransform && transformY <= 0) {
          target.setAttribute('data-y', 0);
        }
      },

      // call this function on every dragend event
      end(event) {
        statsIsHidden = false;

        if (mouseOverParentNode && --panelNum.current < 0) {
          panelNum.current = panelNum.max;
        }

        if (!mouseOverParentNode || statsIsHidden) {
          return stats.showPanel(panelNum.current);
        }

        stats.showPanel(panelNum.current - 1);
      }
    },

    statsNative: {
      node: {
        click(event) {
          if (statsIsHidden) {
            statsIsHidden = false;
            return stats.showPanel(panelNum.current);
          }

          if (++panelNum.current > panelNum.max) {
            panelNum.current = 0;
          }

          stats.showPanel(panelNum.current);
        }
      },

      parent: {
        mouseenter(event) {
          mouseOverParentNode = true;
        },
        mouseleave(event) {
          mouseOverParentNode = false;
        }
      },

      canvas: {
        contextmenu(event) {
          event.preventDefault();

          statsIsHidden = true;
          this.style.display = 'none';
        }
      }
    }
  };

  interact(stats.dom).draggable({
    // keep the element within the area of it's parent
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent'
      })
    ],

    listeners: listeners.statsDragInteract
  });

  const panels = Array.from(stats.dom.querySelectorAll('canvas'));
  panels.forEach((canvas) => {
    canvas.addEventListener('contextmenu', listeners.statsNative.canvas.contextmenu);
  });

  stats.dom.addEventListener('click', listeners.statsNative.node.click);

  statsParentNode.addEventListener('mouseenter', listeners.statsNative.parent.mouseenter);
  statsParentNode.addEventListener('mouseleave', listeners.statsNative.parent.mouseleave);

  requestAnimationFrame(function loop() {
    stats.update();
    requestAnimationFrame(loop);
  });
})();