WebSocket - это, по сути, всего лишь набор кадров для данных TEXT или BINARY.
Он сам не выполняет сжатие.
Однако спецификация WebSocket позволяет Расширения, и в дикой природе было множество расширений сжатия (формализованные спецификации для одного из них завершены).
На сегодняшний день (август 2018 года) принятая спецификация сжатия - permessage-deflate
.
Некоторые расширения, замеченные в дикой природе:
permessage-deflate
- имя формализованной спецификации для использования deflate для сжатия целых сообщений , независимо от количества рамок websocket. x-webkit-deflate-frame
- раннее предложенное сжатие, которое сжимает каждый необработанный кадр данных websocket. Видел использование Chrome и Safari. (теперь устарел в Chrome и Safari) perframe-deflate
- переименованная версия вышеуказанного сжатия. Видимо, использование различных реализаций сервера websocket, а также вкратце проявилось в различных клиентах на базе WebKit . (Полностью устарела в современных браузерах, но все еще отображается в различных клиентских библиотеках WebSocket) Следует отметить, что расширение permessage-deflate
является первым в строке PMCE (сжатие для сообщений Расширения), которые в конечном итоге будут включать в себя другие схемы сжатия (обсуждаемые : permessage-bzip2
, permessage-lz4
и permessage-snappy
)
Я действительно сомневаюсь, что потомков можно удалить в O (1), даже с node.innerHTML = ''
, так как базовая реализация вполне может быть операцией O (N).
Что нужно учитывать для улучшения производительности, так это минимизировать количество повторений DOM.
const list = document.querySelector('ul');
const listClone = list.cloneNode(false);
list.parentNode.replaceChild(listClone, list);
<ul>
<li>First</li>
<li>Last</li>
</ul>
withElOutOfFlow(document.querySelector('ul'), el => {
while(el.lastChild) el.removeChild(el.lastChild);
});
function withElOutOfFlow(el, callback) {
const parent = el.parentNode;
if (!parent) {
callback(e);
return;
}
const nextSibling = el.nextSibling;
parent.removeChild(el);
callback(el);
if (nextSibling) parent.insertBefore(el, nextSibling);
else parent.appendChild(el);
}
<ul>
<li>First</li>
<li>Last</li>
<ul>
.cloneNode()
и .replaceChild()
] На 5% быстрее, чем ВСЕ примеры
(включая принятый ответ)
Следующий пример взят из Range API :
blockquote>const rng = document.createRange(); rng.selectNodeContents(document.querySelector('ul')); rng.deleteContents();
интерфейс Range работает с фрагментами документа, состоящими из узлов и текста. Хотя он выглядит медленным , на самом деле он быстрый и на 100% совместим со всеми браузерами .
Range Range
blockquote>
.createRange()
[1152].selectNodeContents()
.deleteContents()
.replaceWith()
и.createElement()
на 15% медленнее, чем все примеры
Это комбо быстрее большинства примеров и менее многословно (за исключением диапазона демонстрация - самая быстрая.)blockquote>document.querySelector('ul').replaceWith(document.createElement('ul'));
Это 2 взаимодействия DOM: найдите список и замените его пустым списком. См. Демонстрацию 1. Если вы хотите поддерживать IE11 (глобальная доля ATM 2,26%) , не используйте его.
Демонстрация 1
API диапазона
const rng = document.createRange(); rng.selectNodeContents(document.querySelector('ul')); rng.deleteContents();
ul { min-height: 30px; min-width: 30px; outline: 1px dashed red; }
<ul> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> </ul>
[ 1166] Демонстрация 2
.replaceWith()
и.createElement()
<час>document.querySelector('ul').replaceWith(document.createElement('ul'));
ul { min-height: 30px; min-width: 30px; outline: 1px dashed red; }
<ul> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> </ul>
.insertAdjacentHTML()
и amp;.createDocumentFragment()
@ 50% медленнее, чем все примеры
Лучший способ оптимизировать любые манипуляции с DOM - не иметь их. Держите доступ DOM к минимуму - это очень много времени. Каждый раз, когда механизм JS ищет элемент, он будет проходить по дереву DOM, каждый раз, когда тег добавляется или удаляется, узлы (элемент, текст и т. Д.), Которые уже находятся в DOM, должны пересчитываться для определения местоположения и размеров, чтобы даже если количество задействованных узлов всего несколько, это может привести к исключительно длительному процессу для браузера. Это называется reflow, и похожая проблема, связанная со стилями CSS, называется перерисовкой.
Следующая демонстрация удаляет все<li>
в<ul>
с 4 операциями DOM:blockquote>
Ссылается на поиск
]<ul>
- 1Ссылочный родительский элемент
<ul>
добавляет пустой<ul>
- 1 поиск, 1 добавлениеСоздайте
documentFragment
и добавьте оригинал [ 1128] к нему - 1 удаление
.insertAdjacentHTML()
без деструктивного рендерингаhtmlString
в HTML и он очень оптимизирован .
.createDocumentFragment()
никогда не касается DOM и все, что к нему прикреплено, больше не касается DOM.
Демонстрация 3
.insertAdjacentHTML
и.createDocumentFragment()
]// Reference the <ul> const list = document.querySelector('ul'); // Reference parent of <ul> append an empty <ul> list.parentElement.insertAdjacentHTML('beforeend', `<ul></ul>`); // Create a document fragment and append original <ul> to it document.createDocumentFragment().appendChild(list);
ul { min-height: 30px; min-width: 30px; outline: 1px dashed red; }
<ul> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> <li>ITEM</li> </ul>