JavaScriptsVerschiedenes

CPU-Test

Misst laufend, wie pünktlich der Browser einen Timer bedient, und zeichnet den Verlauf in drei Diagramme.

Dieses Script von unserem User sfan schaut dem Browser bei der Arbeit zu. Es fordert ihn auf, eine winzige Funktion immer wieder „in einer Millisekunde" auszuführen, und misst dabei, wie viel Zeit tatsächlich zwischen zwei Aufrufen vergangen ist. Diese Zeitspanne ist ein grober Anhaltspunkt dafür, wie beschäftigt Browser und Rechner gerade sind: Je mehr im Hintergrund zu tun ist, desto später kommt der Browser dazu, den Timer zu bedienen, und desto größer werden die gemessenen Abstände.

Der gemessene Wert steht in Millisekunden über den Diagrammen und wird gleichzeitig als Kurve gezeichnet. Alle drei Diagramme zeigen denselben Messwert, nur in unterschiedlicher Auflösung: Das erste zeichnet jede Messung, das zweite jede elfte und das dritte jede hunderteinste. Dadurch bildet das obere Diagramm jedes kurze Zucken ab, während die unteren den Verlauf über einen längeren Zeitraum zeigen. Ist eine Kurve am rechten Rand angekommen, wird die Fläche gelöscht und links neu begonnen. Mit dem Knopf unter den Diagrammen haltet ihr die Messung an und startet sie wieder — praktisch, wenn ihr euch eine Kurve in Ruhe ansehen wollt.

Ein ehrliches Wort zur Aussagekraft: Ein Browser kann die Auslastung des Prozessors nicht auslesen, dafür fehlt ihm aus gutem Grund die Berechtigung. Was hier gemessen wird, ist die Verzögerung des Timers — und die hängt außer von der Rechenlast auch von den Regeln des Browsers selbst ab. Verschachtelte setTimeout-Aufrufe werden nämlich ab der fünften Ebene auf mindestens vier Millisekunden ausgebremst; unter diesen Wert kommt die Messung deshalb nie, egal wie flott euer Rechner ist. Läuft die Seite in einem Hintergrund-Tab, drosseln die Browser den Timer sogar auf etwa eine Sekunde. Ausschläge nach oben sind also aussagekräftig, der Grundwert ist es nicht.

Gezeichnet wird auf drei <canvas>-Elementen. Als das Script 2011 erschien, war das noch eine Neuigkeit, die längst nicht jeder Browser beherrschte — heute unterstützt sie jeder aktuelle Browser, sodass der Hinweis auf bestimmte Browserversionen entfallen kann. Wen die Ausstattung des eigenen Browsers genauer interessiert, findet die Angaben bei den Browserinformationen; wer sehen will, wie sich mit Mausbewegungen zeichnen lässt, schaut in Malen.

Verschiedenes Baujahr 2011 läuft in deinem Browser
Gemessener Abstand: 0 ms

Diagramm 1 — jede Messung

Diagramm kann nicht angezeigt werden

Diagramm 2 — jede elfte Messung

Diagramm kann nicht angezeigt werden

Diagramm 3 — jede hunderteinste Messung

Diagramm kann nicht angezeigt werden

Kleine Werte bedeuten: Der Browser bedient den Timer pünktlich. Ausschläge nach oben entstehen, wenn Rechner oder Browser gerade mit etwas anderem beschäftigt sind.

Eingesandt von sfan

So funktioniert das Script

Das Script besteht aus vier Teilen: einer Messschleife, die sich selbst immer wieder aufruft, einer Zeichenfunktion für eine einzelne Linie, einer Verteilfunktion, die den Messwert auf die drei Diagramme aufteilt, und dem Start-Stopp-Knopf. Alles steckt in einer sofort ausgeführten Funktion, damit die Variablennamen nicht mit anderen Scripts auf derselben Seite kollidieren.

function ctime() {
  const diff = Date.now() - letzteZeit;
  anzeige.textContent = diff;
  timer = setTimeout(ctime, 1);
  setTimeout(function () { draw(diff); }, 5);
  letzteZeit = Date.now();
}

Das ist die Messung. Date.now() liefert die aktuelle Uhrzeit als Zahl in Millisekunden; die Differenz zur zuletzt gemerkten Zeit ist der gesuchte Abstand. Anschließend bestellt sich die Funktion mit setTimeout(ctime, 1) selbst für die nächste Millisekunde — eine Schleife, die dem Browser zwischen zwei Durchläufen Luft lässt, ganz anders als eine while-Schleife, die den Browser blockieren würde. Das Zeichnen wird mit fünf Millisekunden Verzögerung angestoßen, damit es nicht direkt in der Messung steckt und diese verfälscht. Zum Schluss wird die Zeit für die nächste Runde gemerkt.

Die Originalfassung übergab an setTimeout einen Text ("ctime()"), den der Browser dann wie eval auswerten musste. Heute übergibt man die Funktion selbst — das ist schneller, sicherer und wird vom Browser auch überprüft, wenn man sich vertippt.

function linie(flaeche, kontext, pos, val) {
  const neu = { x: pos.x + 2, y: flaeche.height - val };
  kontext.beginPath();
  kontext.moveTo(pos.x, pos.y);
  kontext.lineTo(neu.x, neu.y);
  kontext.stroke();

Hier wird gezeichnet. Ein Punkt auf der Zeichenfläche besteht aus zwei Zahlen: x ist der Abstand vom linken Rand, y der vom oberen. Der neue Punkt liegt zwei Pixel weiter rechts als der letzte, und seine Höhe ist flaeche.height - val — je größer der Messwert, desto weiter oben der Punkt, weil y nach unten wächst. beginPath() beginnt einen frischen Linienzug, moveTo() setzt den Stift auf den alten Punkt, lineTo() zieht ihn zum neuen, und erst stroke() macht die Linie sichtbar.

  if (neu.x > flaeche.width) {
    neu.x = 0;
    kontext.clearRect(0, 0, flaeche.width, flaeche.height);
  }
  return neu;
}

Ist die Kurve am rechten Rand angekommen, wird die Fläche mit clearRect() vollständig geleert und der Stift wieder nach ganz links gesetzt — die Kurve läuft also von vorn los. return neu gibt den erreichten Punkt zurück; die aufrufende Stelle merkt ihn sich als Ausgangspunkt für die nächste Linie.

if (counter >= 10) {
  lpos2 = linie(c2, gfx2, lpos2, val);
  counter = 0;
} else {
  counter++;
}

So entstehen die drei unterschiedlichen Auflösungen. Für das erste Diagramm wird bei jedem Messwert eine Linie gezogen. Für das zweite zählt counter mit: Erst wenn er 10 erreicht hat, wird gezeichnet und wieder auf 0 gesetzt — es kommt also nur jeder elfte Messwert aufs Papier. Für das dritte Diagramm macht counter2 dasselbe mit dem Grenzwert 100. Wollt ihr die Diagramme anders staffeln, ändert ihr einfach diese beiden Zahlen.

function starten() {
  if (timer !== null) return;
  letzteZeit = Date.now();
  schalter.textContent = "Anhalten";
  ctime();
}

Der Knopf schaltet die Messschleife an und aus. Beim Anhalten bricht clearTimeout(timer) den bereits bestellten nächsten Aufruf ab, und timer wird auf null gesetzt — daran erkennt das Script, dass gerade nicht gemessen wird. Beim Neustart wird letzteZeit zuerst auf die aktuelle Uhrzeit gestellt, sonst würde die gesamte Pause als ein einziger riesiger Messwert im Diagramm landen. Die Prüfung if (timer !== null) return; verhindert, dass versehentlich zwei Schleifen gleichzeitig laufen.

Zum Anpassen: Die Farben der drei Kurven stehen in den strokeStyle-Zeilen (die Originalfassung nutzte reines Rot, Grün und Blau, hier sind es etwas gedecktere Töne). Die Höhe der Diagramme regelt das height-Attribut der <canvas>-Elemente, und der Wert pos.x + 2 bestimmt, wie schnell die Kurve nach rechts wandert — mit 1 läuft sie doppelt so lange, bis sie den Rand erreicht.

Script für die eigene Homepage

Kopiert euch den kompletten Code und fügt ihn an der Stelle eurer Seite ein, an der das Script erscheinen soll. Er läuft ohne weitere Dateien und ohne fremde Server.

Mehr aus der Kategorie Verschiedenes