it-swarm.com.de

Verletzung Die Ausführung einer JavaScript-Aufgabe hat xx ms gedauert

Kürzlich habe ich diese Art von Warnung erhalten, und dies ist das erste Mal, dass ich sie bekomme:

[Violation] Long running JavaScript task took 234ms
[Violation] Forced reflow while executing JavaScript took 45ms

Ich arbeite an einem Gruppenprojekt und habe keine Ahnung, woher das kommt. Das ist noch nie passiert. Plötzlich schien es, als sich jemand anderes an dem Projekt beteiligte. Wie finde ich, welche Datei/Funktion diese Warnung verursacht? Ich habe nach der Antwort gesucht, aber hauptsächlich nach der Lösung, wie man sie löst. Ich kann es nicht lösen, wenn ich nicht einmal die Ursache des Problems finden kann.

In diesem Fall wird die Warnung nur in Chrome angezeigt. Ich habe versucht, Edge zu verwenden, aber ich habe keine ähnlichen Warnungen erhalten, und ich habe es noch nicht in Firefox getestet.

Ich bekomme sogar den Fehler von jquery.min.js:

[Violation] Handler took 231ms of runtime (50ms allowed)            jquery.min.js:2
255
procatmer

Update : Chrome 58+ hat diese und andere Debug-Meldungen standardmäßig ausgeblendet. Um sie anzuzeigen, klicken Sie auf den Pfeil neben "Info" und wählen Sie "Ausführlich".

Chrome 57 hat standardmäßig die Option "Verstöße verbergen" aktiviert. Um sie wieder zu aktivieren, müssen Sie Filter aktivieren und das Kontrollkästchen "Verstöße verbergen" deaktivieren.

plötzlich erscheint es, wenn jemand anderes an dem Projekt beteiligt ist

Ich denke, es ist wahrscheinlicher, dass Sie auf Chrome 56 aktualisiert haben. Diese Warnung ist meiner Meinung nach eine wunderbare neue Funktion. Bitte deaktivieren Sie sie nur, wenn Sie verzweifelt sind und Ihr Prüfer Ihnen die Noten nimmt. Die zugrunde liegenden Probleme sind in den anderen Browsern vorhanden, aber die Browser sagen Ihnen einfach nicht, dass es ein Problem gibt. Das Chromium Ticket ist hier aber es gibt keine wirklich interessante Diskussion darüber.

Diese Meldungen sind Warnungen anstelle von Fehlern, da sie keine größeren Probleme verursachen werden. Dies kann dazu führen, dass Frames herunterfallen oder auf andere Weise weniger flüssig werden.

Es lohnt sich jedoch, diese zu untersuchen und zu beheben, um die Qualität Ihrer Anwendung zu verbessern. Sie können dies tun, indem Sie darauf achten, unter welchen Umständen die Meldungen angezeigt werden, und indem Sie Leistungstests durchführen, um einzugrenzen, wo das Problem auftritt. Der einfachste Weg, um mit dem Testen der Leistung zu beginnen, besteht darin, folgenden Code einzufügen:

function someMethodIThinkMightBeSlow() {
    const startTime = performance.now();

    // Do the normal stuff for this function

    const duration = performance.now() - startTime;
    console.log(`someMethodIThinkMightBeSlow took ${duration}ms`);
}

Wenn Sie sich weiterentwickeln möchten, können Sie auch Chrome's Profiler oder eine Benchmarking-Bibliothek wie diese verwenden.

Wenn Sie einen Code gefunden haben, der lange dauert (50 ms ist der Schwellenwert von Chrome), haben Sie mehrere Möglichkeiten:

  1. Schneiden Sie einige/alle Aufgaben aus, die möglicherweise nicht erforderlich sind
  2. Finden Sie heraus, wie Sie die gleiche Aufgabe schneller erledigen können
  3. Teilen Sie den Code in mehrere asynchrone Schritte auf

(1) und (2) mögen schwierig oder unmöglich sein, aber es ist manchmal sehr einfach und sollte Ihre ersten Versuche sein. Bei Bedarf sollte dies immer möglich sein (3). Um dies zu tun, verwenden Sie etwas wie:

setTimeout(functionToRunVerySoonButNotNow);

oder

// This one is not available natively in IE, but there are polyfills available.
Promise.resolve().then(functionToRunVerySoonButNotNow);

Sie können mehr über die Asynchronität von JavaScript lesen hier .

230
voltrevo

Dies sind nur Warnungen, wie bereits erwähnt. Wenn Sie diese Probleme jedoch unbedingt beheben möchten (und dies sollten Sie tun), müssen Sie zunächst ermitteln, was die Warnung verursacht. Es gibt keinen Grund, aus dem Sie eine Force-Reflow-Warnung erhalten können. Jemand hat eine Liste für einige mögliche Optionen erstellt. Sie können der Diskussion für weitere Informationen folgen.
Hier ist der Kern der möglichen Gründe:

Was zwingt Layout/Reflow

Alle folgenden Eigenschaften oder Methoden veranlassen den Browser, bei Aufforderung/Aufruf in JavaScript den Stil und das Layout * synchron zu berechnen. Dies wird auch als Reflow oder Layout-Thrashing bezeichnet und ist ein allgemeiner Leistungsengpass.

Element

Box-Metriken
  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()
Scrollzeug
  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop und stellen sie ein
Fokus
  • elem.focus() kann ein doppeltes erzwungenes Layout auslösen ( source )
Ebenfalls…
  • elem.computedRole, elem.computedName
  • elem.innerText ( source )

getComputedStyle

window.getComputedStyle() erzwingt normalerweise eine erneute Stilberechnung ( source )

window.getComputedStyle() erzwingt auch das Layout, wenn eine der folgenden Bedingungen erfüllt ist:

  1. Das Element befindet sich in einem Schattenbaum
  2. Es gibt Medienabfragen (im Zusammenhang mit Ansichtsfenstern). Insbesondere eine der folgenden Angaben: ( Quelle ) * min-width, min-height, max-width, max-height, width, height * aspect-ratio, min-aspect-ratio, max-aspect-ratio
    • device-pixel-ratio, resolution, orientation
  3. Bei der angeforderten Eigenschaft handelt es sich um eine der folgenden: ( source )
    • height, width * top, right, bottom, left * margin [-top, -right, -bottom, -left oder Kurzform ] nur, wenn der Rand festgelegt ist. * padding [-top, -right, -bottom, -left oder shorthand ] nur wenn die Polsterung Ist repariert. * transform, transform-Origin, perspective-Origin * translate, rotate, scale * webkit-filter, backdrop-filter * motion-path, motion-offset, motion-rotation * x, y, rx, ry

fenster

  • window.scrollX, window.scrollY
  • window.innerHeight, window.innerWidth
  • window.getMatchedCSSRules() erzwingt nur den Stil

Formen

  • inputElem.focus()
  • inputElem.select(), textareaElem.select() ( source )

Mausereignisse

  • mouseEvt.layerX, mouseEvt.layerY, mouseEvt.offsetX, mouseEvt.offsetY ( source )

dokumentieren

  • doc.scrollingElement erzwingt nur den Stil

Reichweite

  • range.getClientRects(), range.getBoundingClientRect()

SVG

inhaltlich editierbar

  • Viele, viele Dinge,… einschließlich des Kopierens eines Bildes in die Zwischenablage ( Quelle )

Überprüfen Sie mehr hier .

Außerdem finden Sie hier den Chromium-Quellcode aus rsprüngliche Ausgabe und Diskussion über eine Leistungs-API für die Warnungen.


Bearbeiten: Es gibt auch einen Artikel zum Minimieren des Layout-Reflow bei PageSpeed ​​Insight von Google . Es erklärt, was ein Browser-Reflow ist:

Reflow ist der Name des Webbrowser-Prozesses zur Neuberechnung der Positionen und Geometrien von Elementen im Dokument, um einen Teil oder das gesamte Dokument neu zu rendern. Da Reflow eine vom Benutzer blockierende Operation im Browser ist, ist es für Entwickler hilfreich zu verstehen, wie die Reflow-Zeit verbessert werden kann und die Auswirkungen verschiedener Dokumenteigenschaften (DOM-Tiefe, CSS-Regeleffizienz, verschiedene Arten von Stiländerungen) auf den Reflow zu verstehen Zeit. Manchmal kann das Umfließen eines einzelnen Elements im Dokument das Umfließen der übergeordneten Elemente und der darauf folgenden Elemente erfordern.

Außerdem wird erklärt, wie Sie es minimieren können:

  1. Reduzieren Sie unnötige DOM-Tiefen. Änderungen auf einer Ebene in der DOM-Struktur können Änderungen auf jeder Ebene der Struktur hervorrufen - bis zum Stamm und bis zu den untergeordneten Elementen des geänderten Knotens. Dies führt dazu, dass mehr Zeit für die Durchführung des Reflow aufgewendet wird.
  2. Minimieren Sie CSS-Regeln und entfernen Sie nicht verwendete CSS-Regeln.
  3. Wenn Sie komplexe Änderungen am Rendering vornehmen, z. B. Animationen, geschieht dies außerhalb des Flusses. Verwenden Sie dazu die Option "Position absolut" oder "Position fixiert".
  4. Vermeiden Sie unnötig komplexe CSS-Selektoren - insbesondere Nachkommen-Selektoren -, die mehr CPU-Leistung benötigen, um die Selektoren abzugleichen.
67
noob

Ein paar Ideen:

  • Entfernen Sie die Hälfte Ihres Codes (möglicherweise durch Auskommentieren).

    • Ist das Problem noch da? Großartig, Sie haben die Möglichkeiten eingegrenzt! Wiederholen.

    • Ist das Problem nicht da? Ok, schau dir die Hälfte an, die du auskommentiert hast!

  • Verwenden Sie ein Versionskontrollsystem (z. B. Git)? Wenn ja, git checkout einige Ihrer neueren Commits. Wann wurde das Problem eingeführt? Sehen Sie sich das Commit genau an, um festzustellen, welcher Code sich geändert hat, als das Problem zum ersten Mal auftrat.

28
therobinkim

In meinem Fall habe ich festgestellt, dass dies tatsächlich durch einen Code aus einer Erweiterung verursacht wurde. Für mich war die Erweiterung AdBlock.

Um die Ursache des Problems zu ermitteln, führen Sie Ihre Anwendung aus und notieren Sie sie in Chrome unter Registerkarte Leistung.

Dort können Sie verschiedene Funktionen überprüfen, deren Ausführung lange gedauert hat. In meinem Fall stammte die Datei, die mit Warnungen in der Konsole korrelierte, aus einer Datei, die von der AdBlock-Erweiterung geladen wurde. In Ihrem Fall könnte dies jedoch etwas anderes sein.

Überprüfen Sie diese Dateien und versuchen Sie herauszufinden, ob dies der Code einer Erweiterung ist oder Ihrer. (Wenn es Ihnen gehört, haben Sie die Ursache für Ihr Problem gefunden.)

8
Matt Leonowicz

Suchen Sie in der Konsole Chrome auf der Registerkarte "Netzwerk" nach den Skripten, deren Ladezeit am längsten dauert.

In meinem Fall gab es eine Reihe von Angular Add-On-Skripten, die ich aufgenommen, aber noch nicht in der App verwendet hatte:

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-utils/0.1.1/angular-ui-utils.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-animate.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-aria.min.js"></script>

Dies waren die einzigen JavaScript-Dateien, deren Laden länger dauerte als die Zeit, die der Fehler "Langlaufende Aufgabe" angab.

Alle diese Dateien werden auf meinen anderen Websites ausgeführt, ohne dass Fehler generiert wurden. Bei einer neuen Webanwendung, die kaum über Funktionen verfügt, wurde jedoch der Fehler "Long Running Task" angezeigt. Der Fehler wurde sofort nach dem Entfernen beendet.

Ich gehe davon aus, dass diese Angular Add-Ons rekursiv nach ihren Start-Tags in immer tieferen Bereichen des DOM gesucht haben. Da sie keine gefunden haben, mussten sie das gesamte DOM durchlaufen, bevor sie das Programm verließen. Dies dauerte länger als Chrome erwartet - also die Warnung.

5
Jordan Reddick

Dies wurde in der Beta von Chrome 56 hinzugefügt, obwohl es nicht in diesem Änderungsprotokoll des Chromium-Blogs enthalten ist: Chrome 56 Beta: Warnung "Nicht sicher", Web-Bluetooth und CSS position: sticky

Sie können dies in der Filterleiste der Konsole mit dem Kontrollkästchen Verstöße verbergen verbergen.

4
Bastien

Ich habe die Wurzel dieser Nachricht in meinem Code gefunden, der Knoten gesucht und ausgeblendet oder angezeigt hat (offline). Das war mein Code:

search.addEventListener('keyup', function() {
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            node.classList.remove('hidden');
        else
            node.classList.add('hidden');
});

Die Registerkarte Leistung (Profiler) zeigt, dass das Ereignis etwa 60 ms dauert: Chromium performance profiler layout recalculation reflow

Jetzt:

search.addEventListener('keyup', function() {
    const nodesToHide = [];
    const nodesToShow = [];
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            nodesToShow.Push(node);
        else
            nodesToHide.Push(node);

    nodesToHide.forEach(node => node.classList.add('hidden'));
    nodesToShow.forEach(node => node.classList.remove('hidden'));
});

Auf der Registerkarte "Leistung" (Profiler) wird jetzt angezeigt, dass das Ereignis ca. 1 ms dauert: Chromium profiler dark

Und ich habe das Gefühl, dass die Suche jetzt schneller funktioniert (229 Knoten).

3

Wenn Sie Chrome Canary (oder Beta) verwenden, aktivieren Sie einfach die Option "Verstöße ausblenden".

Hide Violations Checkbox in Chrome 56 Console

3
zhaoming

Ich habe eine Lösung im Apache Cordova-Quellcode gefunden. Sie implementieren wie folgt:

var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };

Einfache Implementierung, aber kluger Weg.

Verwenden Sie in Android 4.4 Promise. Verwenden Sie für ältere Browser setTimeout()


Verwendungszweck:

nextTick(function() {
  // your code
});

Nach dem Einfügen dieses Trickcodes sind alle Warnmeldungen verschwunden.

3
wf9a5m75

Dies ist ein Verstoß von Google Chrome, der anzeigt, wann die Protokollierungsstufe Verbose aktiviert ist.

Beispiel für eine Fehlermeldung:

screenshot of the warning

Erklärung:

Reflow ist der Name des Webbrowser-Prozesses zur Neuberechnung der Positionen und Geometrien von Elementen im Dokument, um einen Teil oder das gesamte Dokument neu zu rendern. Da Reflow eine vom Benutzer blockierende Operation im Browser ist, ist es für Entwickler hilfreich zu verstehen, wie die Reflow-Zeit verbessert werden kann und die Auswirkungen verschiedener Dokumenteigenschaften (DOM-Tiefe, CSS-Regeleffizienz, verschiedene Arten von Stiländerungen) auf den Reflow zu verstehen Zeit. Manchmal kann das Umfließen eines einzelnen Elements im Dokument das Umfließen der übergeordneten Elemente und der darauf folgenden Elemente erfordern.

Originalartikel: Browser-Reflow minimieren von Lindsey Simon, UX-Entwickler, veröffentlicht auf developers.google.com.

Und das ist der Link Google Chrome gibt Ihnen im Performance-Profiler in den Layout-Profilen (den lila Regionen) weitere Informationen zur Warnung.

ein erzwungener Rückfluss tritt häufig auf, wenn Sie eine Funktion vor dem Ende der Ausführung mehrmals aufgerufen haben.

Möglicherweise haben Sie das Problem auf einem Smartphone und nicht in einem klassischen Browser.

Ich schlage vor, ein setTimeout zu verwenden, um das Problem zu lösen.

Dies ist nicht sehr wichtig, aber ich wiederhole, das Problem tritt auf, wenn Sie eine Funktion mehrmals aufrufen und nicht, wenn die Funktion länger als 50 ms ist. Ich denke, Sie sind in Ihren Antworten falsch.

  1. Deaktivieren Sie 1-zu-1-Anrufe und laden Sie den Code erneut, um festzustellen, ob der Produktfehler vorliegt.
  2. Wenn ein zweites Skript den Fehler verursacht, verwenden Sie ein setTimeOut, das auf der Dauer der Verletzung basiert.
0
Cherif

1 Ging zur Konsole

2 Klicken Sie auf das Filtersymbol neben (Kontrollkästchen "Protokoll beibehalten").

3 Aktivieren Sie das Kontrollkästchen "Verstoß verbergen"


EDIT

Diese Funktion wurde aus Chrome 58 entfernt

Ändern Sie die Dropdown-Liste der Protokollierungsstufe in "Ausführlich", um Verstöße anzuzeigen.

0
Sajan