Pull to refresh
Comments 25
Значит эта утилита годится только для замены текущего dom дерева на новое, пришедшее из ajax ответа? Хотелось бы увидеть результаты тестов производительности с и без утилиты.
Померял на реальном сложном куске HTML — DiffHTML показал такие результаты:
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

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

Аналог: morphdom и мой форк с поддержкой встроенного svg, сохранением позиции фокуса и гарантированным переиспользованием существующих уникальных (с id, key — в моём форке) элементов (оригинальный morphdom всё ещё имеет несколько кейсов типа этого).

Спасибо за наводку. Мне очень интересна эта тема.
Получается, что идея — в экономии некоторых if() в jQuery, лишь выбраны некоторые пороги узнавания диффов? Например, третий пример:
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, возможно уловите мою мысль.
А что насчет исполнения/добавления javascript-кода/функций в пришедших данных?
Автор предлагает делать это инлайновыми onclick=${onButtonClick}, пример тут. Но с событиями навешенными другими способами могут возникнуть проблемы.
Демается, что это было бы хорошо, но я прошел мимо лишь потому, что нет встроенного транслятора в 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.
ВНИМАНИЕ. На каждый новый тест закрываем все вкладки инкогнито и открываем снова.

В статье:
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 придётся от неё отказываться
dbmon для riot'а — это бэст кэйс, на других кэйсах там всё гораздо печальнее. API у риота вроде нормальное, впаривать они тоже умеют (всякая ложь типа минимальное кол-во дом операций итп), но вот если взглянуть на исходники, то реализация полное говно :)
У меня наоборот

diffhtml ... 19-20
Angular ... 12-14

MacBook Pro i5 / Chrome

Да, оказывается, на деле у DiffHTML показатели средние по больнице. Спасибо за наводку на бенчмарк.
Какие планы у автора касательно своего проекта? Планирует ли автор предлагать библиотеку как инструмент равный любому популярному фреймворку или это будет фича из разряда пониже (к примеру underscore.js)?
Хороший вопрос, пока ничего по этому поводу от автора не слышал. Но судя по инструментарию (транформер html в подобие Virtual DOM), автор предлагает DiffHTML как возможную альтернативу Rect.JS, например. Ну это лично у меня сложилось такое мнение.
тест с последней версией Ember (2.10)
http://mathieuancelin.github.io/js-repaint-perfs/ember/
Only those users with full accounts are able to leave comments. Log in, please.