Когда происходит перекомпоновка в среде DOM?

Какие действия вызовут перекомпоновку веб-страницы с помощью DOM?

Кажется, есть разные точки зрения. Согласно http://www.nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4/, бывает

  • Когда вы добавляете или удаляете узел DOM.
  • Когда вы применяете стиль динамически (например, element.style.width = "10px").
  • Когда вы получаете измерение, которое необходимо вычислить, например, доступ к offsetWidth, clientHeight или любому вычисленному значению CSS (через getComputedStyle () в DOM-совместимых браузерах или currentStyle в IE).

Однако согласно http://dev.opera.com/articles/view/efficient-javascript/?page=3, срабатывая триггеры измерения перекомпоновки только тогда, когда действие перекомпоновки уже поставлено в очередь.

Есть ли у кого-нибудь еще идеи?


person Morgan Cheng    schedule 04.02.2009    source источник
comment
Разные браузеры ведут себя по-разному.   -  person some    schedule 04.02.2009
comment
За исключением случаев, когда они ведут себя одинаково. ;)   -  person coderjoe    schedule 14.08.2009
comment
Ознакомьтесь с докладом Пола Айриша о предотвращении перекомпоновки: перекомпоновка вызывается изменениями высоты, ширины, offsetWidth и т. д. Абсолютное позиционирование не запускает перекомпоновку.   -  person ruhong    schedule 27.09.2015


Ответы (3)


Обе статьи верны. Можно с уверенностью предположить, что всякий раз, когда вы делаете что-то, что может разумно потребовать, чтобы размеры элементов в DOM были вычислены, вы вызовете перекомпоновку.

К тому же, насколько я могу судить, в обеих статьях говорится об одном и том же.

В первой статье говорится, что перекомпоновка происходит, когда:

Когда вы извлекаете измерение, которое необходимо вычислить, например при доступе к offsetWidth, clientHeight или любому вычисленному значению CSS (через getComputedStyle ( ) в DOM-совместимых браузерах или currentStyle в IE), а изменения DOM ставятся в очередь для внесения.

Во второй статье говорится:

Как указывалось ранее, браузер может кэшировать для вас несколько изменений и перекомпоновывать только один раз, когда все эти изменения были внесены. Однако учтите, что измерение элемента приведет к его перекомпоновке, так что измерения будут правильными. Изменения могут быть перерисованы, а могут и не быть визуально перерисованы, но сама перекомпоновка все равно должна происходить за кулисами.

Этот эффект создается, когда измерения выполняются с использованием таких свойств, как offsetWidth, или таких методов, как getComputedStyle. Даже если числа не используются, простого использования любого из них, пока браузер все еще кэширует изменения, будет достаточно, чтобы запустить скрытую перекомпоновку. Если эти измерения проводятся неоднократно, вам следует подумать о том, чтобы сделать их только один раз и сохранить результат, который затем можно будет использовать позже.

Я понимаю, что это означает то же самое, что они сказали ранее. Opera изо всех сил старается кэшировать значения и избегать перекомпоновки за вас, но вы не должны полагаться на ее способность делать это.

Для всех намерений и целей просто верьте тому, что они оба говорят, когда говорят, что все три типа взаимодействий могут вызвать перекомпоновку.

Ваше здоровье.

person coderjoe    schedule 14.08.2009
comment
Есть ли способ принудительно перерисовать (помимо оплавления)? Чтобы визуализировать большую страницу с небольшими приращениями и, следовательно, увеличить скорость визуализации, воспринимаемую конечным пользователем. - person Jean Vincent; 11.05.2012
comment
@coderjoe, измерение элемента заставит его переформатировать, почему они не кешируются в браузерах? Что произойдет, если я вызову getComputedStyle 3 раза сразу после каждого другого! Будет у меня 3 переплавки! - person faressoft; 09.10.2017

Посмотрите на раздел «Отрисовка, инициированная доступом для чтения к свойствам» в Общие сведения о поведении рендеринга в Internet Explorer, где следующий код в IE вызовет рендеринг.

function askforHeight () {
  $("#lower").height();  
}
person Kevin Hakanson    schedule 21.09.2010

document.body.style.display = 'none';
document.body.style.display = 'block';

Это часто решает непонятные ошибки макета.

person I.devries    schedule 04.02.2009
comment
Я столкнулся с ошибкой ie6, из-за которой swf отображался не в том месте. Решено установкой swfObj.style.display = "block" - person aztack; 15.04.2014
comment
Вау, вам все еще нужна поддержка IE6? Оставайся сильным, солдат. - person I.devries; 15.04.2014