poniższy kod ilustruje problem, zmiana kolejności odczytu/zapisu powoduje dużą różnicę czasu wykonania (testowane przy użyciu przeglądarki Chrome, Firefox i IE):dlaczego małe uporządkowanie operacji odczytu/zapisu DOM powoduje ogromną różnicę wydajności
// read->write->read->write...
function clearSlow(divs){
Array.prototype.forEach.call(divs, function(div) {
contents.push(div.clientWidth);
div.style.width = "10px";
});
}
// read->read->...->write->write...
function clearFast(divs){
Array.prototype.forEach.call(divs, function(div) {
contents.push(div.clientWidth);
});
Array.prototype.forEach.call(divs, function(div) {
div.style.width = "10px";
});
}
Oto JSFiddle dla pełnego przykładu http://jsfiddle.net/Dq3KZ/2/.
Moje wyniki dla n = 100:
wersja Powolne: ~ 35ms
Szybka wersja: ~ 2ms
dla n = 1000:
wersja Powolne: ~ 2000ms
Szybko wersja: ~ 25ms
Myślę, że jest to związane z t w każdym przypadku liczba ponownych przeglądarek. W powolnym scenariuszu następuje ponowne nadawanie dla każdej operacji zapisu. Jednak w szybkim scenariuszu proces zmiany pojawia się tylko raz na końcu. Ale nie jestem pewien i nie rozumiem, dlaczego działa to w ten sposób (gdy operacje są niezależne).
Edit: użyłem InnerText
własność zamiast clientWidth
i Style.Width
, mam ten sam problem przy korzystaniu z Google Chrome (http://jsfiddle.net/pindexis/CW2BF/7/). Jednak w przypadku użycia InnerHTML
prawie nie ma różnicy (http://jsfiddle.net/pindexis/8E5Yj/).
Edit2: I otworzyły dyskusję o problemie innerHTML/innerText dla zainteresowanych: why does replacing InnerHTML with innerText causes >15X drop in performance
Czy to zmiana poprzedniej szerokości 'div' powoduje wywołanie, gdy żądane jest kolejne' div' 'clientWidth'? –
Zmiana szerokości div zmienia stan reflow (patrz http://www-archive.mozilla.org/newlayout/doc/reflow.html). Ale reflow nie musi być wykonane natychmiast, tylko wtedy, gdy wynik jest potrzebny. Jeśli nie zażądasz szerokości, reflow nie pojawi się, dopóki wątek się nie skończy (pamiętaj, że naprawdę nie możesz na tym polegać, pamiętam, że notatki Opery mówiły, że reflow mógłby nastąpić wcześniej, gdyby wykonanie skryptu było długie) . A to, co się dzieje, jest trudniejsze do przewidzenia ze względu na to, że reflowsy nie zawsze są całością strony. –
Należy pamiętać, że wszystko to zależy od implementacji, ale wyraźnie się zmienia i natychmiastowe odczytanie w pętli jest najgorszym możliwym przypadkiem. –