Comments 25
Значит эта утилита годится только для замены текущего dom дерева на новое, пришедшее из ajax ответа? Хотелось бы увидеть результаты тестов производительности с и без утилиты.
Можно еще UI компоненты делать, на подобие React / Riot (https://github.com/jmas/htmldiff-todo/blob/master/src/ui.js). Бенчмарки самому интересны.
Померял на реальном сложном куске HTML — DiffHTML показал такие результаты:
На однородном глубоком дереве из DIV лучше всего работает стандартный
Как оказалось, не так просто подготовить объективный бенчмарк. Если есть идеи как оценить объективно — пишите.
el.innerHTML ... 742ms
diffhtml.innerHTML() ... 136ms
morphdom() ... 2023ms
На однородном глубоком дереве из DIV лучше всего работает стандартный
el.innerHTML
, morphdom()
— средний результат, а diffhtml.innerHTML
— хуже всего.Листинг бенчмарка
import * as diffhtml from 'diffhtml';
// import morphdom from 'morphdom';
var rootEl = document.getElementById('root');
var tpl = `...`;
// console.profile("diffhtml.innerHTML()");
var fn = function () { return Math.ceil(Math.random()*1000); };
var start = window.performance.now();
for (var i=0,ln=1000; i<ln; i++) {
// str += tpl;
// V1 = innerHTML
// rootEl.innerHTML = tpl//tpl.replace(/\{rnd\}/ig, fn);
// V2 = diffhtml.innerHTML
diffhtml.innerHTML(rootEl, tpl);
// V3
// morphdom(rootEl, tpl);
}
// console.profileEnd();
console.log(Math.ceil(window.performance.now() - start));
Как оказалось, не так просто подготовить объективный бенчмарк. Если есть идеи как оценить объективно — пишите.
Чем больше DOM деревья и сильнее отличаются, тем менее эффективным будет difhtml. Это сразу понятно было, но надежда была на некую магию. Но для мелких кусочков годится, ведь его же можно и отдельно для некоторых элементов применять?
Как раз на большом реальном дереве получилось очень быстро, быстрей чем обычный innerHTML. Попробую разобраться почему. За ссылку на бенч отдельное спасибо.
Нужно принять во внимание, что холодная вставка (пустой контейнер) будет скорей всего всегда хуже. В своем бенче у меня было 1000 операций вставки подряд одного и того же дерева.
>Как оказалось, не так просто подготовить объективный бенчмарк. Если есть идеи как оценить объективно — пишите.
Если не лень, можете спортировать этот бэнчмарк https://github.com/localvoid/uibench-react/
Вот пример результатов этого бэнча: https://cdn.rawgit.com/localvoid/6715c4b23eadc460112e671b4add3710/raw/907901966dd0473f1026d1ff25e244a022eb5ab1/uibench_results.html
В бэнчмарках уи либ невозможно получить какую-то одну цифру по которой можно сказать что какая-то одна библиотека быстрее другой, нужно рассматривать кучу различных кэйсов.
Если не лень, можете спортировать этот бэнчмарк https://github.com/localvoid/uibench-react/
Вот пример результатов этого бэнча: https://cdn.rawgit.com/localvoid/6715c4b23eadc460112e671b4add3710/raw/907901966dd0473f1026d1ff25e244a022eb5ab1/uibench_results.html
В бэнчмарках уи либ невозможно получить какую-то одну цифру по которой можно сказать что какая-то одна библиотека быстрее другой, нужно рассматривать кучу различных кэйсов.
Получается, что идея — в экономии некоторых if() в jQuery, лишь выбраны некоторые пороги узнавания диффов? Например, третий пример:
Не проще ли написать сразу плагин к jQuery для условной манипуляции DOM? Преимущество в том, что не создаётся новый инструмент, а расширяется давно известный, дополняются лишь правила. Не будет, например, перестановки параметров. Если смущает увесистость jQuery, то у меня есть функция на 1.5K, которая делает элементы условной манипуляции и при этом заменяет основные функции jQuery (аналогичные микролибы — $dom.js, balalaika и другие).
И объём DiffHTML — 80К, что подсказывает, что туда вошли много правил, парсер шаблонов, частично исполняющие роли jQuery. Плагин был бы легче. Другими словами, хотел бы сказать, что оформленные идеи, работающие в коде — конечно, хорошо, но описанное в Гитхабе API наводит на мысли, что к частичным целям можно идти другими и более спрямлёнными путями.
var $temp = $('h1.title', document.body);
if($temp.length && $temp.html() =='Hello world!')
$temp.after('<p>Dear, World!</p>');
Если так, то, действительно, наличие условных инструментов модификации DOM постоянно требуется. Но как в DiffHTML напишется аппенд к любому содержимому (innerHTML) блока $temp? Наверное, надо вводить метасимволы типа "*" и дальнейшие правила разбора шаблона (второго параметра).Не проще ли написать сразу плагин к jQuery для условной манипуляции DOM? Преимущество в том, что не создаётся новый инструмент, а расширяется давно известный, дополняются лишь правила. Не будет, например, перестановки параметров. Если смущает увесистость jQuery, то у меня есть функция на 1.5K, которая делает элементы условной манипуляции и при этом заменяет основные функции jQuery (аналогичные микролибы — $dom.js, balalaika и другие).
И объём DiffHTML — 80К, что подсказывает, что туда вошли много правил, парсер шаблонов, частично исполняющие роли jQuery. Плагин был бы легче. Другими словами, хотел бы сказать, что оформленные идеи, работающие в коде — конечно, хорошо, но описанное в Гитхабе API наводит на мысли, что к частичным целям можно идти другими и более спрямлёнными путями.
Я наверное поясню для чего это все. При помощи подобных библиотек можно абстрагироваться от манипуляции DOM, а перенести работу с шаблонами на уровень текстовых строк-шаблонов.
Да, подход не идеален, и здесь есть много не решенных вопросов, но практика показывает, что чем больше работы с DOM, тем сложней вносить апдейты в DOM-структуры (например переезжать с одного UI-фреймверка на другой). Все грубо говоря жестко прибито к селекторам и определенной вложенности.
Вы можете взглянуть на UI часть ToDo, возможно уловите мою мысль.
Да, подход не идеален, и здесь есть много не решенных вопросов, но практика показывает, что чем больше работы с DOM, тем сложней вносить апдейты в DOM-структуры (например переезжать с одного UI-фреймверка на другой). Все грубо говоря жестко прибито к селекторам и определенной вложенности.
Вы можете взглянуть на UI часть ToDo, возможно уловите мою мысль.
А что насчет исполнения/добавления javascript-кода/функций в пришедших данных?
А почему было не сделать обертку над incremental-dom?
tl;dr не используйте ни diffhtml, ни morphdom. Они даже на синтетике не могут показать хорошие результаты.
1. Открываем http://mathieuancelin.github.io/js-repaint-perfs/ в режиме инкогнито дабы исключить влияние плагинов браузера. (Прим. есть и более сложные способы получить более аккуратные результаты)
2. Chrome devtools. Sources. Press Escape. Rendering. FPS meter. Включаем.
3. Открываем http://mathieuancelin.github.io/js-repaint-perfs/diffhtml/index.html на разрешении 1920*1080. (Дабы потом результаты не расходились с таблицей ниже)
4. Ждем 10 сек устаканивания fps.
ВНИМАНИЕ. На каждый новый тест закрываем все вкладки инкогнито и открываем снова.
Не удовлетворяемся результатами т.к. библиотека развивается. Может что-то пофиксили.
1. Скачиваем содержимое http://mathieuancelin.github.io/js-repaint-perfs/diffhtml/index.html (chrome сохранить страницу целиком)
2. Забрасываем в папку dbmon (diffHTML)_files https://raw.githubusercontent.com/tbranyen/diffhtml/master/dist/diffhtml.js
3. Патчим до https://gist.github.com/vird/ff236a38b6b72e23a9e87c88e38760cd
4. Запускаем по инструкции выше.
Получаем тот же fps.
morphdom, честно, было лень патчить и проверять.
Замечания к методике тестирования и результатам принимаются.
P.s. Есть еще todomvc benchmark. Кто бросит ссылку на большую сборную солянку 20+, тому отдельное спасибо. Ато на http://todomvc.com/ только примеры.
1. Открываем http://mathieuancelin.github.io/js-repaint-perfs/ в режиме инкогнито дабы исключить влияние плагинов браузера. (Прим. есть и более сложные способы получить более аккуратные результаты)
2. Chrome devtools. Sources. Press Escape. Rendering. FPS meter. Включаем.
3. Открываем http://mathieuancelin.github.io/js-repaint-perfs/diffhtml/index.html на разрешении 1920*1080. (Дабы потом результаты не расходились с таблицей ниже)
4. Ждем 10 сек устаканивания fps.
ВНИМАНИЕ. На каждый новый тест закрываем все вкладки инкогнито и открываем снова.
В статье:
diffhtml 14-17
morphdom 11-17
mainstream:
(тут должен быть jquery)
vanilla-optimized 31-33
React 31-34
Backbone 25-27
Angular 28-31
Angular 2.0 Alpha 38-40
vuejs 35-36
ember 0-1 (нужен тест с последней версией, не верю)
Aurelia 33-36 ( http://jdanyow.github.io/aurelia-dbmonster/ )
hipsters:
riot 21-23
Elm 32-36
vidom 41-44
Monkberry 43-45
Inferno 40-43
frzr 40-42
моя поделка 40-43
вне конкурса:
canvas 60
Software:
Chrome 52.0.2743.116 m.
Windows 7 64bit
Hardware:
CPU : AMD A10-7850K (не самый плохой процессор https://www.cpubenchmark.net/high_end_cpus.html 5548 где-то сзади в high end)
GPU : AMD 7970 (не самая плохая видеокарта http://www.videocardbenchmark.net/high_end_gpus.html 5246 где-то top 42)
А теперь представьте как всё это будет тормозить на чём-то по-слабее
Не удовлетворяемся результатами т.к. библиотека развивается. Может что-то пофиксили.
1. Скачиваем содержимое http://mathieuancelin.github.io/js-repaint-perfs/diffhtml/index.html (chrome сохранить страницу целиком)
2. Забрасываем в папку dbmon (diffHTML)_files https://raw.githubusercontent.com/tbranyen/diffhtml/master/dist/diffhtml.js
3. Патчим до https://gist.github.com/vird/ff236a38b6b72e23a9e87c88e38760cd
4. Запускаем по инструкции выше.
Получаем тот же fps.
morphdom, честно, было лень патчить и проверять.
Замечания к методике тестирования и результатам принимаются.
P.s. Есть еще todomvc benchmark. Кто бросит ссылку на большую сборную солянку 20+, тому отдельное спасибо. Ато на http://todomvc.com/ только примеры.
BTW. На хабре еще упоминались
matreshka.js 26-28
Angular light 35-38
Как жаль, что у riot такой низкий показатель. Мне прям очень нравится эта библиотечка. Буду знать, что для перегруженных UI придётся от неё отказываться
У меня наоборот
MacBook Pro i5 / Chrome
Да, оказывается, на деле у DiffHTML показатели средние по больнице. Спасибо за наводку на бенчмарк.
diffhtml ... 19-20
Angular ... 12-14
MacBook Pro i5 / Chrome
Да, оказывается, на деле у DiffHTML показатели средние по больнице. Спасибо за наводку на бенчмарк.
Вы тестировали неоптимизированный angular. Попробуйте
http://mathieuancelin.github.io/js-repaint-perfs/angular/opt.html
http://mathieuancelin.github.io/js-repaint-perfs/angular-track-by/
http://mathieuancelin.github.io/js-repaint-perfs/angular/opt.html
http://mathieuancelin.github.io/js-repaint-perfs/angular-track-by/
Вторая ссылка по недосмотру битая
http://mathieuancelin.github.io/js-repaint-perfs/angular-track-by/
http://mathieuancelin.github.io/js-repaint-perfs/angular-track-by/
Какие планы у автора касательно своего проекта? Планирует ли автор предлагать библиотеку как инструмент равный любому популярному фреймворку или это будет фича из разряда пониже (к примеру underscore.js)?
тест с последней версией Ember (2.10)
http://mathieuancelin.github.io/js-repaint-perfs/ember/
http://mathieuancelin.github.io/js-repaint-perfs/ember/
Sign up to leave a comment.
DiffHTML.js — утилита для патчинга DOM