2017-02-06 28 views
1

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

Вот реализация основного модуля:

;(function(doc, win, undefined) { 
    'use strict'; 

    define(['module', 'domReady!'], function(main) { 
     var modules = main.config().modules; 
     while (modules.length) { 
     require([].concat(modules.shift()), function(module) { 
      module.init(); 
     }); 
     } 
    }); 

}(document, window)); 

кажется, что, несмотря на то, что каждый модуль должен оказать право после его загрузки на экране, прежде чем все модули завершения загрузки ничего не появляется. Это вызывает задержку при входе в приложение и не указывает на то, что приложение запустило выполнение. Что может вызвать такое поведение и как сделать инициализацию приложения максимально гладкой?

ответ

1

Это не часть семантики AMD, чтобы обеспечить эффект, который вы ищете. Единственная гарантия, которую вы имеете, заключается в том, что обратный вызов, который вы передаете на require, не будет работать до тех пор, пока не будут загружены модули, перечисленные в массиве зависимостей, который идет с обратным вызовом и их зависимостями.

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

Как запросы, разрешенные на сервере, также влияют на то, что произойдет в каком порядке.

Тогда есть структура вашего приложения. Предположим, что main.config().modules содержит ['A', 'B', 'C']. Таким образом, вы хотите загрузить A, B, C и попросите их инициализировать как можно скорее. Однако оказывается, что все эти модули также зависят от jquery. Когда RequireJS выполняет A, он запускает define(['jquery], function ($) {.... Итак, теперь нужно выбрать jquery. К тому времени, когда был получен jquery, вероятность того, что B и C также будут ждать его. Поэтому RequireJS будет выполнять A, B, C и обратные вызовы, ожидающие их в близком порядке. С одной зависимостью это может не быть большим делом, но если ваши модули зависят от множества других распространенных модулей, это добавляет, и конечный результат заключается в том, что вы получаете заметное ожидание, пока загружаются общие модули, а затем он выглядит как A , B, C выполнить в партии.

Это возможно с помощью собственного оптимизатора RequireJS или другого оптимизатора, который понимает модули AMD, чтобы попытаться объединить ваши модули в пакеты, которые будут способствовать результату, который вы ищете. Для такого рода оптимизации требуется, чтобы разработчик тщательно проанализировал структуру приложения. В общем случае нет единого флага, опции или плагина, который вы можете просто включить, чтобы получить результат, который вам нужен. Более того, как упоминалось выше, браузер и сервер могут работать таким образом, чтобы это все испортило.


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

;(function(doc, win, undefined) { 
    'use strict'; 

    define(['module', 'domReady!'], function(main) { 
     var modules = main.config().modules; 
     function next() { 
     var name = modules.shift(); 
     if (name === undefined) { 
      return; 
     } 

     require([name], function (module) { 
      // When one module has loaded, we initiate the request for the 
      // next one. 
      next(); 

      // And init what we've got now. 
      module.init(); 
     }); 
     } 

     next(); 
    }); 
}(document, window)); 

Однако стоимость здесь является то, что B запрашивается только после того, как A загружен и т.д.Если в вашем исходном коде все модули запрашиваются сразу же с места в карьер. Это может привести к увеличению времени инициализации.

+0

Спасибо за очень глубокий ответ! Прежде чем использовать библиотеку RequireJS в своем приложении, время загрузки было действительно лучше, по крайней мере, с относительно быстрой скоростью загрузки. Самая большая причина, по которой я начал использовать RequireJS, заключалась в том, чтобы убедиться, что мое приложение поддерживается в будущем по мере его роста (особенно когда число зависимостей и модулей становится выше). Я думаю, что моя главная цель здесь - уменьшить отставание между выборкой основных зависимостей и началом инициализации модулей. По крайней мере, чтобы загрузить мой загрузочный модуль и быстро его инициализировать, и, следовательно, улучшить работу с пользователем. –

 Смежные вопросы

  • Нет связанных вопросов^_^