Преимущества произвольных тегов, или как я отказался от HTML разметки

    Уже какое то время использую/разрабатываю библиотеку MaskJS. Вначале использовал её только как движок для шаблонов, а со временем, она полностью заменила HTML. В статье расскажу какими преимуществами обладает компонентный подход в разработке приложений и данная реализация в частности. Если выделить по-пунктам, то мы получим приблизительно такой список:
    • Скорость
    • Обработчики тегов
    • Пре- и Пост-процессоры
    • IoC
    • Изоляция/Декомпозиция
    • Разметка — Модель — Код — Стили

    Более подробно о самой библиотеке и примеры можете посмотреть здесь — libjs/Mask, a исходники тут — github/Mask

    § Скорость


    1. Производительность

      Сразу о ней, так как всегда первым вопросом, после длительного описания всех преимуществ, я слышу — «Ну хорошо, это у тебя реализовано через свой DOM Builder и все это вкусно, но наверное производительность страдает?!». Поэтому поспешу вас уверить, что данная библиотека даже быстрее, чем то, что вы сейчас используете. Извините за попсовое заявление, возможно я и ошибаюсь, но давайте углубимся.
      Разберем тест, который приводил уже ранее, jsperf.
      Замечу, что для меня, как для своих проектов, так и для работы важны Webkits JavaScriptCore и V8. Как видно из тестов — компиляция и рендеринг опережает другие решения во многих браузерах.
      Mustache здесь немного в преимуществе, так как он кэширует скомпилированный шаблон.

      Компиляция/Парсинг шаблона. Первый выигрыш

      Из шаблона мы строим JSON дерево вида {tagName:'div',attr:{...},nodes:[...]}. Моей первой идеей было подготавливать шаблоны для клиента — для дальнейшего var template = JSON.parse(serializedJsonDom), но когда я провел тесты, oказалось, что mask.compile в целевых движках быстрее JSON.parse — jsperf, а в других браузерах не сильно уступает последнему. Так что прекомпиляция отпадает уже из-за ненадобности.

      Построение DOM. Второй выигрыш

      Получив JSON дерево, мы строим DocumentFragment, который потом вставляем в «живой» DOM. Из теста видно, что и здесь производительность на уровне. Я оставил чистый .appendChild(documentFragment), чтобы показать, что вся соль в создании DocumentFragment. И что опять интересно, .innerHTML здесь тоже уступает в производительности (Chrome).

      Важным моментом также является, что мы изначально рендерим все в один заход. Разберем пример с jQuery виджетами. Как обычно все происходит:
      • в макете указываем контейнер <div id='myWidget'></div>
      • в javascript-e $('#myWidget').myWidgetInit(config);

      Огромным недостатком данного подхода является то, что мы создаем виджет в уже готовый DOM элемент. А как известно менять «живой» DOM вещь относительно дорогая. И при том мы должны признать, что часто у нас не один виджет в приложении.

      Вот собственно и получаем в итоге очень быстрый DOM Builder.

    2. Скорость разработки

      Более подробно это мы рассмотрим в следующих параграфах, собственно ради этого и затевалась эта статья. Здесь же просто отмечу, что произвольные теги существенно повышают скорость и удобство разработки. Рассмотрим данный макет:
      header > menuBar {
          li target='item1' > 'Item1 Title'
          li target='item2' > 'Item2 Title'
      }
      viewsManager {
          view#item1 > carousel {
              img src='img1.png';
              img src='img2.png';
          }
          view#item2 > scroller {
              'About Content'
          } 
      }
      

      Если у нас компоненты menuBar, viewsManager, scroller, carousel и slider уже готовы, то нам даже ничего в javascript-e дополнительно писать не надо, что бы меню и вьюшки переключались, что бы работал скролл, что бы картинки крутились. Разве не прелесть? И разве не для этого существует макет? Конечно многие виджеты умеют также самo-инициализироваться, но в основном это реализовано через Dom Ready Event и поиск/замену нужных тегов — все это дополнительный «overhead». Здесь же все проходит через этот самый DOM Builder. Вы можете вставить такой макет в любое время и он будет работать.



    § Обработчики тэгов


    Это и есть наши компоненты. Builder встретив тег обработчика, проинициализирует объект класса, и передаст контекст рендеринга в этот обработчик — никакой магии. Если же никто под тегом не зарегистрирован — создаст элемент сам. Для более полной и удобной работы с компонентами имеется также небольшой «абстрактный и не только» класс Compo (Исходники, Документация)

    § Препроцессоры


    Учитывая, что у нас древовидный render flow, мы получаем мощный инструмент воздействие на рендеринг и макет в целом. Препроцессорами я называю компоненты которые изменяют нижний макет. Таким образом мы как бы внедряемся нашим компонентом в макет — правим по усмотрению нижний шаблон или подменяем входные данные модели и продолжаем рендерить. Это очень удобный паттерн для построение разных макетов (layouts). Вот пример с MasterPages (asp.net привет):
    layout:master#twoColumnLayout  {
        div.wrap {
            div.layoutLeft > placeholder#left;
            div.layoutLeft > placeholder#right;
        }
    }
    layout:view master='twoColumnLayout' {
        left { /** content */ }
        right { /** content */  }
    }
    

    Компонент #twoColumnLayout должен конечно дополнительно подгрузить свои стили, но об этом в другой раз.
    Это очень простой пример, но здесь видно, как элементарно мы можем подставлять разные шаблоны нашему представлению. Пример реализации — layout.js

    § Постпроцессоры



    Их также можно назвать декораторами. Здесь мы изменяем уже родителей, и не шаблон, так как он уже прорендерин, а непосредственно HTMLElement (мы помним, что работаем с DocumentFragment, так что все изменения безболезненны). Такой подход также является мощным помощником при проектировании. На примере биндингов:
    div {
        bind value='name';
        bind value='status' attr='class';
    }
    

    Здесь постпроцессор свяжет модель с элементом div.
    var person =  { name: "Alex", status: "happy" }
    container.appendChild(mask.renderDom(template, person));
    setTimeout(function(){ person.status = 'busy' ; person.name="Anonym" }, 1000);
    

    Код думаю понятный. А реализацию можно посмотреть здесь — github

    § Inversion of Control (Dependency Injection)


    Извините за названия параграфа — название «уж больно сильно» нравится. Эх звучит то как… Не так мне сам паттерн нравится, как его название — чувствуется мощь. Простите за лирику, не удержался. Возвращаясь к нашей теме, можно сказать, что произвольные теги открывают нам горизонты новых или хорошо забытых старых паттернов.
    В планах реализовать, например, фабрику редакторов свойств:
    form {
        propertyEditor value='name';
        propertyEditor value='birthday';
        propertyEditor value='age';
    }
    

    А реализация будет выглядеть примерно так:
    mask.registerHandler('propertyEditor', Class({
        render: function(values, container, cntx){
            var value = Object.getProperty(values, this.attr.value),
                  template;
            switch(Object.typeOf(value)){
                case 'string': 
                    template = Object.format('input type="text" value="#{%1}" > bind value="#{%1}" prop="value";',this.attr.value);
                    break;
               case 'datetime':
                    template = Object.format('datePicker date="%1";', value.toString());
                    break;
               /** и так далее */
            }
            mask.renderDom(template, values, container, cntx);       
       });
    }}
    


    Важным моментом здесь является то, что мы можем внедрятся в шаблон переопределив любой из тегов, даже тот же «DIV» — это открывает нам неограниченные горизонты для манипуляции с представлением, тестирования и прочего, что на ум придет.

    § Изоляция


    Произвольные теги, или вернее их обработчики, поддаются хорошей изоляции. Как это и должно быть при блочной композиции, любой блок может быть выделен в отдельный проект (декомпозиция), разработан, протестирован и подключен обратно. Например, если из примера выше у нас нет компоненты «карусель» — мы закрываем основной проект, разрабатываем компонент который вращает своих детей (картинки), возвращаемся в основной проект и подключаем его. Наш загрузчик должен уметь подгружать все нужные компоненту ресурсы, такие как вспомогательные картинки и стили. О загрузчике я уже рассказывал, и потом хочу еще пару слов сказать, так как появилось несколько интересных идей. Но это в следующей статье.
    Изоляция важна не только в процессе разработки, но и в архитектуре приложения. Это достигается через событийную модель.

    § Разметка — Модель — Код — Стили


    Я очень люблю структуру вэб программирования (разметка — код — стили), поэтому старался придерживаться ее в MaskJS — максимально убрать логику из разметки сконцентрировавшись на макете и данных. Посмотрите на другие шаблонизаторы — циклы, условия, выражения и прочее. Мне кажется, намного приятнее иметь такoe (кода нет, есть только макет):
    ul > list value='users' > li > '#{name}'
    

    Тег(компонент) list; возьмет массив "users" из модели переданную в шаблон, и продублирует свой шаблон li > "#{name}" N(users.length) раз. Все остальное можно также через компоненты реализовать, или воспользоватся уже готовым решением. Таким образом макет — макетом, код — кодом, а стили — стилями. Все это должно переплетаться по-минимуму. Конечно — это все субъективно, и возможно я в корне не прав, а вы знаете все намного лучше.

    § Уход от HTML


    В силу всего выше сказанного, я полностью отказался от написания обычного HTML. В странице имеем тег скрипт с типом «mask/template» содержимое которого рендерим в DOM. Многие готовые библиотеки для удобства стараюсь оборачивать в компонент, как на пример — TimePicker

    Прошу прощение, если кого-то обидел или где-то ошибся. Хотя в Chrome есть отличная проверка на орфографию, так с пунктуацией он не помогает, а наверное «ой как надо».

    Удачного дня!
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 47

      +1
      А я вот хочу, чтобы допилил web qml, там и синтаксис приятный и работать оно теоретически может очень быстро.
      • UFO just landed and posted this here
          +5
          Спасибо не надо. Лучше уж запилить новый фреймворк без привязки к MS.
            0
            К слову, Microsoft представили CSS3 Grid Layout. Вкусно :)

            Есть ещё FlexBox Module, который уже худо-бедно поддерживается в браузерах. Я с ним вчера побаловался — лучами счастья изошёлся.
            +12
            Толку от IE? Надо чтобы это стало стандартом на всех браузерах.

            а так красота, да)
              +3
              Это будет ActiveX N2 по своему влиянию на веб. Помнится, благодаря первому появилось сумасшедшее количество вебинтерфейсов, которые не могли работать нигде, кроме IE, причем строго определенных версий.
              +8
              Есть хорошая библиотека от гугла, использующая такой подход — AngularJS.
                +20
                Я боюсь представить, во что обойдется поддержка проектов на этом, если вдруг придется искать нового разработчика.
                  +1
                  А что вас смущает? Синтаксис? Ведь, что касается функционала кастомных контролов, так там важна только одна функция «render». Шаблонизатор относительно простой. И к тому же, не подумайте, я никого не заставляю этим пользоватся — просто рассказал, что и почему использую сам.
                  0
                  Без обид, но в IE 8 не работает. Пускай ещё пару лет полежит.
                    +2
                    Ничего :) Сам шаблонизатор уверен работает, сайт на гитхабе делал «очень» на скорую руку, и все проверить не мог.
                    0
                    Вы пишете про то, что свойство «innerHTML» работает медленно, а как насчет более быстрого и, в большинстве случаев, более правильного метода «insertAdjacentHTML», который, если не ошибаюсь, уже все браузеры поддерживают?
                      0
                      Спасибо, хорошее замечание, но insertAdjacentHTML не во много раз быстрее, особенно если мы вставляем хтмл в пустую ноду. Все равно требуется время на парсинг и построение дерева. Добавил новый тест: jsperf:2. И вообще смысл был, не показать, что вот — я сделал нечто — и оно быстрее браузера ;) Конечно же решение немного медленное — но максимально приближено к возможностям браузера, и пока что одно из самых быстрых решений «доселе» мне известных.
                      0
                      а как насчет SEO? Как индексируются ссылки? И, например, google отображает страницу в кэше или вообще отказывается от индексирования сайта?
                        0
                        Много вам по этому поводу не скажу, так как этим я не занимаюсь. Оптимизация происходит наверное, как во всех остальных, обычных SaaS приложениях. Помню, что можно в robots.txt указать ссылку на sitemap index с перечнем sitemap-ов для нужных категорий, ну а там
                         <urlset xmlns="...">
                         <url>
                         <loc>url</loc>
                         <lastmod>date</lastmod>
                         </url>
                        

                        Такие ссылки генерируются программно, значит и данный «html» может тоже быть преобразован и отдаваться поисковикам.
                          0
                          Да в вопросе не столь важно пройдет ли Google кроулером по сайту. В SEO важно, индексирует ли он ссылки, анкоры. Причем, на PR влияют ссылки с других ресурсов, их расположение на странице, внутренняя перелинковка. А ссылки из sitemap не имеют веса в SEO для всех ПС.
                        –1
                        Круто, уже много лет назад отказался от HTML, правда не дошли руки написать свой шаблонизатор, так что написал классический дом строитель который позволяет быстро и удобно создавать ноды в JS, тем самым избавившись от привязки JS к существующему дому, сделав его провайдером view приложения.
                        Выглядит примерно так:
                        node.root = Node('div', {'class' : 'menu'},
                          Node('div', {'class' : 'left'},
                            node.form = Node('form', {'class' : 'form'},
                              Node('h1', 'Authorize'),
                              Node('div',
                                node.email = Node('input', {'type' : 'text',  'value' : 'test@gmail.com'})
                              ),
                              Node('div',
                                node.password = Node('input', {'type' : 'password',  'value' : '123'})
                              ),
                              Node('div',
                                node.submit = Node('div', {'class' : 'button left'}, 'Authorize'),
                                node.cancel = Node('div', {'class' : 'button'}, 'Cancel')
                              )
                            )
                          ),
                          Node('div', {'class' : 'right'},
                            Node('div', {'class' : 'inner'},
                              Node('h1', 'New User'),
                              Node('p', {'innerHTML' : 'Haven\'t registered yet?<br/>Please become a our subscriber.'})
                            )
                          )
                        )
                        node.form.addEventListener('submit', function(){
                          //some actions
                        }, false);
                        document.body.appendChild(node.root);

                        Больше всего понравилась ваша идея с пост/препроцессорами. Правда думаю было бы круче как-то их доработать, добавить чуточку магии :)
                          +7
                          У вас какой то шаг назад, выглядит крайне неудобным и многословным, имхо.

                          P.S. А как на это поисковики реагируют, адекватно?
                            0
                            выглядит крайне неудобным и многословным

                            Сохраняет вложенную структуру HTML для лучшего понимания, в принципе ее редактировать может даже кодер, при этом по размерам меньше HTML кода. Элементы генерируется во view компоненте приложения независимо от дома, что позволяет сделать пре-обработку дома до того как он появится в дом структуре. К тому-же такой подход полностью убирает необходимость использовать дом селекторы, т.к. все нужные ноды уже в есть в скопе приложения.
                            А благодаря такой чудесной особенности ООП как полиморфизм, возможно создавать целые семейства view компонентов с возможностью их прозрачной подмены в рантайме. Причем благодаря такому подходу можно полностью редизайнить приложение, т.к. JS не привязан ни к структуре DOM, ни к id/class/tagname. Все преимущества на лицо.

                            Естественно дом строитель уступает по гибкости шаблонизаторам как в этой статье.
                            P.S. А как на это поисковики реагируют, адекватно?

                            Честно говоря, никогда не занимался сайтами. Делаю в основном приложения и веб сервисы, там SEO вообще не стоит как задача.
                              0
                              Вы правильно рассуждаете. Но вы в самом начале пути. Мы начинали с чего-то подобного. Но как здесь заметили в таком виде не очень удобно описывать шаблоны, к тому же теряется наглядность. Лучше оставить описание шаблона в виде html/xhtml формате с дополнениями. Конечно, для этого придется реализовывать свой парсер и т.п. но оно того стоит. Да и ссылки удобно хранить не только на элементы, но и на текстовые узлы, атрибуты и комментарии.
                              В общем посмотрите на реализацию шаблонов в basis.js (надеюсь все же будет скоро статья на хабре) — это то куда мы пришли.
                              Если кратко, то получается так
                              var myTemplate = new basis.template.html.Template(
                                '<div class="menu">' +
                                  '<div class="left">' + 
                                    '<form{form} class="form">' +
                                      '<input{email} type="text" value="{emailValue}">' +
                                      ....
                                '</div>'
                              );
                              var domMap = myTemplate.createInstance();
                              // domMap.element -> <div class="menu">
                              // domMap.form -> <form class="form">
                              // и т.д.
                              domMap.set('emailValue', 'some@email.ru');
                              

                              Хотя шаблоны мы храним каждый в отдельном файле, а в коде пишем только на этапе прототипирования. В шаблон так же добавляется подключение css стилей. Напрямую мы не заполняем шаблон, это делает соответствующий компонент. Шаблоны могут динамически менять исходный код. Например:
                              myTemplate.setSource('<div>new source</div>');
                              

                              Заменит уже созданные фрагменты на новые. И многое другое…
                              Сейчас проблема с документацией/статьями, что в ближайшее время постараемся исправить.
                            +2
                            Чем это удобнее HTML?
                              0
                              Все преимущества и удобства есть в моем ответе выше.
                              Недостатком можно назвать то что для правки существующего шаблона, кодеру нужно будет провести пятиминутный ликбез. Так-же для конвертации html -> JSBuilder для больших шаблонов, у нас на проекте был написан небольшой скрипт в 50 строк.
                              0
                              Да, у вас интересный подход к построению ДОМ. Но вы лишаетесь такой замечательной вещи, как разметка — хотя это дело вкуса конечно. Мне, например, она очень помогает, как понять так и построить структуру приложения/компоненты. А пост/препроцессоры всего лишь паттерны такие — но тут действительно можно, что то интересное развить из этого.
                                0
                                Подход интересный, и в принципе себя уже неоднократно оправдал, на довольно крупных сервисах. Но, как я уже говорил выше, он уступает полноценным JS шаблонизаторам.
                                А под разметкой вы подразумеваете HTML код?
                                  +1
                                  Да, но это может быть не только html, a любой макет(разметка) — xml, xaml, mask. В первом комментарии Gorthauer87 упомянул qml, но признаюсь, хоть qt очень мощный фрэймворк сделали, ихняя разметка это нечто — css в перемешку с кодом(функции, события), но это субъективно.

                                  Вернувшись к маск разметки, так она удобная тем, что с помощью произвольных тегов, мы скрываем некоторую реализацию, вместо
                                  <div class='overlay'><div class='container'><div class='dialog'>hello</div></div></div>
                                  

                                  можем иметь
                                  dialog > 'hello'
                                  

                                  Таким образом реализацию диалогового окна мы скрыли за компонент, таким образом макет у нас становится более прозрачным.
                              –1
                              Великолепно.
                                0
                                >> Более подробно о самой библиотеке и примеры можете посмотреть здесь — libjs/Mask
                                В IE (даже в 9м) сайт по указанной ссылке не отображается (разве что только фон).
                                Судя по коду он тоже написан на MaskJS? Почему так?
                                  0
                                  Да, maskjs там тоже используется, как и много других вещей. В ие9 починил. Было пару причин почему не работало — но к шаблонизатору это не относилось — мои недочеты. Признаюсь конечно, что сайт в ие9 выглядит очень уж коряво, но это проблемы верстки и прочего.
                                • UFO just landed and posted this here
                                    0
                                    Мне кажется данное решение создает больше проблем, чем решает.

                                    Даже если мы получаем прирост производительности при вставке в DOM, это ведь не критичное местов в js. Ведь основная проблема производительности, в коде, который выполняется с частым интервалом (анимации, события).

                                    А используя такую штуку мы получаем букет проблем:
                                    + сео
                                    + незнакомому разработчику трудно понять код
                                    + нельзя ускорить процесс написания кода (autocomplete, zen coding)
                                    + многие виджеты не могут работать правильно с блоками, пока они не вставлены в dom и не имеют width/height/display

                                    Собственно сразу же вопрос, если мы получаем больше проблем, чем выгоды, как вам удается использовать данное решение в своих проектах и при этом не матерится? Не лучше ли использовать шаблонизатор типа handlebars.js, либо более производительное решение:
                                    function renderWidget(params) {
                                      return '<div class="test">'+ params.content +'</div>'
                                    }
                                    


                                      0
                                      Интересный и очень критичный комментарий. На самом деле как раз работа с ДОМ очень дорогая. Анимация — так это сейчас через transitions и animations делается — а это отдельный поток + gpu. События сами по себе ничего не нагружают — важно, что вы в этих событиях делаете, и работа с ДОМом здесь не на последнем месте. По поводу вашых плюсов (вернее минусов :) )
                                      • сео — не интересует, во первых много делаем приложений даже не под браузеры, а это мобильные и десктопные приложения, а то что для веба — в основном корпоративные инструменты. И даже то что для паблика, то это решается — делаю не я, но никто не «ругал».
                                      • незнакомый разработчик — подобных проблем не было, всем все понятно, а если не понятно, то нужен ли такой сторонний разработчик? Здесь все достаточно просто.
                                      • Ускорить процесс. Это какраз кардинально ускоряет процесс разработки. (Нативный zen coding :), a из за произвольных тэгов, этой разметки становится ещё меньше)
                                      • Виджеты. Правильно — поэтому есть событие DOMInsert — слушаем, инициализируемся

                                      И хочу вас огорчить ни handlebars, ни тем более ваше решение не достаточно производительны.
                                        0
                                        Я сделал сравнение вставки обычного string шаблона и вашего

                                        Правильно ли я сделал тест?
                                          0
                                            0
                                            Тест сделали не правильно — это в основном «Dom-Based Template Engine» — поэтому используйте renderDom. А renderHtml там только для тестов и прочего. Вот ссылка — jsperf — в Хроме маск быстрее, в других возможно нет. НО, в данном тесте вы сравнивается полноценный дом рендерер/шаблонизатор и маленькую функцию, от которой собственно в проекте смысла не много. А если найдете или напишете более быстрый шаблонный движок — будет здорово, и я буду рад почитать об этом здесь.
                                              0
                                              Я обновил url выше, теперь renderHTML работает через documentFragment (конвертацию я быстро нашел на stackoverflow и не уверен что это самый производительный вариант).

                                              Даже в такой реализации производительность выше. В этот раз хоть правильно тест сделал?)
                                                0
                                                Handlebars comparison — а теперь сравните на фоне вами рекомендованного handlebars.js. Повторюсь, что конечно, маленькая функция с одной конкатацией стрингов будет быстрее шаблонного движка. И если такой маленькой функции вам хватает для проектов, ну тогда я рад за вас.
                                                  0
                                                  Я согласен, что по сравнению с другими шаблонизаторами, производительность вашего отличная, но такой синтаксис меня очень смущает, в нем легко сделать ошибку и трудно ее найти. Даже в вашем тесте jsperf.com/maskjs-vs-json есть ошибка, mask.renderDom возвращает лишь часть dom объекта.

                                                  Ведь шаблоны в первую очередь делаются для уппрощения их редактирования, а если очень важная производительность можно использовать js без шаблонов. Или как вариант, попробовать Dart.
                                                    0
                                                    Вы наверное ссылкой ошиблись, так как .renderDom там совсем не используется, а .compile, и на первый взгляд без ошибок там. А в синтаксисе, конечно же можно допустить ошибку, но не менее легче чем в обычном html, или javascript-e. В редакторе выбрав подсветку как в javascript, сразу видно литералы/блоки. И должен признать, что парсер преднамеренно сделан без кучи проверок на валидность синтаксиса, хотя сделать это не сложно. Но мне это не надо — абстракции компонент и синтаксис позволяют держать шаблоны маленькими и наглядными, где ошибку пропустить уже довольно сложно становится.

                                                    В первую очередь шаблоны нужны, что бы «оживить» html связав его с данными. А в данном случае, я предлагаю дополнительно компонентно-ориентированный макет.

                                                    > js без шаблонов — что бы построить более менее сложное приложение(а не просто страницу), одной функцией(продемонстрированной вами выше) не обойтись — в результате получаем далеко не более быстрое решение.
                                                    > Неужели Dart будет быстрее, можете провести тест?
                                        +1
                                        О, добрый день. Я наткнулся на ваш шаблонизатор 3 недели назад.

                                        Я не буду писать, чем ваш шаблонизатор хуже или лучше других. Их много и у всех свои свойства. Сейчас вообще становиться модно в каждой крупной компании иметь свой собственный.

                                        То, что ваш шаблонизатор шустрый отрицать не буду, но когда я увидел у вас «is even faster than native JSON.parse», у меня закрались большие сомнения в вашей правоте.

                                        И как оказалось, просто ваш тест не является чесным, так как JSON представление шаблона, использованное вами для сравнения, содержит 40% «лишнего».

                                        И чтобы не быть голословным, я написал новый тест, где JSON шаблон предствален более рацилонально. И, как и ожидалось, ваш mark в нем проигрывает JSON.parse — jsperf.com/maskjs-vs-json/2

                                        Более того мы можем отказаться от валидации JSON, используемой в JSON.parse для обеспечения безопасности, и использовать eval. Тогда мы получим ровно два раза большую скорость парсинга.

                                        Так что ваш тест сыграл с вами вами злую шутку.
                                        И да, фразу «is even faster than native JSON.parse» наверное лучше убрать :)
                                          0
                                          О, так это вы создали 2-ой тест — очень грамотный подход, особенно array nested tree object. А вот тест как раз ваш не честный, так как на выходе мы получаем разные json. Я же взял тот json, который на выходе по данному шаблону выдает mask.compile, и сравнил с парсингом оного через JSON.parse — кажется довольно честно. Согласен, что от «40%» лишнего надо бы избавится, правда потом мы будем размножать проверки на подобии node.attr != null?. В любом случае, этот тест просто показывает, что компиляция происходит довольно быстро, и много мы не выиграем, если будем компилировать шаблоны перед дэплоем. А это, по крайней мере, мне очень важно — иметь чистые шаблоны в релизе.
                                            0
                                            Моя конфигурация JSON, это то что я по быстрому получил заменив ваш JSON при помощи нескольких RE в текстовом редакторе. Не более того. Касательно структруры я не задумывался — поэтому прошу без претензий.

                                            Моя цель была — уменьшить длину строки. В какие структуры там внутри это превращается это дело второе.
                                              0
                                              Хм, мне кажется вы сочли, что мой ответ с сарказмом — вовсе нет. Действительно — array nested tree в javascript хороший паттерн.
                                              А вот то, в какую структуру это все превращается довольно важно — ведь с ней потом работать «дом-билдеру» и компонентам, поэтому уменьшать строки, тем самым изменяя структуру на выходе, не вариант.
                                                0
                                                Есть подозрение, что в силу меньшей вложенности и замены обращения к полям хэша, на обращения к полям массива, ваш «дом-билдер» переписанный под предложенную мной структуру справлялся бы быстрее.
                                                  0
                                                  Да, я об этом подумал как только увидел. Обязательно попробую с этим вариантом, тут просто больше будет семантических проблем с произвольными компонентами. Ведь намного удобнее работать, когда создав обработчик компоненты, вы получите атрибуты в .attr, a детей в .nodes — чем [1], [2]. Но над этом я ещё подумаю. Спасибо вам.
                                            0
                                            И по-поводу eval — в данном тесте мы «эвалим» один и тот же шаблон — это то же не честно, так как v8 и wjs кэшируют результат — webkit (fixed)
                                              0
                                              да, к сожалению jsperf с этим ничего сделать не может
                                            0
                                            Jade синтаксис в случае с шаблонизатором на мой взгляд удобнее и немногословнее всего. Думаю что отказ от html разметки лежит в этом направлении.

                                            Only users with full accounts can post comments. Log in, please.