Альтернативы повторной заливке и перекраске

Я читал на SO и в других местах, которые перерисовывают и перекрашивают -flows дорого обходятся браузеру.

Меня интересуют альтернативы CSS/JS для перерисовки/display:none и перерисовки/visibility:hidden, которые не так требовательны к вычислительным ресурсам браузера.

Просто для ясности, и, пожалуйста, поправьте меня, если я ошибаюсь, общий сценарий повторного потока — это когда вы устанавливаете display:none для элемента, который вы хотите переключить отображение, например, раскрывающееся меню. Повторный поток означает, что браузер сначала "перетекает", т. е. отображает элемент и все под ним как видимое содержимое, но затем должен перестроить все это, потому что выпадающее меню должно быть скрыто.

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


person tim peterson    schedule 04.03.2013    source источник
comment
Если вы хотите изменить то, что отображается, вам нужно перекомпоновать и перерисовать хотя бы один раз. Лучшее, что вы можете сделать, это свести к минимуму количество перекомпоновок, не чередуя изменения DOM с чтением вычисляемых свойств.   -  person John Dvorak    schedule 04.03.2013
comment
На типичной веб-странице (например, на этой здесь — Stackoverflow), каково типичное верхнее предельное число display:none, которое можно было бы использовать, прежде чем оно начнет выглядеть отрывисто?   -  person tim peterson    schedule 04.03.2013
comment
Элементы DOM, которые постоянно скрыты, не вызывают перекомпоновку. Что больно, так это удалить этот элемент. Насколько большой контейнер? Удалите этот. Насколько он велик сейчас? Хорошо, удалите и это. Что теперь?   -  person John Dvorak    schedule 04.03.2013
comment
Дело в том, что если вы удаляете сразу несколько элементов, вы можете получить только одну перекомпоновку, если браузер может избежать всех перекомпоновок, кроме последней.   -  person John Dvorak    schedule 04.03.2013
comment
Спасибо @Jan, значит, я неправильно понял, что такое повторный поток? Если элемент имеет CSS-атрибут display:none, то его не нужно передавать, а затем повторно запускать при рендеринге страницы? Можете ли вы дать ответ, который представляет собой типичный пример того, что такое повторный поток?   -  person tim peterson    schedule 04.03.2013
comment
reflow = браузер вычисляет, где находится каждый элемент; repaint = браузер размещает некоторые пиксели на экране   -  person John Dvorak    schedule 04.03.2013
comment
Я почти уверен, что это не должно быть проблемой. Посмотрите, как быстро браузер может создать 1000 элементов div, сделать их невидимыми, а затем снова сделать видимыми: jsfiddle.net/howderek /aDzgc   -  person howderek    schedule 04.03.2013
comment
@howderek хороший пример!   -  person tim peterson    schedule 04.03.2013
comment
@timpeterson он по-прежнему работает быстро даже с opactiy: jsfiddle.net/howderek/aDzgc/embedded/result   -  person howderek    schedule 04.03.2013


Ответы (2)


Я думаю, вы неправильно интерпретируете это утверждение.

Если вы динамически генерируете элементы, рассмотрите следующие два сценария:

  1. Сгенерируйте элемент, добавьте его в DOM. Повторение.
  2. Сначала создайте DOMDocumentFragment. Добавьте элементы во фрагмент. Повторение. Добавьте фрагмент в DOM.

Метод 1 будет выполнять перерисовку для каждого добавляемого вами элемента. Метод 2 будет выполнять только одну перерисовку в конце. Если у вас мало элементов для добавления, метод 1, вероятно, подойдет. Если вы добавляете много узлов, метод 2 будет значительно быстрее.

Вот что подразумевается под повторная покраска стоит дорого.


Может быть, это хороший способ взглянуть на это:

Перерисовка имеет базовую стоимость, скажем, 100. Создание элемента DOM и добавление его стоит 1. Если вы выполняете метод 1 для 7 элементов, ваша стоимость будет (1 + 100) * 7 = 707. Если вы Выполняя метод 2, ваша стоимость будет: 1 * 7 + 100 = 107. Что значительно ниже. Цифры просто для иллюстрации. Вероятно, это гораздо больше, чем это, но я думаю, что это хороший и простой способ взглянуть на производительность перекраски.

person Halcyon    schedule 04.03.2013
comment
поэтому добавление, а затем удаление загрузчика gif из DOM является хорошим примером повторного потока? Это не может быть дорого. Я предполагаю, что если JS неоднократно добавляет/удаляет/скрывает/показывает большие фрагменты HTML, то, возможно, расходы становятся актуальными. - person tim peterson; 04.03.2013
comment
@timpeterson добавление gif действительно не повредит производительности (если только он не вытеснит еще 10000 элементов) - person John Dvorak; 04.03.2013
comment
@FritsvanCampen спасибо, так что искать альтернативы перекрашиванию/повторному течению даже разумная цель? - person tim peterson; 04.03.2013
comment
Я не думаю, что существует такая вещь. Если у вас проблемы с производительностью, рассмотрите возможность уменьшения количества элементов на экране. - person Halcyon; 04.03.2013

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

В общем, имейте в виду, что следующие операции всегда вызывают перекомпоновку:

  • Изменение дерева DOM путем добавления, удаления или перемещения узлов.
  • Изменение вычисляемых свойств CSS, таких как offsetWidth
  • Чтение вычисленных значений CSS с помощью getComputedStyle (или currentStyle в старом IE)

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

Установка стилей обычно вызывает перекомпоновку, но браузеры попытаются избежать этого, если изменение не может повлиять на положение или размеры других элементов[цитата].

Чтобы немного позабавиться с перекомпоновкой, см. раздел Будет ли перекомпоновка?

person bfavaretto    schedule 04.03.2013