HTML insertBefore и управление макетом / перекомпоновкой
У меня есть список, который я хочу обновить в ответ на событие, чья полезная нагрузка содержит новый элемент списка. Я хочу добавить новый элемент списка в список.
Я использую следующую логику, чтобы добавить новый список сообщений, полученный от события, к списку.
<html>
<script>
function addItem() {
setInterval(() => {
var ul = document.getElementById('mylist');
var newItem = document.createElement('li')
newItem.innerHTML = 'hello0.0'
ul.insertBefore(newItem, ul.childNodes[0]);
}, 1000);
}
</script>
<body>
<button onclick='addItem()'> </button>
<ul id='mylist'>
<li id="insertPoint"> hello1 </li>
<li> hello2 </li>
</ul>
</body>
</html>
Теперь, когда я профилирую это в Chrome, каждый раз, когда происходит событие, происходит повторное ожидание. Chrome говорит мне, что около 7 узлов требуют компоновки. Это число является постоянным, даже если список содержит сотни элементов.
Теперь мои вопросы
i) Каковы эти 7 узлов, которые нуждаются в макете?
ii) Похоже, что краска нарисована на всем документе, так как список непосредственно прикреплен к телу. Таким образом, если список содержит 1000 элементов, хотя макет выполняется только для 7 узлов, все элементы по-прежнему необходимо перекрашивать. Есть ли более разумная тактика, чтобы избежать этого?
1 ответ
Обновить
После предоставления HTML-кода я настраиваю тестовый пример, который включает следующие методы:
Общая скорость - это суть, перекраска - это только часть большого мира, который является DOM. На Chrome оба insertAdjacentElement/HTML
были значительно быстрее, чем insertBefore()
(на @10%), тогда как в Firefox только незначительно (на.55%).
i) Каковы эти 7 узлов, которые нуждаются в макете?
Узлы могут быть элементами, текстом, комментариями, пробелами и т. Д., Поэтому это зависит от контекста. Это звучит тривиально, это постоянная 7.
ii) Похоже, что краска нарисована на всем документе, так как список непосредственно прикреплен к телу. Таким образом, если список содержит 1000 элементов, хотя макет выполняется только для 7 узлов, все элементы по-прежнему необходимо перекрашивать. Есть ли более разумная тактика, чтобы избежать этого?
Единственный способ избежать полной перекраски страницы - AJAX AFAIK.
Пытаться insertAdjacentHTML()
хотя его название является полным, это очень быстрый и гибкий метод. Вот подпись:
стихияinsertAdjacentHTML ( "position", string);
элемент: любой элемент, способный содержать контент (т.е. имеет конечный тег
</*>
)"позиция": есть четыре позиции, которые относятся к элементу:
"beforebegin": вставляемый элемент (т. е. второй параметр: строка) будет помещен перед элементом. э.
insertBefore()
- ех.
<li>string</li>
<ul>element</ul>
- ех.
"afterbegin":строка будет помещена вэлемент перед всеми дочерними элементами. э.
parentNode.prepend()
- ех.
<ul>
<li>string</li>
,<li>item</li>
,<li>item</li>
</ul>
- ех.
"beforeend": строка вставляется в элемент как последний дочерний элемент. э.
appendChild()
- ех.
<ul>
<li>item</li>
,<li>item</li>
,<li>string</li>
</ul>
- ех.
"afterend": строка помещается после элемента. э. не существует и, кроме того, просто используя
insertAdjacentHTML()
другая альтернатива слишком запутанная, я не собираюсь ее включать.- ех.
<ul>
<li>item</li>
,<li>item</li>
</ul>
<li>string</li>
- ех.
string: это строка, представляющая один или несколько элементов, которые будут отображаться в HTML. э.
innerHTML
демонстрация
const btn = document.querySelector('.btn');
const li = `<li class='item'>Item</li>`;
const ul = document.querySelector('.ul');
btn.addEventListener('click', function(e) {
ul.insertAdjacentHTML('afterbegin', li);
}, false);
<button class='btn'>ADD</button>
<ul class='ul'></ul>