Как стать автором
Обновить

Комментарии 18

Я как-то не интересовался джаваскриптовыми шаблонизаторами, поэтому хочется спросить у автора (а заодно и у читательского сообщества джаваскриптовикóв): существовали ли до этого шаблонизаторы с аналогичным (подстановки, итерации, фильтры, комментарии) или с бóльшим набором возможностей? Какие можете порекомендовать?

Самостоятельно пытаясь ответить на этот вопрос, сейчас полез в проект Node.js почитать вики-страницу «Modules», нашёл сообщение «DEPRECATED» и удаление ссылки с заглавной страницы вики. Совершённое не прохожим каким-нибудь вики-редактором, а одним из центральных участников проекта.

Долго нецензурно ругался, и даже на время позабыл, о чём сперва хотел спросить на Хабрахабре.

Однако вот вспомнил, возвращаюсь спросить.

Знает ли кто ответ?
Да полно. Для меня самые популярные:
Handlebarsjs
Dot.js
EJS

Первая ссылка гугла по javascript template engine.
stackoverflow.com/questions/7788611/what-javascript-template-engines-you-recommend

Вторая:
garann.github.io/template-chooser/
Есть очень продвинутый BEMHTML, но у него немного другая концепция и довольно сложно вкурить, как его прикрутить, к динамически изменяющимся данным, но результат получается неплохой.
Страница удалена потому что модулей стало слишком много, чтобы их отслеживать. Большое количество модулей из списка устарело, либо не поддерживается.
Некоторое время назад начал потихоньку дописывать doT, так как из всех существовавших он больше всех привлек. Основной репозиторий был заброшен долгое время, и PR они не принимали.

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

Тут можно посмотреть github.com/printercu/doT
Спасибо! Использовал doT в своем недопроекте. Непременно просмотрю ваш код — может удалю пару велосипедов.
Там тест стал неправильно работать. Движок MaskJs, как видно, сменил язык парсинга, поэтому он ничего по факту не делал, поэтому на тесте был быстрее всех.

jsperf.com/javascript-template-engine-compare/79 — исправленный тест (посмотрел доки MaskJs и написал правильно).

(Проблема этого теста в том, что он ведёт на актуальные версии шаблонизаторов. Еслли что-то в них изменилось, есть вероятность, что работать не будет или будет показывать неправильно, как в этом случае.)

И в лидерах в этом тесте — doT и underscore:
Класс! doT всё-таки самый быстрый))
Вот jsperf хороший сервис, но никогда не уверен в актуальности теста — не хватает удаления и редактирования. А Маска уже давно перешла немного в другую область — mvc движок — todomvc, поэтому на данный момент чистое сравнение с шаблонизаторами также не совсем верно. Одним главным отличием всегда было то, что генерировался DOM вместо HTML, и такой подход себя оправдывает в общей производительности приложения.
Это же лишняя работа — сначала push(), потом join(''). Быстрее будет просто собирать в строку.

… Ещё одну статью с самописным шаблонизатором к этой habrahabr.ru/post/201592/ (про doT.js) — и неделя шаблонизаторов состоится!
Не уверен. ИМХО как раз конкатенация строк — это очень затратная операция.
К тому же если строка будет очень большой, то это будет дополнительно тормозить.
Но, безусловно, возможно, что я ошибаюсь.
Последний раз когда я разбирался с этим вопросом на дворе стоял 2007 год, с тех пор многое могло измениться.

jsperf.com/array-join-vs-string-connect
НЛО прилетело и опубликовало эту надпись здесь
Вот, тоже об этом подумал.
У меня на каждом шаге цикла строка вычисляется же.
Предсказать её невозможно никак.
И я тут не знаю, что будет лучше, join или +=
Для разнообразия:

Вот был написал мной в свое время «шаблонизатор»: code.google.com/p/kite/
Объем (в LOC) примерно такой же как у автора, но
1. Компилируемый — идея.
2. {{mustache}} compatible + conditionals
Подключил к Вашему тесту dot().

Получилось, что jQuery.tmpl() вообще отдыхает — за 10 секунд не может быть сравним с остальными с одинаковым числом циклов. Поэтому число циклов пришлось увеличить, чтобы результаты точнее были, а jQuery.tmp — убрать. Выходит:

<script type="text/javascript" src="doT.js"></script>
<script type="text/doT" id="d-template">
  <ul>
    {{~it:val}}
      <li><b>{{=val.firstName}}</b> <i>{{=val.lastName}}</i></li>
    {{~}}
  </ul>
</script>

var NUM_REPETITIONS = 1500;
...
       function test_doT()
       {
         var template = $("#d-template" ).html();
         var html;
         var t1 = (new Date()).getTime();
         var compiled = doT.compile(template);
         for(var n = 0; n < NUM_REPETITIONS; ++n)
           html = compiled(data.contacts);
         var t2 = (new Date()).getTime();
         $("#out").html(html);
         
         return (t2 - t1) / NUM_REPETITIONS;
       }
...
res.push( { name:"doT", time: (test_doT()*1000), ratio:0, sloc:140 } );

Поскольку doT как-то вообще всем фору даёт, решил усложнить ему задачу и включить для него вариант с компиляцией в каждом цикле. Т.е. фактически интерпретатор. Получилось:

    html = doT.compile(template)(data.contacts);
Картина в Хроме:

(измерения не очень точны для коротких интервалов из-за малого общего интервала измерения, хотя было взято 6000 циклов; поэтому надо предполагать погрешность примерно в 10%).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории