Подтвердить что ты не робот

Есть ли способ создать из элементов DOM в Web Worker?

Контекст: У меня есть веб-приложение, которое обрабатывает и показывает огромные файлы журналов. Обычно их длина составляет всего около 100 тыс. Строк, но может составлять до 4 млн. Строк или более. Чтобы иметь возможность прокручивать этот файл журнала (как инициированный пользователем, так и через JavaScript) и фильтровать строки с достойной производительностью, я создаю элемент DOM для каждой строки, как только данные поступят (в JSON через ajax). Я нашел это лучше для производительности, а затем построил HTML в фоновом режиме. После этого я сохраняю элементы в массиве, и я показываю только видимые строки.

Для линий max 100k это занимает всего несколько секунд, но для линий 500k (не считая загрузки) требуется больше одной минуты. Я хотел улучшить производительность еще больше, поэтому я попытался использовать веб-работников HTML5. Проблема в том, что я не могу создавать элементы в веб-рабочем, даже вне DOM. Поэтому я закончил работу с json-конверсией в Web Workers и отправил результат в основной поток. Там он создается и сохраняется в массиве. К сожалению, это ухудшило производительность, и теперь это занимает не менее 30 секунд.

Вопрос:. Есть ли способ, который я не знаю, создавать элементы DOM, вне дерева DOM, в веб-рабочем? Если нет, почему бы и нет? Мне кажется, что это не может создать проблемы concurrency, так как создание элементов может происходить параллельно без проблем.

4b9b3361

Ответ 1

Хорошо, я сделал еще несколько исследований с информацией, предоставленной @Bergi, и нашел следующее обсуждение списка рассылки W3C:

http://w3-org.9356.n7.nabble.com/Limited-DOM-in-Web-Workers-td44284.html

И выдержка, в которой объясняется, почему нет доступа к парсеру XML или парсер DOM в веб-работнике:

Вы предполагаете, что ни один из кода реализации DOM не использует какой-либо вид не-DOM-объектов, когда-либо, или что если эти объекты полностью поточно. Это не так, по крайней мере, в Гекко.

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

Например, синтаксический анализатор XML должен делать некоторые вещи, которые в Gecko могут делать только на основной теме (загрузка DTD, небрежно, есть немногие другие, которые я видел раньше, но не помню, как это было раньше).

Однако существует также обходное решение, в котором используется сторонняя реализация парсеров, из которых jsdom является примером, При этом вы даже имеете доступ к своему отдельному документу.

Ответ 2

Итак, есть ли способ, который я не знаю, создавать элементы DOM, вне дерева DOM, в веб-рабочем?

Нет.

Почему бы и нет? Мне кажется, что это не может создать проблемы concurrency, так как создание элементов может происходить параллельно без проблем.

Не для их создания вы правы. Но для добавления их к главному document - их нужно будет отправить в другую память (например, это возможно для blobs), чтобы они были недоступны для рабочего после этого. Тем не менее, нет абсолютно никакой обработки документов, доступной в WebWorkers.

Я создаю элемент DOM для каждой строки, как только данные поступят (в JSON через ajax). После этого я сохраняю элементы в массиве, и я показываю только видимые строки.

Построение более 500 тыс. элементов DOM - тяжелая задача. Попробуйте создать элементы DOM только для видимых строк. Чтобы повысить производительность и показать первые несколько строк быстрее, вы также можете вырезать их обработку на меньшие единицы и использовать промежутки времени между ними. См. Как остановить интенсивный цикл Javascript от зависания браузера

Ответ 3

Нет прямого доступа к DOM через веб-работников. Недавно я выпустил @cycle/sandbox, он по-прежнему является WIP, но он доказывает, что с JS-архитектурой Cycle довольно просто объявить поведение пользовательского интерфейса в Web Worker. Фактический DOM касается только основного потока, но прослушиватели событий и обновления DOM опосредованно объявляются в рабочем документе, а объект синтезированных событий отправляется, когда что-то происходит с этими слушателями. Кроме того, прямое подключение этих изолированных компонентов циклического цикла к бок о бок с регулярными компонентами цикла.

http://github.com/aronallen/-cycle-sandbox/

Ответ 4

Вам нужно понять природу веб-мастера. Программирование в потоках затруднено, особенно если вы используете память; странные вещи могут случиться. JavaScript не оборудован для обработки любого типа потокового перемежения.

Подход веб-мастеров заключается в том, что нет общей памяти. Это, очевидно, приводит к выводу, что вы не можете получить доступ к DOM.

Ответ 5

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

Это не относится к веб-работникам, но относится к проблеме, которую вы пытаетесь решить. Вот что-то, что может помочь ускорить работу:

  • Используйте DocumentFragments. Добавьте к ним элементы по мере поступления данных и добавьте фрагменты в DOM с интервалом (например, один раз в секунду). Таким образом, вам не нужно прикасаться к DOM (и выполнять перерисовку) каждый раз, когда загружается строка текста.

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

Ответ 7

У вас есть пара анти-шаблонов в вашем дизайне:

  • Создание объекта DOM имеет значительные накладные расходы, и вы создавая потенциально миллионы из них сразу.
  • Попытка заставить веб-исполнителя управлять DOM - это именно то, что веб рабочих не для. Они делают все остальное, поэтому цикл событий DOM остается отзывчивым.

Вы можете использовать шаблон курсора для прокрутки наборов данных произвольно больших.

  • DOM отправляет сообщение работнику с начальной позицией и количеством запрошенных строк (курсор).
  • Случайный доступ к веб-рабочему рабочему столу, сообщения о возвращаемых линиях (данные курсора).
  • DOM обновляет элемент с ответом на событие асинхронного курсора.

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

Ответ 8

Таким образом, вы не можете напрямую создавать DOM в веб-обозревателе, но может быть другой вариант сделать справедливую бит вашей обработки вне основного потока.

Проверьте этот jsPerf, который я только что создал: http://jsperf.com/dom-construction-obj-vs-str

По сути, вы могли бы испускать POJSO, у которых есть все те же значения, которые вы получаете из DOM, и конвертировать их в объекты DOM после получения сообщения (это то, что вы делаете, когда получаете HTML обратно, в конце концов; POJSOs являются лишь более низкими издержками, поскольку не требуют дальнейшей обработки строк). Таким образом, вы можете делать такие вещи, как emit event listeners и т.д. (Например, префикс имени события с помощью "!" И наличие карты значений для некоторого аргумента представления шаблона).

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

Ответ 9

Нет, вы не можете создавать элементы DOM в веб-рабочем, но вы можете создать функцию, которая принимает сообщение сообщения от этого веб-рабочего, что does создает элементы DOM. Я думаю, что соизволить, что ваш поиск называется массивом. И вам нужно будет смешать это с шаблоном проектирования веб-рабочего.