2016-02-19 8 views
6

dem folgenden Code vor:DOM Laden aus danach Skript blockiert

<head> 
<style> 
.box{ 
    background-color:red; 
    height:150px;  
    width:150px; 
} 
</style> 
</head> 
<body> 
    <div class="box"></div> 

    <script> 
    var start = new Date(); 
    while(true) { 
    var now = new Date(); 
    if (now-start > 10000) 
    break; 
    } 
    console.log('main thread finished'); 
    </script> 
</body> 

Es ist eine große mir Überraschung, dass DOM seine Beladung für 10 Sekunden aufschiebt (.box Rechteck wird nach 10 Sekunden erscheint!) . Da es zuerst (<div class="box"></div>) kommt, warum wartet auf das Skript, das folgt? Irgendeine vernünftige Erklärung?

Danke

+0

Entschuldigung @Rayon; Nach den Änderungen ist jedoch nicht ersichtlich, dass das Skript nach DOM kommt! In diesem Fall hat meine Frage keine Bedeutung ... –

+0

Wenn Sie dieses Snippet ausführen, sehen Sie die gleichen Ergebnisse. Die Platzierung des Skripts spielt in diesem Fall keine Rolle. – Rayon

+0

macht es keinen Unterschied, ob Sie in Körper oder Kopf setzen. Die Ausführung hält trotzdem an. –

Antwort

1

es zu vereinfachen, JavaScript ist single-threaded, was bedeutet, es nicht um das DOM-Modell zur gleichen Zeit wie die Pflege Ihrer kleinen Skript nehmen. Es geht eins nach dem anderen.

Wirklich umfassende exmplatantion kann here gefunden werden.

Um das Problem der blockierten Benutzeroberfläche zu vermeiden, können Sie sich über Web Workers informieren.

+1

Wenn es einer nach dem anderen geht, sollte Element zuerst vor der Ausführung der While-Schleife gemalt werden .. macht Sinn? – Rayon

+0

@RayonDabre, naja, ich meinte es kann nicht gleichzeitig gemacht werden, aber ich bin mir nicht sicher wann genau die DOM Verarbeitung startet (vielleicht erst nach dem Closing '', keine Ahnung und ich wäre nicht überrascht, wenn dies browserspezifisch wäre) aber offensichtlich Es beginnt, nachdem das Skript verarbeitet wurde. – Anton

+0

@RayonDabre, wie auch immer, bitte sehen Sie meine aktualisierte Antwort, können Sie Web-Arbeiter verwenden, um einige Sachen im Hintergrund zu verarbeiten. – Anton

0

Dieses Skript wartet nicht auf das vollständige Laden der Seite, bevor sie gestartet wird. Deshalb warten Sie 10 Sekunden. Deshalb wird dieser Code normalerweise von window.onload oder $ (document) .ready() eingeschlossen.

1

Aufgrund der Art und Weise der Motor (Einzelfaden) alle Skriptausführung blockiert jede progressive Darstellung in der Seite unter dem Skript

enter image description here

+0

Das ist nicht ganz richtig. Einige Browser laden andere Ressourcen parallel herunter, aber diese Ressourcen können erst ausgeführt oder angezeigt werden, nachdem dieses Skript ausgeführt wurde. – jfriend00

+0

Es hängt davon ab, wie Sie das Skript und die Browserkompatibilität konfigurieren. – Sagi

+0

Im Beispiel gibt es keine externen JS-Dateien, daher ist diese Antwort irrelevant. – Anton

2

„Scripts ohne async arbeitet oder Attribute verschieben, sowie Als Inline-Skripte werden abgerufen und sofort ausgeführt, bevor der Browser die Seite analysiert. " - von MDN.

Also Ihr Skript stoppt für 10 Sekunden zu analysieren. Nicht um über das Rendern der Seite zu sprechen. Im Grunde wurde dies getan, um sofortige HTML-Änderungen innerhalb des ausführenden Skripts zu unterstützen. Wenn Ihr Skript beispielsweise document.write('More html') aufruft, wirkt sich dies auf das Parsing aus.

Übrigens hat das ausführende Skript Zugriff auf die DOM-Struktur, die wurde bereits geparst. Betrachten Sie das folgende Beispiel.

<div class="box">Affected</div> 
 
<script> 
 
\t [].forEach.call(document.querySelectorAll('.box'), function(box){ 
 
    \t  box.innerText += '... modified'; 
 
    }); 
 
</script> 
 
<div class="box">Not</div>

+0

Aber das Element, das er fragt, ist vor dem Skript, nicht danach. – Qwertiy

0

Browser Gemäß den Standards kann das Element vor der Skriptausführung machen. Aber es bedeutet nicht, dass es muss. Ich habe Ihren Code in 4 Browsern überprüft und nur einer von ihnen hat die .box vor der Skriptausführung gezeichnet - es war Opera 12. Alle anderen Browser - Chrome, FF, IE11 nicht.

Wie ich mich erinnere, sagte irgendwann Chrome, dass es ihnen ermöglicht, etwas zu optimieren, und sie dachten, dass die Internetgeschwindigkeit groß genug wurde, um bis zur vollständigen Beladung zu warten.