Предварительный просмотр следующей большой разработки платформы

Серия выпусков Meteor 1.4.x была сосредоточена на улучшении взаимодействия разработчиков с большими приложениями Meteor и упрощении отправки дополнительных улучшений в основные пакеты. Это привело к значительному сокращению времени восстановления, обновленным версиям зависимостей, таких как Node, и улучшенному разделению основных компонентов. Мы также проделали огромную работу, чтобы облегчить участие в проекте Meteor, чем когда-либо прежде, с целым набором руководств и процессов для заинтересованных разработчиков, позволяющих сообщать об ошибках, исправлениях и функциях в проект. Мы видели, как эти разработки нашли отражение в положительных отзывах команд, использующих Meteor в производственной среде, а также участников на GitHub.

Серия Meteor 1.5 будет посвящена следующему важному запросу, о котором мы слышим от разработчиков: производственной производительности, особенно в отношении загрузки приложений и времени запуска. Люди ожидают, что Интернет будет быстрым, и сейчас существует множество способов заставить даже сложные веб-приложения загружаться почти мгновенно. Первичный метод был назван разделением кода, и нечто подобное недавно было продвинуто через процесс стандартов ECMAScript в качестве функции, называемой динамический импорт.

Посмотреть демо

Чтобы понять, на что похоже использование динамического импорта в текущей бета-версии Meteor, посмотрите демонстрационное видео Бена Ньюмана, представленное на недавней Meteor Night:

Динамический импорт - это оператор импорта, который возвращает обещание вместо синхронного возврата модуля:

// Static import
import MyComponent from './component';
render(MyComponent);
// Dynamic import
import('./component').then((MyComponent) => {
  render(MyComponent);
});

Это дает модульной системе возможность делать что-то, что требует времени, например, асинхронно загружать этот модуль с сервера. Используя динамический импорт в нужных местах, вы можете значительно уменьшить размер пакета и время запуска вашего приложения!

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

Вы можете попробовать эту функцию сегодня, запустив текущую бета-версию 1.5! Найдите новейшую бета-версию, посетив PR на GitHub.

Немного изменив способ импорта, можно получить два типа преимуществ:

  1. Размер пакета. Динамические модули совсем не обязательно загружать при запуске приложения, а это значит, что пользователям не нужно загружать столько байтов кода, чтобы увидеть начальную визуализацию страницы.
  2. Время выполнения. Даже без динамического импорта перемещение некоторых статических операторов импорта в глубину вашего приложения может ускорить начальное время запуска вашего приложения за счет выполнения меньшего количества кода. Например, вы можете поместить оператор импорта в обратный вызов маршрутизатора или различные условные операторы. Вы по-прежнему оплачиваете сетевые затраты на загрузку этих модулей, но ваше приложение инициализируется быстрее, чем раньше. Поскольку технически импорт ECMAScript 2015 поддерживается только на верхнем уровне или в модуле, это особенность Meteor, которая обычно достигается в других фреймворках путем непосредственного ввода require.

Что особенного в динамическом импорте Meteor?

В сообществе JavaScript было несколько реализаций разделения кода и динамического импорта, среди которых особо выделялись Webpack, System.js и Next.js. Все эти системы великолепны, и каждый сборщик модулей будет иметь определенный набор компромиссов. Вот преимущества подхода, принятого в Meteor:

Гибкость без настройки. Как и следовало ожидать от Meteor, вам нужно написать точно нулевую конфигурацию, чтобы начать использовать динамический импорт в Meteor 1.5. Просто напишите const React = await import('react') вместо import React from 'react' всякий раз, когда вы хотите, чтобы модуль загружался динамически, а не был включен в стартовый пакет. В то же время нет особой магии - вы можете точно контролировать, какие модули являются динамическими, без привязки к конкретному маршрутизатору или инфраструктуре пользовательского интерфейса. Он также хорошо работает с React, Angular 2 или Moment.js.

Точное разделение кода. Некоторые подходы к разделению кода, например, в Webpack, работают путем создания определенного набора «пакетов» кода - каждый из них представляет собой набор модулей, которые ваше приложение предполагает использовать вместе. Однако иногда эти пакеты будут иметь значительные перекрывающиеся части, что означает, что вам придется загружать одну и ту же страницу, компонент или библиотеку несколько раз во время нормальной работы приложения. Одно из предложений этих систем - поместить общие зависимости в пакет «поставщик», который используется совместно другим кодом. В системе Meteor нет определенных точек входа или скомпилированных пакетов - вместо этого сервер предоставляет клиенту именно тот набор пакетов, который ему нужен, и не более того. Мы называем это «точным разделением кода», и это означает, что вы загружаете каждый пакет ровно один раз.

Работает одновременно с существующим кодом Meteor. Ни одно решение Meteor не будет полным без обратной совместимости и миграции. Вы можете сразу же начать использовать динамический импорт в своем приложении, даже если остальная часть вашего кода написана с использованием «классических» переменных в области видимости пакета Meteor. Просто выберите особенно дорогой модуль или пакет npm, запросите его с динамическим import(...), и вперед в гонки! Вы даже можете разделить пакет посередине, чтобы люди могли отправлять пакеты Meteor и npm, которые не загружают весь код сразу.

Работает одинаково для клиента и сервера. Большинство систем связывания предназначены только для работы с кодом на стороне клиента, но многие приложения Meteor написаны таким образом, что модули часто используются совместно между клиентом и сервером. Если вы загрузите модуль с динамическим импортом в код вашего сервера, он будет работать нормально, поскольку на сервере этот динамический импорт будет компилироваться в простой Node.js require.

Совместимость со спецификациями и возможность отладки. Мы изо всех сил старались убедиться, что переносимые модули в Meteor соответствуют спецификации и имеют важные функции, такие как живые привязки. Еще одна замечательная вещь - это то, что транспилированный код легко отлаживать на клиенте. Никаких странных имен переменных, таких как _require_0, только имя модуля, которое вы ожидали.

Как это работает

Так что же делает Meteor по-другому, чтобы включить некоторые из этих функций? Итак, вот краткое изложение:

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

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

Пример использования

Итак, что вы должны импортировать динамически? Где вам в первую очередь следует воспользоваться этой удивительной силой, позволяющей загружать новый код по своему желанию?

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

  1. Редко используемые маршруты, например админка. Возможно, вы даже захотите динамически загрузить все свои маршруты.
  2. Дорогие компоненты пользовательского интерфейса, такие как средство просмотра PDF, встроенная карта или комплексная визуализация данных.
  3. Большие библиотеки, такие как moment.js, которые используются только для мелких деталей на странице.
  4. Языковые пакеты для интернационализации следует загружать только после того, как пользователь выберет этот язык.

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

Присоединиться к разговору!

Независимо от того, являетесь ли вы текущим разработчиком Meteor, стремящимся сделать свое приложение более производительным, или гуру JavaScript, ищущим более простой способ получить лучшие функции современного JavaScript, вы захотите принять участие в обсуждении Meteor 1.5 и динамического импорта. .

Примите участие и поделитесь своим мнением о PR GitHub для версии 1.5. Давайте вместе создадим что-нибудь великое!