Существует несколько подходов к созданию виджетов в dojo. Один из них — использовать флаг parseOnLoad для dojo, чтобы сообщить ему, что он должен проанализировать DOM после того, как сам dojo и все dojo.require завершили работу. Другой вариант — напрямую подключиться к обратному вызову функции dojo.addOnLoad и начать создавать собственные виджеты. В обоих этих случаях в производственной среде нам потребуется основной профиль всего нашего кода javascript.

Институционализация фаз Javascript

Однако, поскольку мы хотели разделить способ создания наших накопительных пакетов, dojo не обязательно предоставлял нам простой механизм, когда определенные определения JS еще не существуют. Сначала мы пытались перехватывать ошибки отсутствующих виджетов в parseOnLoad и просто повторно вызывать dojo.parse.parser() после получения требований, но хотя это в какой-то степени достигло того, что мы хотели, это было не совсем элегантное решение нашей проблемы. . Это маскировало другие ошибки, которые могли произойти при создании виджета.

Итак, мы углубились в синтаксический анализатор и начали извлекать его части, чтобы мы могли контролировать, когда и где мы хотим вызывать синтаксический анализатор.

Другой парсер типа Dojo

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

Порядок, в котором работает этот парсер, довольно прост. Во-первых, он начнет выполняться, как только dojo.addOnLoad вызовет наш обратный вызов. По сути, для нас это означает, что он извлек наш основной накопитель dojo.js и первый «этапный» накопительный пакет. Это позволяет нам начать загрузку страницы, отправляя запросы данных (см. наш пост о загрузчике данных позже!), а затем для оставшихся сверток javascript. Ключевым моментом здесь является то, что мы еще не оцениваем javascript, просто сохраняем его, пока не будем готовы. Может случиться так, что javascript уже кэширован, но мы все еще хотим отображать страницу в определенном порядке, чтобы пользователи сначала и как можно раньше видели верхнюю часть содержимого сгиба.

Итак, после того, как мы отправили наши сетевые запросы, мы можем начать первую фазу создания виджета. Большинство наших виджетов происходят от виджета, который знает, что мы загружаем наш javascript поэтапно. Этот виджет переопределяет фазу buildRendering. Мы отключаем проверку _Templated на наличие дочерних элементов и просто сообщаем нашему парсеру, что у только что созданного им виджета есть дочерние элементы, которые необходимо создать. Синтаксический анализатор делает это для каждого создаваемого виджета, собирая каждый новый тип dojoType в шаблонах виджетов. Когда он собирает эти типы, он сначала проверяет, может ли он их создать (существует ли класс), и, если нет, сохраняет их для повторного анализа при последующей загрузке фазы.

Как только синтаксический анализатор завершит свою первую фазу сканирования и создания виджета, он вызовет метод startup() для всех виджетов. Это в значительной степени соответствует традиционному определению жизненного цикла startup(). После того, как все виджеты будут проинформированы, синтаксический анализатор оценит следующую фазу javascript и переберет все сохраненные узлы off dom, для которых он еще не нашел класс dojo.

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

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

_delayedAdopt

Последняя маленькая деталь с этой настройкой — это программное создание. Нам пришлось немного поумничать, чтобы мы могли создать что-то после того, как все накопительные пакеты javascript будут загружены. Вдохновленные статьей Хиггина для _Adopt (то, что мы также используем для программного создания), мы создали вторую функцию, которая действует точно так же, как accept(), но использует строку для имени класса.

delayedAdopt: function(/* string */cls, /* object? */props, /* dom-узел */node, /* function */callback) {}

Обратный вызов автоматически привязывается к контексту, в котором он был создан, как и обычный метод accept(), но не будет выполняться до тех пор, пока требование для этого виджета не будет снято. Это позволяет нам сделать создание виджетов, которые не нужны в верхней части содержимого сгиба, на более позднем этапе.

Поэтапная загрузка

Со всем этим вместе это дает нам возможность разделить наш javascript на куски и задать порядок создания страницы. Он уменьшает первоначальный размер страницы, так что пользователь взаимодействует и видит что-то почти сразу. Большинство людей едят глазами и не любят страницы, которые, кажется, загружаются медленно. Надеемся, что это похоже на то, что страница загружается быстрее для пользователей.