Когда мы начали разрабатывать новые приложения в Emarsys на ранних стадиях Angular (2 бета), первое, что мы заметили, - это рост размера и замедление скорости приложения. Размер унифицированного исходного кода быстро превысил 3 Мбайт, и потребовалось несколько секунд, чтобы просто начать реагировать.

Компиляция точно в срок (JIT)

Основная причина этого заключалась в том, что мы использовали JIT-компиляцию. Это снижает производительность, анализируя шаблоны компонентов каждый раз, когда пользователь открывает веб-страницу. Для синтаксического анализа также нужен компилятор, встроенный в приложение. Это часть, которая преобразует HTML-шаблоны в исполняемый код. Компилятор может занимать половину размера связанного кода, а это огромная часть.

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

Компиляция с опережением времени (AOT)

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

Таким образом, компиляция происходит только один раз во время сборки, и нам больше не нужно отправлять компилятор Angular и шаблоны HTML в пакет. Сгенерированный исходный код можно запустить сразу после загрузки в браузер, никаких предыдущих шагов не требуется.

Компиляция AOT превращает этот HTML-шаблон

в этот исполняемый фрагмент кода.

Преимущества компиляции AOT

  • Меньший размер приложения (исключая компилятор Angular)
  • Более быстрый рендеринг компонентов (уже скомпилированные шаблоны)
  • Ошибки синтаксического анализа шаблона, обнаруженные ранее (во время сборки)
  • Более безопасный (нет необходимости динамически оценивать шаблоны)

Для компиляции AOT нам понадобятся некоторые инструменты, которые будут выполнять это автоматически в процессе сборки. В настоящее время существует два твердых раствора. Оба метода работают, но служат разным целям и имеют разные преимущества и недостатки.

Решение 1. Инструмент командной строки ngc

Инструмент командной строки ngc поставляется с пакетом @ angular / compiler-cli. Это оболочка для компилятора Typescript (tsc). Вы можете указать файлы для компиляции в tsconfig.json с помощью полей f iles и excludes. Параметры компилятора можно поместить внутри свойства angularCompilerOptions.

При запуске ngc он ищет входной модуль (он дает контекст для компиляции) и соответствующие компоненты, директивы и каналы. Для каждого из них он компилирует и выводит файл Typescript с суффиксом .ngfactory.ts, в котором находятся скомпилированные шаблоны. По умолчанию скомпилированные файлы создаются рядом с исходным файлом. Место назначения можно изменить с помощью genDir внутри angularCompilerOptions.

Кроме скомпилированных фабричных файлов, он также генерирует преобразованные файлы из Typescript в Javascript. Эти файлы представляют собой некомпилированные файлы Typescript с описанием исходных классов рядом с ними в файле с суффиксом .metadata.json. Эти файлы не нужны для запуска приложения в режиме AOT. Они пригодятся только при создании библиотеки Angular, поддерживающей компиляцию AOT.

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

Нам нужно изменить файл модуля на .ngfactory.ts с суффиксом
и импортировать начальную загрузку из @ angular / platform-browser. @ angular / platform-browser не включает компилятор, что значительно увеличивает размер файла.

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

Преимущества

  • Его всегда можно использовать с новейшей версией Angular сразу после ее выпуска.
  • После компиляции можно использовать любой инструмент связывания
  • Выводит файлы метаданных для разработки библиотеки

Недостатки

Примеры репозиториев

Решение 2.Плагин @ ngtools / webpack

Следующий пакет @ ngtools / webpack - это плагин для Webpack 2, публикуемый как часть репозитория Angular CLI. Он предоставляет загрузчик и плагин для настройки конфигурации.

Плагину требуется расположение конфигурации Typescript и модуля ввода приложения. Свойство entryModule состоит из пути к файлу и экспортируемого класса модуля, разделенных хэш-меткой. С их помощью он может запускать компилятор AOT и генерировать заводские файлы.

Одно большое отличие заключается в том, что он не переносит фабрику, метаданные и перенесенные файлы JIT Javascript в файловую систему. Он объединит приложение только на основе заводских файлов, которые существуют только в файловой системе памяти Webpack. Он также ищет точку входа и автоматически преобразует файл начальной загрузки, чтобы он стал подходящим для файлов, скомпилированных AOT.

Загрузчик внутри свойства rules позволяет использовать любой тип файла внутри свойства декоратора templateUrl и styleUrls компонента.
Например, SCSS, LESS для таблиц стилей и PUG для шаблонов. Он заменяет относительные URL-адреса в операторах templateUrl и styleUrls на require. Также лениво загружаемые модули на маршрутах передаются в операторы import, и субмодули также компилируются с помощью AOT с основным приложением.

Этот загрузчик в основном выполняет работу awesome-typescript-loader + angular-router-loader + angular2-template-loader и добавляет в цепочку компиляцию AOT.

Преимущества

  • Пользовательские типы файлов, доступные для шаблонов и стилей через загрузчики Webpack (SCSS, PUG,…)
  • Нет отдельного процесса для компиляции
  • Режим просмотра файлов, скомпилированных AOT
  • Нет необходимости поддерживать версию файла начальной загрузки AOT
  • Нет вывода на диск для отдельных файлов * .ngfactory.ts

Недостатки

  • Может использоваться только с Webpack 2
  • Нужно дождаться новых версий после выхода Angular в репозиторий Angular CLI.
  • Совместимо с текущей версией
  • Не подходит для публикации пакетов, совместимых с AOT, потому что он не выводит отдельные скомпилированные файлы

Примеры репозиториев

Решение 3.Плагин @ ultimate / aot-loader

Совершенно новый плагин Webpack 2 (в настоящее время находится в стадии бета-тестирования), созданный командой Ultimate Angular. Он предоставляет загрузчик и плагин для настройки конфигурации.

@ Ultimate / aot-loader очень похож по конфигурации и возможностям на плагин Angular CLI. Файлы фабрики и метаданные создаются только в файловой системе памяти. Точка входа также трансформируется для загрузки заводских файлов вместо обычных. Модули с отложенной загрузкой переносятся и разделяются на разные части, кроме основного пакета.

Загрузчики внутри правил позволяют нам писать шаблоны и стили компонентов в желаемом расширении (SCSS, PUG и т. Д.).

Преимущества

  • Те же преимущества, что и у пакета Angular CLI
  • Совместим с Angular 4

Недостатки

  • Может использоваться только с Webpack 2
  • Не подходит для публикации пакетов, совместимых с AOT, потому что он не выводит отдельные скомпилированные файлы

Примеры репозиториев

Резюме

Неважно, какое решение вы выберете, ваше приложение может значительно выиграть от компиляции AOT за счет размера и скорости. Он вдвое уменьшает размер приложения малого и среднего размера и увеличивает скорость его запуска. Если вы используете только HTML для шаблонов и CSS для стилей или систему сборки, отличную от Webpack, или разрабатываете пакет в Angular 2, ngc может вам подойти. В противном случае я бы придерживался плагина @ ngtools / webpack или @ ultimate / aot-loader и пользовался его преимуществами по сравнению с решением командной строки.

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

Спасибо за внимание! Если вам понравилась эта история, порекомендуйте ее, нажав кнопку 👏 сбоку и поделившись ею в социальных сетях. Подпишитесь на меня в Medium или Twitter, чтобы узнать больше об Angular!

Особая благодарность Вассиму Чегаму за изображения, посвященные компиляции AOT и JIT.