Изменяет ли браузер всю страницу на изменения или только конкретные элементы?

Предположим, что у меня есть элемент с id #msg и при определенном условии я хочу добавить к нему класс, чтобы применить стиль, например. чтобы текст выглядел красным.
Я могу сделать $('#msg').addClass(theclass)
Мой вопрос: как реагирует браузер? Развертывает ли он всю страницу или повторно отображает этот конкретный элемент?

Ответ 1

В вашем примере (addClass) это зависит от того, что находится в добавляемом вами классе. Добавление самого класса только изменяет атрибут на целевом node.

  • Некоторые изменения вызовут repaint, то есть при изменении цвета, bgcolor и т.д. Только те элементы, к которым применяется новый CSS, будут повторно отображены.
  • Некоторые изменения вызовут reflow, то есть когда пространство видимое, занятое элементами или их содержимым, изменит размеры или позицию. В зависимости от их собственных свойств и свойств родительских и дочерних объектов, а также свойств родительских и дочерних элементов и т.д. И т.д. Перепланирование будет влиять на большее количество элементов в дереве документов.

Браузеры достаточно умны, чтобы изменять только элементы, требующие повторной рендеринга. Метод минимизации количества повторных рендерингов состоит в том, чтобы установить элемент position: absolute или display: none, чтобы временно удалить его из потока документов, внести изменения, а затем снова вставить. Это особенно важно, если, например, вы делаете какой-то элемент скольжения вниз. Если элемент находится в потоке и в начале дерева DOM, каждый пиксель, который он растягивает, вызовет повторную визуализацию.

Ради удовольствия, сделайте простую аналогию с бумагой на столе, в этом примере с вставкой элементов. Стол - это окно вашего браузера, = бумага, _= пустое пространство. Вы хотите поставить другой лист в верхнем левом положении. Это начальная ситуация:

□ □ □ □
□ □ □ □
_ _ _ _

После того, как вы положите новый лист на стол: (■ = новый, ▧ = перемещен)

■ □ □ □
▧ □ □ □
▧ _ _ _

Если вторая строка была одним длинным рулоном бумаги (= полный div), вся строка будет двигаться:

■ □ □ □
▧ _ _ _
▧▧▧▧▧▧▧

Если вы вставили лист в третью строку, переполнение не произойдет.

Примечание: Это теоретическое объяснение. Его эффективность будет зависеть от браузера. Источник: Высокопроизводительный Javascript, "Перепроверяет и переплачивает", стр .70.

Ответ 2

Мое понимание, основанное на результатах, представленных этим инструментом https://developer.chrome.com/devtools/docs/timeline, состоит в том, что НЕТ, весь DOM не перерисовывается/регенерируется, просто элемент, который имел изменение класса.

Демо

HTML:

<p>Lorem ipsum dolar sit amet...</p>

<input id="btn" type="button" value="click me" />

JavaScript:

$(document).on('click', '#btn', function () { 
  $('p').addClass('red')  
})

CSS

.red {
    color: red;
}

**** **** редактировать Мне пришлось изменить свой ответ от "Нет" к "Да", а затем "Нет" от "Да". Этот инструмент четко указывает на перерисовку рассматриваемого элемента, другие элементы DOM не затрагиваются.

Однако Если внутренний/внешний размер элемента изменяется или даже нужно запрашивать javascript, для этого потребуется перерисовать элемент DOM, и вся ветвь элементов будет перерисована, а затем кэширована браузером.

enter image description here