Ответ 1
Если я, наконец, собираю все в один файл для развертывания, то все мое приложение загружается одним выстрелом, а не по требованию. Разве это не связывание, противоречащее AMD вообще и RequireJS в частности?
Это не противоречиво. Загрузка модулей по требованию является лишь одним из преимуществ RequireJS. В моей книге большая польза заключается в том, что модуляция помогает использовать подход "разделяй и властвуй". Мы можем посмотреть на это следующим образом: несмотря на то, что все функции и классы, которые мы помещаем в один файл, не пользуются загрузкой по требованию, мы по-прежнему пишем несколько функций и несколько классов, потому что это помогает разбивать проблему структурированным способом.
Однако множественность модулей, которые мы создаем в разработке, не обязательно имеет смысл при запуске приложения в браузере. Наибольшая стоимость загрузки по требованию отправляет несколько HTTP-запросов по проводу. Скажем, ваше приложение имеет 10 модулей, и вы отправляете 10 запросов для его загрузки, потому что вы загружаете эти модули по отдельности. Ваша общая стоимость будет той стоимостью, которую вы должны заплатить, чтобы загрузить байты из 10 файлов (позвоните по адресу Pc для стоимости полезной нагрузки), плюс накладные расходы для каждого HTTP-запроса (позвоните в Oc для накладных расходов). Накладные расходы связаны с данными и вычислениями, которые должны произойти, чтобы инициировать и закрывать эти запросы. Они не несущественны. Таким образом, вы платите Pc + 10 * Oc. Если вы отправляете все в один кусок, вы платите Pc + 1 * Oc. Вы сохранили 9 * Oc. На самом деле сбережения, вероятно, больше, потому что (поскольку сжатие часто используется на обоих концах для уменьшения размера передаваемых данных), сжатие будет давать большие преимущества, если все данные будут сжаты вместе, чем если бы они сжаты как 10 кусков. (Примечание: в приведенном выше анализе отсутствуют данные, которые не подходят для покрытия.)
Кто-то может возразить: "Но вы сравниваете загрузку всех модулей отдельно и загружаете все модули в один кусок. Если мы загружаем по требованию, мы не будем загружать все модули". По сути, в большинстве приложений есть ядро модулей, которые всегда будут загружаться, несмотря ни на что. Это модули, без которых приложение не будет работать вообще. Для некоторых небольших приложений это означает все модули, поэтому имеет смысл объединить все их вместе. Для больших приложений это означает, что основной набор модулей будет использоваться каждый раз, когда приложение запускается, но небольшой набор будет использоваться только по случаю. В последнем случае оптимизация должна создавать несколько пакетов. У меня есть приложение. Это редактор с режимами для различных задач редактирования. Хорошие 90% модулей относятся к ядру. Они будут загружены и использованы в любом случае, поэтому имеет смысл объединить их. Код для самих режимов не всегда будет использоваться, но все файлы для данного режима понадобятся, если режим загружен вообще, поэтому каждый режим должен быть его собственным пакетом. Таким образом, в этом случае модель с одним ядром и серией пучков режимов имеет смысл: а) оптимизировать развернутое приложение, но б) сохранить некоторые преимущества загрузки по требованию. Что красота RequireJS: она не требует, чтобы сделать то или другое исключительно.