Xpoint
   [напомнить пароль]

Ускорить создание динамического меню

2005-05-06 17:37:42 [обр] alc [досье]
Здравствуйте. Пишу расширение для firefox. При инициализации расширения происходит заполнение выпадающего меню. Причем размер немаленький - около 700 элементов. В результате - задержка в этой части около 0.2 с(Athlon 1300, WinXP). А лишних тормозов при запуске программы иметь не хочется. Можно ли соптимизировать это дело? Например, как-нибудь загрузить сразу все элементы из переменной, содержащей XUL код?
  var menu = document.getElementById("ListMenu");
  for(var i=menu.childNodes.length - 1; i>=0; i--)  {
     menu.removeChild(menu.childNodes.item(i));
  }
  for(var i=0;i<MyArray.length; i++)  {
     var tempItem = null;
     tempItem = document.createElement("menuitem");
     tempItem.setAttribute("label", MyArray[i][0]);
     tempItem.setAttribute("tooltiptext",  " MyArray[i][1]);
     tempItem.setAttribute("value",  MyArray[i][2]);
        tempItem.setAttribute("oncommand", "alert(‘test’)");
       menu.appendChild(tempItem);
  }
спустя 18 минут [обр] Алексей Севрюков [досье]
alc[досье] Хм, а 1/5 секунды это разве много?
спустя 4 минуты [обр] Владимир Палант [досье]
  1. Лучше не добавлять элементы в меню, находящееся в документе. Либо создать новое меню, либо удалить его временно из документа (то же самое с удалением старых элементов, конечно). Тогда Gecko не будет создавать события при вставке элементов, это должно сэкономить немало времени.
  2. Вставить все элементы за раз можно, но неизвестно, будет ли это быстрее. Что-то в этом роде:
var code='<menulist id="ListMenu" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' +
 '<menuitem/>' +
 '...' +
 '</menulist>';
var fragment = new DOMParser().parseFromString(code, 'text/xml');

var menuParent = document.getElementById('???');
menuParent.removeChild(menuParent.firstChild);
menuParent.appendChild(fragment.documentElement);
спустя 21 час [обр] alc [досье]

Спасибо. Работает ровно в 2 раза быстрее. Но почему-то меню (в тубаре) получается страшненьким. Не отображается, ни label выбранного элемента, ни кнопка разворачивания списка.
XUL:

<toolbaritem  id="List-Item" >
<menulist id="TB-List”  xmlns=http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="140">
  <menupopup id="TB-ListMenu">
    <menuitem label="test" tooltiptext="test" value="test"/>
  </menupopup>
</menulist>
</toolbaritem>

В качестве родительского использовал List-Item

спустя 55 минут [обр] Владимир Палант [досье]

Странно. Пишу (кавычки поправил):

var code = '<menulist id="TB-List" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" width="140">' +
          '<menupopup id="TB-ListMenu">' +
          '<menuitem label="test" tooltiptext="test" value="test"/>' +
          '</menupopup>' +
          '</menulist>';
var fragment = new DOMParser().parseFromString(code, 'text/xml');

var menuParent = document.getElementById('List-Item');
if (menuParent.firstChild)
  menuParent.removeChild(menuParent.firstChild);
menuParent.appendChild(fragment.documentElement);

Всё отображается нормально (см. иллюстрацию). Mozilla 1.7.7 и Firefox 1.0.

спустя 8 минут [обр] Владимир Палант [досье]
PS: Как вы составляете XUL-код, который нужно парсить? Если вы объединяете большое количество строк, то лучше не пользоваться оператором +=. Даниил Алиевский когда-то искал оптимальный способ для конкатенации строк в JavaScript. Если строк всего 700, то особо мучаться не стоит: создаётся массив, все строки засовываются в него с помощью array.push(str), а потом вызывается array.join(''), чтобы объединить все строки. Этот вариант значительно более эффективен, может и в вашем случае что-то даст.
спустя 5 часов [обр] sndralex [досье]
А лучше всего применить RDF.
спустя 7 минут [обр] Владимир Палант [досье]
Быстрее от этого ничего не станет, RDF — весьма тормозная штука, хоть и удобная.
спустя 4 дня [обр] alc [досье]

Оказывается меню отрисовывалось неправильно от того что я ставил пробелы до и после открытия/закрытия тегов

Неправильно:
...there.is.only.xul" width="140"> '
Правильно:
...there.is.only.xul" width="140">'

Кстати, да, спасибо за array.join(''). Теперь работает за 70 мс, т.е. почти в 3 раза быстрее.

Powered by POEM™ Engine Copyright © 2002-2005