[JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 13:04
Оценка:
Всем привет!

У меня возник один, на первый взгляд, странный вопрос.

Я пишу макрос (метапрограмму) который по коду на статически типизированном языке (Nemerle) генерирует клиентский JavaScript для Web-страниц. В том числе этот генератор должен формировать скрипты клиентских шаблонов. Шаблон — это генератор HTML. К шаблону можно будет производить декларативную привязку ViewModel (используется шаблон проектирования MVVM).

Так вот в коде Nemerle шаблон представлен в виде AST который формирует XML в формате XLinq (XElement(...)). Другими словами имеется уже разобранный HTML, а не просто текст.

Вопрос заключается в том можно ли генерировать JavaScript который будет работать не с текстом, а напрямую с DOM-ом HTML-я? Не приведет ли это к тормозам или очень большому объему скриптов (ведь их придется слать на клиента)?

Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [JavaScript] Формирование DOM-а в броузере
От: Temoto  
Дата: 01.03.11 13:19
Оценка: +1
VD>Всем привет!

VD>У меня возник один, на первый взгляд, странный вопрос.


VD>Я пишу макрос (метапрограмму) который по коду на статически типизированном языке (Nemerle) генерирует клиентский JavaScript для Web-страниц. В том числе этот генератор должен формировать скрипты клиентских шаблонов. Шаблон — это генератор HTML. К шаблону можно будет производить декларативную привязку ViewModel (используется шаблон проектирования MVVM).


VD>Так вот в коде Nemerle шаблон представлен в виде AST который формирует XML в формате XLinq (XElement(...)). Другими словами имеется уже разобранный HTML, а не просто текст.


VD>Вопрос заключается в том можно ли генерировать JavaScript который будет работать не с текстом, а напрямую с DOM-ом HTML-я? Не приведет ли это к тормозам или очень большому объему скриптов (ведь их придется слать на клиента)?


VD>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


Манипуляции с DOM медленные, особенно удаление поддеревьев. Создавать лучше всего так:

e = document.createElement('div');
e.innerHTML = "что отрендерил шаблон";

Ну или e = $("что отрендерил шаблон")[0], если очень хочется впихнуть jQuery.

Работает везде, но в IE, конечно, с оговорками: http://www.ericvasilik.com/2006/07/code-karma.html
Re: [JavaScript] Формирование DOM-а в броузере
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.03.11 13:30
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


Насколько я понимаю, рекомендуемое авторами jQuery — jQuery.tmpl
Re[2]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 13:54
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Манипуляции с DOM медленные, особенно удаление поддеревьев.


Шаблон должен только рендерить некую часть ХТМЛ-я и заменять ее то что было до этого.

Вот примеры того что требуется реализовать:
http://knockoutjs.com/examples/templating.html
http://knockoutjs.com/examples/cartEditor.html

T>Создавать лучше всего так:


T>e = document.createElement('div');

T>e.innerHTML = "что отрендерил шаблон";

То есть тупо формировать код который сначала создаст строку, а потом скормит ее броузеру?

А со строками жабаскрипт шустро работает?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: Temoto  
Дата: 01.03.11 14:44
Оценка: 47 (1)
T>>Манипуляции с DOM медленные, особенно удаление поддеревьев.

VD>Шаблон должен только рендерить некую часть ХТМЛ-я и заменять ее то что было до этого.


VD>Вот примеры того что требуется реализовать:

VD>http://knockoutjs.com/examples/templating.html
VD>http://knockoutjs.com/examples/cartEditor.html

T>>Создавать лучше всего так:


T>>e = document.createElement('div');

T>>e.innerHTML = "что отрендерил шаблон";

VD>То есть тупо формировать код который сначала создаст строку, а потом скормит ее броузеру?


Да. Жаваскриптер Алексей подсказывает, что только V8 и какая-то опера делают createElement незначительно быстрее, чем innerHTML. Поэтому innerHTML выбирается как "неплохое на современных браузерах и лучшее на старых".

Вот ещё ссылка по теме: http://gaperton.livejournal.com/55094.html

VD>А со строками жабаскрипт шустро работает?


Ну, как обычно, + медленнее, чем join.
Re[2]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 15:51
Оценка:
Здравствуйте, Курилка, Вы писали:

VD>>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


К>Насколько я понимаю, рекомендуемое авторами jQuery — jQuery.tmpl


Его же использует и кнокаут. Вопрос, насколько он шустрый. По моим ощущениям — не очень.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 17:10
Оценка:
Здравствуйте, Temoto, Вы писали:

T>Ну, как обычно, + медленнее, чем join.


А полноценного StringBuilder/StringBufer я так понимаю не?

А массивы в ЖС шустро работают? Можно промежуточные результаты в них складывать, а потом join использовать?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: anonymous Россия http://denis.ibaev.name/
Дата: 01.03.11 17:12
Оценка:
Здравствуйте, VladD2, Вы писали:

T>>e = document.createElement('div');

T>>e.innerHTML = "что отрендерил шаблон";
VD>То есть тупо формировать код который сначала создаст строку, а потом скормит ее броузеру?

Если вы завяжетесь на innerHTML, то на вашем фреймворке никогда не удастся создать XML-документ (XHTML и прочее).
Re: [JavaScript] Формирование DOM-а в броузере
От: anonymous Россия http://denis.ibaev.name/
Дата: 01.03.11 17:27
Оценка: 47 (1)
Здравствуйте, VladD2, Вы писали:

VD>Вопрос заключается в том можно ли генерировать JavaScript который будет работать не с текстом, а напрямую с DOM-ом HTML-я? Не приведет ли это к тормозам или очень большому объему скриптов (ведь их придется слать на клиента)?


Не сложно написать код переводящий некую структуру, описывающую разобранный HTML, в текст для последующей вставки через innerHTML или в фрагмент документа, для вставки методами DOM. Поэтому достаточно будет предавать эту структуру и код работающей с ней. Кроме того, все эти текстовые данные достаточно хорошо сжимаются при передаче.

VD>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


Разработчики могут склоняться к иным библиотекам. Возможно, лучшим решением будет написание абстракции, позволяющей подключить желаемую библиотеку.
Re[5]: [JavaScript] Формирование DOM-а в броузере
От: Temoto  
Дата: 01.03.11 17:51
Оценка:
T>>Ну, как обычно, + медленнее, чем join.

VD>А полноценного StringBuilder/StringBufer я так понимаю не?


VD>А массивы в ЖС шустро работают? Можно промежуточные результаты в них складывать, а потом join использовать?


Все только так и делают.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: Курилка Россия http://kirya.narod.ru/
Дата: 01.03.11 18:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Курилка, Вы писали:


VD>>>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


К>>Насколько я понимаю, рекомендуемое авторами jQuery — jQuery.tmpl


VD>Его же использует и кнокаут. Вопрос, насколько он шустрый. По моим ощущениям — не очень.


Про скорость вспоминается только этот пост годишней давности
Re[5]: [JavaScript] Формирование DOM-а в броузере
От: anonymous Россия http://denis.ibaev.name/
Дата: 01.03.11 18:52
Оценка:
Здравствуйте, VladD2, Вы писали:

T>>Ну, как обычно, + медленнее, чем join.

VD>А полноценного StringBuilder/StringBufer я так понимаю не?
VD>А массивы в ЖС шустро работают? Можно промежуточные результаты в них складывать, а потом join использовать?

Такие вопросы не вполне корректны, скорость тех или иных вещей очень сильно зависит от конкретного браузера и даже от его версии. К примеру, вот этот конкретный вопрос. IE когда-то очень медленно складывал строки (не знаю как сейчас), поэтому для него оптимальным решением было сложить строки в массив и вызвать join. Однако другие браузеры складывают строки быстро, и накладные расходы на формирование массива могут делать в них способ с join невыгодным. Однако в среднем, поскольку в IE выигрыш получается существенным, лучше использовать join.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: c-smile Канада http://terrainformatica.com
Дата: 01.03.11 19:26
Оценка: 47 (1)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Курилка, Вы писали:


VD>>>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


К>>Насколько я понимаю, рекомендуемое авторами jQuery — jQuery.tmpl


VD>Его же использует и кнокаут. Вопрос, насколько он шустрый. По моим ощущениям — не очень.


Я сравнивал следующие движки:


jQuery.tmpl() и JavaScript Micro-Templating должны быть самыми быстрыми — templates компилируются в JS bytecode и исполняются.
Re[4]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 19:33
Оценка:
Здравствуйте, anonymous, Вы писали:

A>Если вы завяжетесь на innerHTML, то на вашем фреймворке никогда не удастся создать XML-документ (XHTML и прочее).


Это по чему это? И что "прочее"?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 19:37
Оценка:
Здравствуйте, anonymous, Вы писали:

A>Такие вопросы не вполне корректны, скорость тех или иных вещей очень сильно зависит от конкретного браузера и даже от его версии. К примеру, вот этот конкретный вопрос. IE когда-то очень медленно складывал строки (не знаю как сейчас), поэтому для него оптимальным решением было сложить строки в массив и вызвать join. Однако другие браузеры складывают строки быстро, и накладные расходы на формирование массива могут делать в них способ с join невыгодным. Однако в среднем, поскольку в IE выигрыш получается существенным, лучше использовать join.


Вопрос как раз совершенно корректный и очевидный. Конечно же рассчитывать надо самый медленный из реально используемых робузеров. Так что если скажем IE 6 тормозит, то "+" лучше не использовать.

Ну, а массив + join хорош еще и тем, что в отличии от + — это динамическое решение. Скорость упрется только в скорость изменения размеров массива. "+" же будет по любому перезанимать память при каждом присвоении переменной.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.03.11 20:00
Оценка:
Здравствуйте, anonymous, Вы писали:

A>Не сложно написать код переводящий некую структуру, описывающую разобранный HTML, в текст для последующей вставки через innerHTML или в фрагмент документа, для вставки методами DOM. Поэтому достаточно будет предавать эту структуру и код работающей с ней. Кроме того, все эти текстовые данные достаточно хорошо сжимаются при передаче.


Интересная мысль. Надо подумать над этим.

VD>>Если вопрос производительности не критичен, то второй вопрос. Какими методами лучше всего формировать DOM? Пока что я склоняюсь к использованию JQuery.


A>Разработчики могут склоняться к иным библиотекам. Возможно, лучшим решением будет написание абстракции, позволяющей подключить желаемую библиотеку.


Основная задача вообще снять с разработчика необходимость писать ЖабаСкрипты.
Здесь можно увидеть примеры альфа-версии (прототипа) библиотеки.
Вот один из примеров:
  [Record, ViewModel]
  public class BetterListViewModel
  {
    public ItemToAdd     : string { get; set; }
    public AllItems      : VMArray[string] { get; set; }
    public SelectedItems : VMArray[string] { get; set; }

    public AddItem() : void
    {
      when (ItemToAdd != "" && AllItems.IndexOf(ItemToAdd) < 0) // Prevent blanks and duplicates
        AllItems.Add(ItemToAdd);
        
      ItemToAdd = ""; // Clear the text box
    }

    public RemoveSelected() : void
    {
      AllItems.RemoveAll(SelectedItems);
      SelectedItems = VMArray.Empty; // Clear selection
    }
  }

  public partial module Views
  {
    [View]
    public BetterListView(viewModel : BetterListViewModel) : XElement
    {
      _ = viewModel;
      xml <# 
        <div class="note" xmlns="">
          <form data-bind="submit:AddItem">
              Add item: <input type="text" data-bind='value:ItemToAdd, valueUpdate: "afterkeydown"' />
              <button type="submit" data-bind="enable: ItemToAdd().length > 0">Add</button>
          </form>
           
          <p>Your values:</p>
          <select multiple="multiple" height="5" data-bind="options:AllItems, selectedOptions:SelectedItems"> </select>
           
          <div>
              <button data-bind="click: RemoveSelected, enable: SelectedItems().length > 0">Remove</button>
              <button data-bind="click: function() { AllItems.sort() }, enable: AllItems().length > 1">Sort</button>
          </div>
        </div>
      #>
    }
  }

По модели представления (BetterListViewModel в данном случае) генерируется объект ЖабаСкрипта который автоматически оповещает всех подписчиков.

Представление генерируется на сервере, но использует клиентский биндинг. Для элементов вроде button, input и select на клиенте ничего генерировать не надо.

Шаблоны же нужны для более сложных случаев. Они так же будут описываться на статически типизированном языке. Их можно будет отрендерить на сервере (и получить ХТМЛ), или на клинте (с использованием скрипта сформированного по описанию представления в статически типизированном языке). При этом к этим шаблонам должен быть доступен биндинг. Шаблоны должны перереднедиться при изменении модели представления.

Таким образом программист не будет непосредственно работать с ЖабаСикрипотом. Он будет описывать код в статически-типизированном виде (с интеллигентом и проверками строго компилятора) и получать все скрипты в готовом виде. Так что что за сктипт генерируется и какие базовые ЖабаСкрипт-библиотеки используются зависит только от нас (меня в данном случае).

Собственно можно даже обойтись без библиотек. Но боюсь придется убить много времени на обход несовместимостей разных броузеров. По сему и думаю как упростить свою задачу.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [JavaScript] Формирование DOM-а в броузере
От: anonymous Россия http://denis.ibaev.name/
Дата: 01.03.11 20:17
Оценка:
Здравствуйте, VladD2, Вы писали:

A>>Если вы завяжетесь на innerHTML, то на вашем фреймворке никогда не удастся создать XML-документ (XHTML и прочее).

VD>Это по чему это? И что "прочее"?

Про XHTML я ошибся, там теперь innerHTML работает, по крайней мере в Gecko. Хотя раньше не работал, потому что вставлять текст в валидный XML-документ не считалось хорошей идеей. А прочее это, к примеру, XUL. Мало ли какой язык разметки решит использовать разработчик, DOM даёт тут единый подход.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: dotneter  
Дата: 02.03.11 08:04
Оценка:
Здравствуйте, VladD2, Вы писали:

А где можно посмотреть на исходники компилятора nemerle в js?

VD>Собственно можно даже обойтись без библиотек. Но боюсь придется убить много времени на обход несовместимостей разных броузеров. По сему и думаю как упростить свою задачу.

Имхо, в голом javascript смысла нет, идеалогически было бы конечно правильно сделать обертку, но вроде никто так не делает, тот же asp.net mvc завязан на jquery, думаю jQuery.noConflict() оптимальный вариант.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[3]: [JavaScript] Формирование DOM-а в броузере
От: Gaperton http://gaperton.livejournal.com
Дата: 10.03.11 07:27
Оценка:
Здравствуйте, VladD2, Вы писали:

Замените уж тогда HTML на что-нибудь читабельное. Вроде HAML.
Re[4]: [JavaScript] Формирование DOM-а в броузере
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.03.11 12:42
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Замените уж тогда HTML на что-нибудь читабельное. Вроде HAML.


DSL, конечно, можно прикрутить любой, но что-то я не вижу в HAML-е особой читаемости.
Сейчас это дело выглядит как HTML/XML с активными областями (как квази-цитата):
http://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/Nemerle.Xml
using Nemerle.Collections;
using Nemerle.Xml;

using System;
using System.Console;
using System.Xml.Linq;

[assembly: DefineXmlns(ns1="some-ns")]

class TestClass
{
  public Prop1 : int { get; set; }
  public Prop2 : string { get; set; }
}

module Program
{
  Main() : void
  {
    def makeClassInfoPage(cls : Type) : void
    {
      def props  = cls.GetProperties();
      def events = cls.GetEvents();
      def title  = $"Класс <$(cls.Name)>";

      def html = xml <# 
        <html>
          <head>
            <title>$title</title>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
            <link rel="stylesheet" href="http://rsdn.ru/css/article.css" type="text/css" />
          </head>
          <body marginwidth="20" marginheight="20">
            <H1>$title</H1>
            
            <H2 $unless (props.IsEmpty())>Свойства</H2>
            <ol $unless (props.IsEmpty())>
              <li $foreach (p in props)>$(p.Name) : $(p.PropertyType)</li>
            </ol>
            
            <H2 $unless (events.IsEmpty())>События</H2>
            <ol $unless (events.IsEmpty())>
              <li $foreach (e in events)>$(e.Name) : $(e.EventHandlerType)</li>
            </ol>
          </body>
        </html>
   #>;
   
      def path = IO.Path.ChangeExtension(IO.Path.GetTempFileName(), "html");
      IO.File.WriteAllText(path, html.ToString());
      _ = Diagnostics.Process.Start(path);
    }
    
    makeClassInfoPage(typeof(XAttribute));
    makeClassInfoPage(typeof(TestClass));
  }
}
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.