Ангуляр что это такое


Введение в Angular: что это за фреймворк и зачем его использовать

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

Зачем нужен фреймворк?

Если вы не знаете, то JS (или клиентский) фреймворк – это технология, обеспечивающая нам инструментами для создания веб-приложения, но также задающая дизайн приложения и организацию кода.

Большинство фреймворков сейчас слишком самоуверенны. У них есть своя философия того, как должно строиться веб-приложение. Вам придется потратить время, чтобы изучить базовые концепции. Другие решения типа Backbone не указывают разработчикам, как строить проект. Поэтому некоторые даже называют такие технологии просто библиотеками, а не фреймворками.

На самом деле, JS фреймворки появились не так давно. Я помню, когда сайты писали с плохо структурированным JS кодом (в большинстве случаев под управлением jQuery). Однако клиентские UI становились все сложнее, и JS потерял репутацию «игрушечного» языка. Современные сайты сильно полагаются на JS, поэтому необходимость правильной организации (и тестирования!) кода возросла. Поэтому клиентские фреймворки стали популярны, и на данный момент их, как минимум, десяток.

Введение в Angular: что такое Angular

Раньше среди JS фреймворков AngularJS был любимчиком, так как был представлен корпорацией google в 2012. Он был построен по концепции Model-View-Controller. Авторы же фреймворка называли концепцию “Model-View-*” или даже “Model-View-Whatever”.

Практический курс по созданию веб-приложения на Angular4

Скачайте БЕСПЛАТНЫЙ мини-курс и изучите базовые возможности JavaScript-фреймворка Angular 4 за ближайшие 3 дня

Узнать подробнее

Фреймворк на чистом JS должен был разъединить логику приложения и манипуляции с DOM. Его целью были обновления динамических страниц. Но это было не так навязчиво: под контролем AngularJS могла быть только часть страницы. Этот фреймворк представил много мощных функций, позволяющих разработчикам легко создавать богатые, одностраничные приложения.

В частности, была представлена интересная концепция привязки данных, по которой представление автоматически обновляется при любом изменении модели и наоборот. Поверх этого представили идею директив, которые позволяют создавать собственные HTML теги и оживлять их через JS. Например, можно написать:

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

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

AngularJS стал популярен очень быстро и получил большую поддержку. Тем не менее, разработчики решили пойти еще дальше и перешли к созданию новой версии Angular 2 (позже просто Angular без части JS). Фреймворк получил новое имя не просто так: он был полностью переписан и перепроектирован, а многие концепции были пересмотрены.

Первый стабильный релиз Angular 2 опубликован в 2016, после чего AngularJS стал терять популярность в угоду новой версии. Одна из главных функций Angular 2 – возможность разрабатывать под несколько платформ: веб, мобильные устройства и нативный десктоп (AngularJS по умолчанию не имел мобильной поддержки).

Чтобы еще сильнее все усложнить в конце 2016 вышел Angular 4. «А где же версия 3?», спросите вы. У меня был тот же вопрос. Как оказалось, версии 3 вообще не было опубликовано! Но как так? В официальном блоге разработчики объяснили, что с Angular 2 перешли на семантическое управление версиями.

Следуя этому принципу, изменение основной версии (например, 2.х.х становится 3.х.х) означает переломные изменения. Проблема в том, что компонент Angular Router уже был в версии 3. Чтобы исправить это несоответствие, было принято решение пропустить Angular 3. К счастью, переход с Angular 2 на 4 прошел легче, чем с AngularJS на Angular 2, но разработчиков все же смутила вся эта путаница.

В ноябре 2017 вышел Angular 5. Он совместим с предыдущими версиями Angular. Скоро должен выйти Angular 6 и должен привнести еще больше крутых функций и улучшений.

Введение в Angular: преимущества Angular

Так почему же Angular? Потому что он поддерживается на разных платформах (веб, мобильные устройства, нативный десктоп), он мощный, современный, у него отличная экосистема, и он просто крутой. Не убеждены? Позвольте немного углубиться в подробности:

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

Это JS, но лучше. Angular построен на TypeScript, который, в свою очередь, полагается на ES6. Вам не нужно учить полностью новый язык, и вы получаете функции типа статической типизации, интерфейсов, классов, пространства имен, декораторы и т.д.

Не нужно изобретать велосипед. В Angular уже есть много инструментов для создания приложения. Благодаря директивам, HTML элементы могут вести себя динамически. Вы можете усилить формы с помощью FormControl и представить различные правила валидации. Можно легко посылать асинхронные HTTP запросы различных типов. Можно без труда настроить маршрутизацию. В Angular есть еще много функций!

Компоненты разъединены. Angular старался убрать жесткую связь между различными компонентами приложения. Инъекция проходит подобно NodeJS, что позволяет легко заменять компоненты.

Практический курс по созданию веб-приложения на Angular4

Скачайте БЕСПЛАТНЫЙ мини-курс и изучите базовые возможности JavaScript-фреймворка Angular 4 за ближайшие 3 дня

Узнать подробнее

Все манипуляции с DOM проходят там, где должны. В Angular представление и логика приложения не связаны, что сильно очищает и упрощает разметку.

Тестирование в центре внимания. Angular тщательно протестирован и поддерживает юнит тесты и сквозное тестирование с помощью инструментов типа Jasmine и Protractor.

Angular подготовлен к мобильным устройствам и десктопу – один фреймворк под множество платформ.

Angular активно обслуживается и имеет большое сообщество и экосистему. По фреймворку можно найти много материалом и полезных сторонних инструментов.

Можно сказать, что Angular не просто фреймворк, а платформа, которая позволяет разработчикам строить приложения для веба, мобильных устройств и десктопа. Более подробно архитектуру можно изучить в этом руководстве.

Введение в Angular: сложности Angular

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

Рекомендуется писать приложения Angular на TypeScript, поэтому его нужно понимать. Можно писать код на современном JS (ES6), но я редко вижу такое.

TypeScript – надстройка JS. Поэтому ее тоже нужно знать.

Чтобы еще сильнее ускорить процесс разработки, нужно понять Angular CLI.

Для установки Angular и других компонентов активно используется npm. Его также нужно знать.

Умение настраивать таск раннеры типа Gulp или Grunt также может пригодиться. С их помощью можно много чего сделать перед развертыванием приложения в продакшене.

Сейчас широко используются минификаторы типа UglifyJS и упаковщики типа Webpack.

Во время разработки приложения очень важно иметь возможность отлаживать код. Нужно уметь работать в инструментах отладки типа Augury.

Очень важно тестировать приложения Angular, которые могут стать очень сложными. Один из самых популярных инструментов тестирования — Jasmine (фреймворк для тестирования) и Protractor (используется для сквозного тестирования).

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

Стоит отметить, что иногда использовать Angular для приложения будет излишне. Если проект маленький или средний без сложного UI и взаимодействия, возможно, лучше взять старый добрый JS. Поэтому очень важно оценить все требования, функции нового приложения и дедлайны перед принятием решения об использовании JS фреймворка.

Заключение

В этом введении в Angular мы обсудили Angular, клиентский фреймворк с поддержкой нескольких платформ. Мы узнали о его некоторых функциях и концепциях, а также узнали об отличии от AngularJS, предыдущей версии фреймворка.

Надеюсь, теперь вы понимаете основную идею Angular, и где он может пригодиться!

Автор: Ilya Bodrov-Krukowski

Источник: https://www.sitepoint.com/

Редакция: Команда webformyself.

Практический курс по созданию веб-приложения на Angular4

Скачайте БЕСПЛАТНЫЙ мини-курс и изучите базовые возможности JavaScript-фреймворка Angular 4 за ближайшие 3 дня

Узнать подробнее

webformyself.com

Angular 2: что это такое

Всем привет! Сегодня мы начнем разбирать фреймворк от известной компании Google — Angular 2.

Что такое Angular 2

Это фреймворк, основной целью которого является создание одностраничных браузерных приложений или по другому Single Page Application (SPA).  Многие фичи были взяты из AngularJs ( первая версия ).

Вот какие отличительные достоинства имеет ангулар 2:

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

Недостатком является малое количество документации именно для русскоязычной аудитории, преимущественно это связано из-за недавнего релиза во всемирную паутину.

Для работы с Angular 2 используются:

  • TypeScript
  • JavaScript
  • Dart

Основным из этих трех значится TypeScript, который является препроцессором JavaScript. Это значит, что после компиляции файла весь код будет переведен на JavaScript. Поэтому  ваша программа будет работать на любом современном браузере.

Браузер Версии
  Chrome С первой версии
  FireFox С первой версии
  Edge С версии выше 13
  Internet Explorer С версии выше 9
 Safari С версии выше 7
  IOS С версии выше 7
  Android С версии выше 4.1
  Internt Explorer Mobile С версии выше 11

Каким образом он будет переводится поговорим позже.

Возможности Angular 2

В ангулар 2 большое количество фич, которые стоит разобрать. Сейчас мы пройдемся по основным из них.

  • Модульная система — это свойство отделение определенного функционала приложения в отдельные файлы (напоминает объектно-ориентированное-программирование).
  • Компоненты — с помощью их отображается содержимого html, css на экран браузера.
  • Метаданные — руководят правильным отображениям компонентов и их классов.
  • Анимация — компоненты работающие с интерфейсом по средством анимации.
  • Формы — компонент работающий с вводимыми формами. Что произайдет после клика по кнопке, после удаление всех символов с формы, за это все отвечает этот компонент.
  • Сервисы — компоненты которые внедряют (несут) логику во взаимодействие с приложением.
  • Роутер — компонент, который обеспечивает загрузку компонентов из другого компонента. Можно реализовать загрузку содержимого без перезагрузки самой страницы. Например, вы отправили форму, или перешли по ссылке. Такая загрузка реализована на официальном сайте.
  • Директивы — помогают улучшить взаимодействие с работой интерфейса.
  • Работа с сервером — взаимодействие с сервером.

Обо всем этом и многом другом будут сделаны отдельные уроки.

Если у вас имеются идеи по поводу создания новых статей, то пишите в комментарии.

codelessons.ru

Просто Angular

8-9-го декабря 2016 года была проведена первая конференция по Angular в Бельгии. Игор Минар (ведущий разработчик Angular) выступил в качестве основного докладчика с несколькими интересными объявлениями относительно того, по какому графику будет выпускаться Angular. И представьте себе, в марте 2017 года нас ждет релиз Angular 4. При этом, на данный момент уже опубликована бета-версия.

От переводчиков

Всем привет, с вами Максим Иванов и Дмитрий Сергиенков, и сегодня мы выясним куда делась третья версия, и почему мы по-прежнему можем быть верны Angular. Сейчас начинающему фронтенд-разработчику, изучающему JavaScript, довольно трудно определиться: какой же фреймворк или библиотеку им взять и изучить, оставаясь в тренде? Конечно, без слова React, сейчас не обходится ни один разговор на тему фронтенда, однако, в свое время я начал с первой версии Angular, начитался много руководств по написанию фронтенда на ES6 (с классами и прочим добром) и до сих пор не жалею. Да, вы можете писать корпоративные приложения с использованием только jQuery, но по мере развития и сложности проекта вы начнете закапывать себя в спагетти-коде, смешивая логику и представление, MV*-фреймворки же этого сделать вам не дадут.

Содержание

Почему Angular 4? Где Angular 3? Что происходит?

Спецификация семантического версионирования

Еще в сентябре, когда вышла вторая версия, Angular Team объявила о том, что она будет поддерживать семантическое версионирование (SEMVER).

Как видно из названия, семантическое версионирование — это добавление смысла каждому номеру версии. Семантика номера версии позволяет разработчику определить, что за модернизация была проведена в данной версии продукта, к тому же, мы можем настроить наши инструменты, например, менеджер пакетов NPM, таким образом, чтобы при сборке приложения выбиралась конкретная версия зависимых библиотек, чтобы при этом мы ничего не сломали.

Семантика версии состоит из трех чисел:

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

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

Что это может означать для Angular Team? Понятно, что для любого бурно развивающегося программного обеспечения наступает момент, когда приходится проводить критические изменения. И поэтому, по объективным соображениям, Angular Team сменила версию 1.x на 2.x, из-за того, что те изменения, которые были выполнены, сломали работу основного кода.

Критические изменения не должны приносить боль

Сообщество Angular точно поймет, о чем идет речь. Пользователям, чтобы перейти на вторую версию, пришлось переписать весь код. Хотя многие и полюбили Angular 1.x, но по объективным причинам были сделаны общие критические изменения, был написан новый API, новые шаблоны. Это было очевидно, и в конечном счете, Angular 2 был полностью переписан (хотя и существует способ менее болезненно мигрировать на новую версию).

Сейчас решено, что переход от версии 2 до версии 4, 5,… не должен быть таким болезненным, как это было с первой версией. Теперь код не будет полностью переписываться, наши изменения будут затрагивать только отдельные библиотеки, поставляемые сейчас с Angular 2, в свою очередь они будут соблюдены согласно SEMVER. Кроме того, постепенно мы будем включать Deprecation фазы (предупреждения консоли разработчика о том, что в следующих версиях данный функционал поддерживаться не будет), чтобы позволить разработчикам своевременно перейти на новый функционал.

Angular Team использует собственный инструмент контроля изменений и обработки автоматических обновлений. Команда упорно работает над ним, и запланировала выпуск совместно с выходом Angular 5 в 2017 году.

Теперь это просто «Angular»

Как вы, возможно, уже догадались, термин «Angular 2» будет устаревшим с выходом 4-ой или 5-ой версии. Тем не менее, теперь следует начать называть его просто «Angular» без версии. Кроме того, вы должны начать избегать библиотек с GitHub/NPM с префиксом ng2- или angular2-. Существует единый ресурс с документацией — angular.io c официальным сообществом на GitHub.

Новые правила версионирования

С этого момента, старайтесь избегать использования номера версии, если он не является действительно необходимым для устранения неоднозначности.

Три простых руководящих принципа:

  • Используйте «Angular» по умолчанию (например, «Я angular-разработчик», «Это Angular-Meetup», «Angular сообщество быстро развивается»)
  • Используйте «Angular 1», «Angular 2», «Angular 4», когда речь идет о специфичных вещах («Это эта функция X появилась в Angular 4», «Мы обновились с Angular 1 до 2», «Я предлагаю это изменение в Angular 5»)
  • Используйте полную версию semver при сообщении об ошибке (например, «Эта проблема присутствует в Angular 2.3.1»)

Вся документация, даже для Angular 1.x, будут приведены в соответствие с этими правилами в ближайшие недели. Но если вы пишите что-то в своем блоге, пишите статьи, курсы, книги или всякий раз, старайтесь ориентироваться на специфическую версию Angular, дописывайте версию в заголовках публикации, якобы в данной статье используется Angular 2.3.1. Это помогает избежать путаницы для ваших читателей, особенно, когда вы пишете о конкретных API.

Почему мы решили все же пропустить третью версию

Библиотеки ядра Angular находятся в одном репозитории на GitHub. Все они имеют свою версию и распространяются как различные пакеты NPM:

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

Кроме того, важно понимать, что Angular используется в Google. Большинство приложений Google используют Angular из основной ветки репозитория на GitHub. Всякий раз, когда происходит обновление в ветке master, все сразу же интегрируется в основной внутренний репозиторий Google (в компании используется один монолитный репозиторий), где располагаются такие продукты как Google Maps, Adsense и другие. В результате все проекты, использующие Angular падают, если они имеют критические изменения, поэтому приходится все переписывать, что, в свою очередь, неудобно. Таким образом, лучше всего иметь полностью унифицированную версию, которую было бы легче поддерживать в течение долгого времени, что помогло бы команде быть более продуктивной в выпуске новых функций.

Предварительный график релизов

Тот факт, что критические изменения все же будут, не означает, что они появятся сразу же через неделю. Angular Team уверяет в том, что в дальнейшем у вас останется обратная совместимость между версиями, теперь изменения будут иметь четкий характер и идти по конкретному графику в течение трех циклов:

  • патч-релизы каждую неделю
  • каждые 3 месяца будут появляться незначительные изменения (minor) в функционале
  • каждые 6 месяцев новая версия Angular с незначительной миграцией

Следующие 3 месяца будут посвящены доработке Angulr 4.0.0.

После Angular 4.0.0 вас ждет предварительный график дальнейших выпусков:

Вывод: не беспокойтесь

В конце Игор Минар подытожил:

  • не беспокойтесь о номерах версий
  • мы должны развиваться вместе с Angular, чтобы не допускать такого, как это было с различиями между Angular 1.x и 2.x, мы должны сделать это вместе как сообщество, развивать и улучшать наш любимый продукт
  • вы должны осознать почему нам пришлось поступить так с Angular 1.x и переписать все с нуля

Angular2 Webpack Starter

Angular2 Webpack Starter — представляет из себя репозиторий для быстрого старта с Angular и TypeScript, посредством сборщика проектов Webpack.

Что включено в данный репозиторий:

  • Лучшие практики по организации файлов и каталогов на Angular 2
  • Система сборки Webpack 2 с TypeScript
  • Демонстрационный пример на основе Angular 2
  • Свежая версия Angular
  • Ahead of Time (AoT) для быстрой загрузки вашего приложения
  • Tree shaking для автоматического удаления неиспользуемого кода из вашего проекта
  • Тестирование с использованием Jasmine и Karma
  • Покрытие тестами с Istanbul и Karma
  • End-to-end Angular 2 тестирование с Protractor
  • Менеджер типов с @types
  • Material Design
  • Hot Module Replacement
  • Поддержка Angular 4 путем изменения package.json и любых других будущих версий

Быстрый старт

Убедитесь, что у вас есть Node.js версии >= 5.0 и NPM >= 3.0

# клонируем наш репозиторий git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git # выбираем директорию cd angular2-webpack-starter # устанавливаем зависимости посредством npm npm install # далее по желанию # запускаем сервер npm start # запускаем Hot Module Replacement npm run server:dev:hmr

Переходим на http://0.0.0.0:3000 или http://localhost:3000 в вашем браузере. Более подробно на официальном репозитории.

Содержательный видеокурс

Курс даст возможность быстро начать создавать свои приложения с использованием одного из самых популярных фреймворков – Angular 2. В процессе прохождения курса шаг за шагом вы сделаете реальное приложение и хорошо разберетесь в специфике Angular 2. Курс на английском, но на самом деле, если у вас хромает язык, главное попытаться вникнуть в код, который пишет автор, в основном все прикрепляется слайдами, которые тоже интуитивно понятны. Платить ничего не нужно, сиди и развивайся.

Что хорошего появилось в уходящем 2016 году вместе с Angular 2

Статистика (на сентябрь 2016 года)

  • 1.2 миллиона разработчиков использующих Angular 1
  • 623 тысячи уже используют Angular 2

Если Angular 1 был монолитным проектом, то теперь Angular 2 следует рассматривать как платформу.

Angular 1 использовал 43 встроенных директивы, теперь в Angular 2 мы используем [ ] и ( ).

Angular 2 быстрее

Изначально Angular 1 весил 56K. При этом ядро самого Angular 2 было — 170K. Angular Team оптимизировали тонны кода и теперь ядро Angular 2 весит 45K.

Отложенная загрузка

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

Быстрый рендеринг

По сравнению с первой версией приложения на Angular 2 работают в 2,5 раза быстрее, а перерисовка в 4,2 раза быстрее. Команда Angular считает, что она может сделать рендеринг еще более быстрым.

Официальное руководство по написанию кода

Во времена Angular 1 появилось большое количество руководств по написанию кода. Это привело к большому количеству отличительных стилей, что привело к разночтению в Интернете. Для Angular 2 теперь есть официальное руководство по стилю.

Материальный дизайн для приложений на Angular 2

Angular Material выглядит действительно хорошо. Использовать материальный стиль в вашем приложении достаточно легко, просто встраивайте компоненты.

Прогрессивные web-приложения с Angular Mobile Toolkit

Angular Mobile Toolkit позволит легко создавать веб-приложений, которые загружаются мгновенно на любом устройстве, даже без подключения к Интернету.

Прогрессивные веб-приложения очень интересны для многих веб-разработчиков. Создание и повторное использование вашего кода для создания мобильного приложения с хорошей производительностью, почти равное нативному мобильному приложению. Angular Mobile Toolkit является еще одним шагом к осуществлению этой мечты.

Шаблонизация на стороне сервера

Большой проблемой приложений на Angular 1 было то, что они собирались только в браузере. Это означает, что ваши приложения были совершенно SEO-неориентированные.

Команда Angular вынесли основной компонент сборки, и теперь ваши приложения можно собирать где угодно, в том числе и на сервере.

Достаточно легко это сделать при помощи NodeJS для сборки шаблонов на стороне сервера.

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

Быстрая разработка приложения через терминал при помощи Angular CLI

Самое приятное — это Angular CLI. Установка приложения занимает много этапов, где много вещей может пойти не так:

  • настройка типизации с TypeScript
  • настройка импортов компонентов
  • запуск приложения
  • использование System.js

Angular CLI делает установку простой в одну строку:

ng new scotch-app

Чтобы начать работать с Angular CLI, все, что вам нужно сделать, это:

npm install -g angular-cli ng new scotch-app cd scotch-app ng serve

Больше нам не требуется Gulp, Grunt, Webpack, Browserify.

Большое количество туториалов

Например, это видео вполне объясняет как построить приложение на Angular 2:

Опциональная типизация в вашем web-приложении

Есть много интересных вещей, которые может сделать TypeScript. Есть много причин, почему вы должны использовать TypeScript. Благодаря TypeScript Angular 2 стал лучше развиваться.

Хорошие инструменты для отладки

Любой человек, который использует Batarangle с Angular 1 знает, что его способность видеть переменные и состояние вашего приложения в браузере является большим подспорьем при разработке.

Теперь есть Angular Augury, он позволяет нам сделать именно это. Нет необходимости в console.log () в каждой части вашего приложения, чтобы увидеть состояние переменной, иерархию и наследование в вашем браузере.

Платформа для разработки бизнес-приложений Firebase

Вы можете построить приложение в режиме реального времени с Angular 2, Firebase и AngularFire2 примерно за 10 минут, например чат. Есть много функциональных возможностей, которые реализуются в короткий промежуток времени.

Кроссплатформенные мобильные приложения с NativeScript + Angular 2

В то время как Angular Mobile Toolkit сосредоточено на создании прогрессивных веб-приложений, NativeScript больше заинтересован на создании нативных приложений с Angular 2.

В чем разница, спросите вы? Например в анимации. Имея нативную анимации, отличную от браузерной все будет выглядеть гладко даже при большом количестве объектов.

Простое тестирование благодаря зонам

Zone.js библиотека для управления асинхронными задачи, способ управления контекстом выполнения. Много фантастических слов, но основная идея состоит в том, что тестирование будет намного проще в Angular 2!

Все эти асинхронные задачи отслеживаются благодаря zone.js. В своем видео Джули Ральф рассказывает как это работает:

В заключении

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

habr.com

Создаем свой Angular 2

Здравствуйте, в этой статье описан механизм работы Angular 2. Сегодня мы заглянем под капот популярного фреймворка. Эта статья является вольным переводом доклада Тобиаса Боша (Tobias Bosch) — The Angular 2 Compiler. Ссылку на оригинал доклада Вы можете найти в конце статьи.

Овервью

Тобиас Бош – сотрудник компании Google и член рабочей группы разработчиков Angular, который создал большинство составляющих частей компилятора. Сегодня он рассказывает о том, как работает Angular изнутри. И это не что-то заоблачно сложное. Надеюсь, что вы используете некоторые полученные знания в своих приложениях. Возможно, вы, как и наша команда, создадите свой собственный компилятор или небольшой фреймворк. Я расскажу о том, как работает компилятор и как мы достигли своей цели.

Что такое компилятор?

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

Все то, что происходит между ними – это сфера деятельности компилятора. С виду может показаться, что это чистой воды магия. Но это не так.

Что мы сегодня рассмотрим?

Сначала мы немного поговорим о производительности: что имеется в виду под быстрой работой? Мы поговорим о том, какие виды входных данных у нас есть. Также мы поговорим о лексическом анализе, о том, что это такое, и что компилятор Angular 2 делает с анализом. Мы поговорим о том, как Angular 2 берет проанализированные данные и обрабатывает их. В целом, реализация этого процесса происходила у нас в три попытки, сначала была простая реализация, потом улучшенная и еще более улучшенная. Так сделали это Мы. Это те этапы, благодаря которым нам удалось достичь ускоренной работы нашего компилятора. Также мы обсудим разные среды, достоинства и недостатки динамической (Just In Time) и статической (Ahead Of Time) компиляции.

Производительность: что означает быстрая работа?

Представим ситуацию: я написал приложение и утверждаю, что оно быстро работает. Что я имею в виду? Первое, что можно подумать, это то, что приложение очень быстро загружается. Возможно, вы видели AMP-страницы Google? Они загружаются нереально быстро. Это можно отнести к понятию «быстрый». Возможно, я использую большое приложение. Я переключаюсь от одной рубрики к другой. Например, от краткого обзора к развернутой странице, и такой переход происходит очень шустро. Это тоже может характеризовать быстроту. Или, скажем, у меня есть большая таблица и сейчас я просто изменю все ее значения. Я создаю новые значения без изменения структуры. Это реально быстро. Все это – разные аспекты одного и того же понятия, разные вещи, на которые нужно обращать внимание в приложении.

Переход по путям

Я хотел бы остановиться детальней на этапе перехода по путям (switching a route). Важный момент, — при переходе по путям, фреймворк разрушает и воссоздает все заново. Он не придерживается структуры: все разрушается и все воссоздается заново.

Как можно сделать этот процесс быстрым?

Чтобы сделать что-то быстро, нужно измерить эту быстроту. Для этого нужен тест. Один из тестов на производительность, которые мы используем – это тест производительности по методу deep-tree. Возможно, вы слышали о таком. Это компонент, который используется дважды. Это рекурсия компонента до тех пор, пока не будет достигнута определенная глубина.

У нас есть 512 компонентов и кнопки, которые могут разрушать или создавать эти компоненты. Далее мы замеряем, сколько времени уходит на разрушение и создание компонентов. Так и происходит переход по путям. Переход от одного view к другому. Разрушение всего – создание всего.

Какие у нас есть входные данные?

Компоненты

У нас есть компоненты, и я думаю, что их все знают.

У них есть шаблон (template). Вы можете сделать шаблоны встроенными или поместить их в отдельный файл, стоит помнить что у них есть контекст. Экземпляры компонентов по своей сути – это контекст, данные, которые используются для постройки шаблона (template). В нашем случае, у нас есть пользователь, у пользователя есть имя (в нашем случае это мое имя).

Шаблон

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

Здесь мы имеем некоторый новый синтаксис: помните двойные фигурные скобки, квадратные и круглые скобки? Это привязка Angular к свойствам или событиям. Сегодня мы будем говорить только о фигурных скобках и о том, что они означают. С точки зрения семантики это значит «взять данные из компонента и поместить их в определенное место». При изменении данных должно происходить обновление текста.

Директивы

Директивы содержат селектор – это селектор CSS. Суть в том, что когда Angular проходит разметку, если он находит директиву, которая соответствует какому-то элементу, то выполняет ее. Допустим, у нас есть селектор для форм, и этим мы как бы говорим, — каждый раз когда мы создаем элемент формы, пожалуйста создай эту директиву. Точно так же и с ngModel. Когда вы создаете атрибут ngModel, вы должны создать и директиву. У этих директив могут быть зависимости. Это наше выражение зависимости.

Зависимость имеет иерархическую структуру, таким образом, чтобы ngModel запрашивала ngForm.

И что же делает Angular?

Он просматривает все дерево в поисках ближайшей ngForm, которая на один уровень выше в структуре дерева. Он не будет просматривать одноуровневые элементы, только родительские. Есть и другие входные данные, но мы не будем останавливаться на них подробно. Все, что делается в Angular, проходит через компилятор. Хорошо, у нас есть входные данные. Следующее, что нам необходимо – это понять их. Это просто набор бреда, или, все-таки, это имеет какой-то смысл?

Процесс лексического анализа

Первая стадия
Допустим, у нас есть какой-то шаблон, к примеру, HTML.

Представление шаблона

Как мы его можем представить таким образом, чтоб компилятор его понял? Этим занимается анализатор. Он прочитывает каждый символ, а затем анализирует смысл. То есть, он создает дерево. У каждого элемента есть только один объект. Допустим, есть какое-то имя – имя элемента, есть дочерние элементы. Скажем так, текстовый узел представляет собой JSON объект с текстовыми свойствами. Также у нас есть атрибуты элемента. Скажем так, мы кодируем это все как вложенные списки. Первое значение – это ключ, второе – это значение атрибута. И так далее, здесь нет ничего сложного. Такая репрезентация называется абстрактным синтаксическим деревом (АСД, english — AST). Вы будете часто слышать это понятие. Это все – HTML.

Как мы можем изобразить связь элемента с данными?

Мы можем отобразить это следующим образом. Это – текстовый узел, то есть у нас есть JSON объект с текстовыми характеристиками. Текст пустой, потому что изначально нет никакого текста для отображения. Текст зависит от входящих данных. Входящие данные представлены в этом выражении. Любые выражения также анализируются на предмет того, что же они означают. Вы не можете обьявить функцию внутри выражений или исрользовать цикл for, но у нас есть такие штуки как pipes, при помощи которых Вы можете работать с выражениями. Мы можем изобразить это выражение, user.name, как путь к свойству. А также мы можем уловить, откуда именно из вашего шаблона это выражение пришло.

Определение места выражения

Так почему же это так важно? Почему нам важно знать, откуда именно из АСД пришло это выражение? Все потому, что мы хотим показать вам сообщения об ошибках во время выполнения программы. Скажем так, чтобы ваш пользователь знал об этих ошибках. И потом, бывают же и исключения? Например, невозможно прочитать имя из undefined. Если такое происходит, тогда вам нужно отправиться в отладчик ошибок и проверить, установить точку прерывания на первой ошибке. Тогда вы должны понять, где именно произошла ошибка.

Компилятор Angular предоставляет вам больше информации

Он показывает, из какого именно места в шаблоне «растут ноги» этой ошибки. Цель – показать вам, что ошибка берет свои истоки, например, из конкретно этой интерполяции во второй строке, 14 столбце вашего шаблона. Для этого нам нужно, чтобы номера строк и столбцов были в АСД.

Далее, какие нам нужны анализаторы, чтобы построить это АСД?

Здесь существует множество возможностей. Например, мы можем использовать браузер. Браузер – отличный анализатор HTML, верно? Он занимается этим каждый день. Такой подход у нас был при разработке Angular 1, этот же подход мы начинали использовать при разработке Angular 2. Сейчас мы не используем браузер в таких целях по двум причинам:
  1. из браузера нельзя вытащить номера строк и столбцов. При анализе HTML браузер просто не использует их.
  2. мы хотим, чтобы Angular работал и на сервере.
Очевидно, что на сервере нет браузера. Мы могли бы сказать: в браузере мы используем браузер, а на сервере мы используем нечто другое. Так и было. Но потом мы попали в тупиковые ситуации, например, с SVG, или с размещением запятых, поэтому нам нужно было, чтобы везде была одинаковая семантика. Поэтому, проще вставить фрагмент JavaScript, и анализатор. Это как раз то, что делаем мы. Итак, мы говорили об HTML и выражениях.

Как мы представляем директивы, которые мы находим?

Мы можем отобразить их через JSON объекты, которые представляют элементы, просто добавив другое свойство: директивы. И мы ссылаемся на функции конструктора этих директив. В нашем примере с вводными данными с ngModel, мы можем изобразить этот элемент как JSON объект. У него есть имя input, атрибуты, ngModel и директивы. У нас есть указатель на конструкторы, а также мы улавливаем зависимости, потому что нам нужно указать, что если мы создаем ngModel, нам нужна и ngForm, и нам нужно подхватить эту информацию. Учитывая АСД с информацией HTML, связями и директивами, — как мы воплощаем это все в жизнь? Как это можно сделать проще всего? Сначала разберемся с HTML. Какой самый простой способ создать элемент DOM? Во-первых, вы можете использовать innerHTML. Во-вторых, вы можете взять уже существующий элемент и клонировать его. И в-третьих, вы можете вызвать document.createElement. Давайте проголосуем. Кто считает, что способ innerHTML – самый быстрый? А кто считает, что element.cloneNode быстрее всего создаст элемент? Или может, самый быстрый способ – это element.createElement? Очевидно, все меняется с течением времени. Но на данный момент:
  • innerHTML – это самый медленный вариант. Это очевидно, потому что браузер должен вызвать свой анализатор, взять вашу строку, пройтись по каждому символу и построить элемент DOM. Очевидно, что это очень медленно.

  • element.cloneNode – это самый быстрый способ, потому что у браузера уже есть построенная проекция, и он просто клонирует эту проекцию. Это просто добавление в память еще одного элемента. Это все, что требуется сделать.
  • document.createElement – это нечто между двумя предыдущими способами. Этот способ очень близок к element.cloneNode. Чуть-чуть медленнее, но очень близок.

Вы скажете: «Хорошо, давайте будем использовать element.createElement для создания нового элемента DOM». Так работал Angular 1, и так же мы начинали при разработке Angular 2. И по традиции, оказывается, что это не совсем честное сравнение, по крайней мере, не в случае с Angular. В случае использования Angular, нам нужно создать какие-то элементы, но, помимо этого, мы должны разместить эти элементы. В нашем случае мы хотим создать новые текстовые узлы, но также нам нужно найти именно тот, который отвечает за user.name, поскольку позже мы хотим обновить его. Поэтому, если сравнивать, то мы должны сравнивать как создание, так и размещение. Если использовать innerHTML или cloneNode, то придется заново проходить весь путь построения DOM. При использовании createElement или createTextNode вы обходите эти действия стороной. Вы просто вызываете метод и сразу же получаете его исполнение. Никаких новых построений и прочего. В этом отношении, если сравнивать createElement и createTextNode, они оба примерно одинаковы по скорости (зависимо от количества привязок). Во-вторых, требуется гораздо меньше структур данных. Вам не требуется отслеживать все эти индексы и прочее, поэтому такие способы проще и почти одинаковы по скорости. Поэтому, мы используем эти способы, и другие фреймворки также переключаются на такой подход. Итак, мы уже можем создавать элементы DOM.

Теперь нам нужно создать директивы

Нам нужно внедрение зависимостей от дочернего элемента к родительскому. Допустим, у нас есть структура данных под названием ngElement, которая включает элемент DOM и директивы для данного элемента. Также есть родительский элемент. Это простое дерево внутри дерева DOM.

И как же мы можем создать элементы DOM из АСД?

У нас есть шаблон, у нас есть элемент, из которого мы построили АСД. Что мы можем сделать со всем этим?

В нашем ngElement и конструкторе вызываем document.createElement, просматриваем атрибуты и присваиваем их элементам, и дальше добавляем элемент к нашему родительскому элементу. Как видите, никакой магии.

Дальше переходим к директивам. Как это работает?

Мы просматриваем привязки, каким-то образом получаем их (расскажу об этом чуть позже) и просто повторно вызываем new для конструктора, отдаем ему привязки и сохраняем Map. Map будет переходить от типа директив (ngModel) к экземплярам директив. И весь этот поиск директив будет работать таким образом: у нас будет метод, который получает директиву, которая сначала проверяет сам элемент (если ли у него директива). Если нет, то возвращаемся к родителю и проверяем там. Это самое простое, что можно сделать. Мы сами начинали в этом направлении. И это работает.

Важная деталь: привязки. Как отобразить привязки?

Вы просто создаете класс binding, у которого есть target – Node. Им будет текстовый узел. У target есть свойство, в нашем случае это будет значение узла, это место, куда поместится значение. И выражение.

Привязка работает таким образом: каждый раз, когда вы оцениваете выражение или когда оно просто изменяется, вы сохраняете его в target. То есть у вас может быть следующий метод: сначала вы оцениваете выражение, если оно изменилось – то обновляете target и другие сохраненные ранее значения.

Что касается тех исключений, о которых речь шла ранее – мы вызываем методы try catch для отслеживания пути оценивания. Когда срабатывает исключение, мы его повторно генерируем и создаем для него модель из номеров строк и столбцов. Так мы и получаем номера строк и столбцов, в которых есть ошибки. Это все мы связываем в представление. Это последняя структура данных.

Представление – это элемент шаблона. То есть, когда мы просматриваем код ошибок – мы увидим много представлений. Это просто элементы шаблона. И их мы соединяем в представление. Представление ссылается на компонент, ng-элементы и привязки а также метод dirty-check, который просматривает привязки и проверяет их. Вот мы и закончили первую стадию. У нас есть новый компилятор. Насколько мы быстры? Почти на таком же уровне, что и Angular 1. Уже неплохо. Используя подход проще, мы добились той же скорости. А ведь Angular 1 не медленный.
Вторая стадия

Как нам ускорить процесс? Какой следующий шаг? Что мы упустили? Давайте разбираться. Нам нужно что-то, что имеет отношение к нашим структурам данных. Когда дело касается структуры данных, на самом деле, это очень сложный вопрос. Если сравнивать с прошлой написанной нами программой, где появляется try-catch, но если отбросить это, мы увидим, что многие функции тормозят процесс, и что многие моменты нужно оптимизировать. Если вы считаете причиной медленной работы своей программы структуры данных, то это очень сложный вопрос, потому что они разбросаны по всей вашей программе. Это всего лишь предположение, что дело в структурах данных. Мы провели эксперименты и попробовали разобраться. Мы наблюдали за этими директивами: Map внутри ngElements.

Получается, что для каждого элемента в дереве DOM мы создаем новый map? Можно было бы сказать, что там нет директив, мы их не создавали. Но все-таки, мы всегда создаем map, наполняем его директивами и считываем с него информацию. Это может быть неэкономно, это может перегружать память, прочтение все-таки занимает тоже какое-то время. Альтернативный подход: можно сказать: «Окей, мы разрешаем только 10 директив для одного элемента. Далее мы создаем класс inlinengElement, 10 свойств для элементов директив и типов директив, и для того, чтобы найти директиву мы создаем 10 условных операторов IF». Это быстрее? Возможно.

Это не потребляет много ресурсов памяти, да?

К примеру, установка: вы устанавливаете свойство, а не map. Чтение может быть немного медленным из-за 10 условий. Это как раз тот случай, для которого был оптимизирован JavaScript VM. JavaScript VM может создавать скрытые классы (можете погуглить о них на досуге). Это и делает JavaScript VM быстрее. Переключение на эту структуру данных – это то, что ускоряет процессы. Позже мы посмотрим на результаты тестов производительности. Еще одна штука, для которой нужно оптимизировать структуры данных – это повторное использование существующих экземпляров. Можно задать логичный вопрос, — Если некоторые строки уничтожены, а другие восстанавливаются, то почему тогда не кешировать эти строки в кеше и изменять данные, как только строки появляются? Так мы и сделали. Мы создали так называемый view cache, который восстанавливает старые экземпляры представлений.

Перед тем, как перейти в новый пул, нужно уничтожить состояние. Состояние содержится в директиве. Так мы убиваем все директивы. Далее, когда происходит выход из пула, нужно заново создать эти директивы. Этим занимаются методы hydrate и dehydrate. Узлы DOM мы сохранили, поскольку все происходит из модели, весь статус – в модели. Поэтому мы ее и сохранили. И снова мы провели тест на производительность.

Среда тестирования

Чтобы вы поняли результаты этих тестов, стоит отметить, что Baseline – это программа с ручным JavaScript кодом и жесткой кодировкой. В такой программе не были использованы никакие фреймворки, программа была написана только для этого теста deep–tree. В программе производится dirtyChecking. Эту программу мы приняли за единицу. Все остальное сравнивается в соотношении. Angular 1 получил отметку 5,7.

Раньше мы показывали такую же скорость с оптимизированными структурами данных и без view cache. Мы были на уровне 2,7. Так что, это неплохой показатель. Мы увеличили скорость в два раза за счет быстрого доступа к свойствам. Сначала мы подумали, что наша работа на этом заканчивается.

Недостатки второй стадии

Мы создали приложения на этой базе. Но потом мы увидели недостатки:
  1. ViewCache плохо дружит с памятью. Представьте, вы переключаете маршруты обработки запросов. Ваши старые запросы остаются в памяти, потому что они кешированы, не так ли? Вопрос в том, когда удалять запросы из кэша? На самом деле, это очень сложный вопрос. Можно было бы создать несколько простых элементов, которые бы позволяли пользователю выбирать, кэшировать что-то или нет. Но это было бы, как минимум, странно.
  2. Еще одна проблема: элементы DOM имеют скрытое состояние. Например, элемент помещен в фокус. Даже если у вас нет привязки к фокусу, и элемент может находиться как в фокусе, так и вне его, то его удаление или возвращение может изменять фокус этого или других элементов. Про это мы не подумали. Появились связанные с этим баги. Можно было пойти таким путем: мы могли полностью удалять элементы, чтобы удалить их состояние, и даже восстанавливать их. Но это бы свело на нет показатели ViewCache, если бы нам пришлось воссоздавать DOM. Ведь у нас был показатель 2,7. Как же мы бы достигли скорости в такой ситуации?
Третья стадия
Класс view Дальше к нам пришла мысль: давайте еще раз посмотрим на наш класс view. Что там у нас? У нас есть компонент – эти уже оптимизированные ngelement, так? У нас есть привязки. Но класс view по-прежнему содержит эти массивы. Можем ли мы создать InlineView, который тоже использует только свойства? Никаких массивов. Это возможно? Оказалось, да. Как это выглядит? Примерно так.

Шаблон

Итак, у нас, как и ранее, будет шаблон, и для каждого элемента мы просто будем создавать код. Для этого шаблона мы будем создавать код, который отображает наш класс view. В конструкторе для каждого элемента мы вызовем document.createElement, который будет храниться в свойстве Node0 – для первого элемента, для второго мы опять вызовем document.createElement, который будет храниться в Node1. Дальше, когда нам понадобится присоединить элемент к своему родителю, у нас есть свойства, так ведь? Нам просто нужно сделать все в правильном порядке. Мы можем использовать свойство для обращения к предыдущему состоянию. Именно так мы поступим с DOM.

Директивы

С директивами мы поступаем точно так же. У нас есть свойства для каждого экземпляра. И опять-таки, нам просто нужно убедиться в правильности порядка выполнения действий: что сначала идут зависимости, а затем те компоненты, которые используют эти зависимости. Что сначала мы используем ngForm, а затем – ngModel.

Привязки

Далее, привязки. Мы просто создаем код, который выполняет dirty-check. Мы берем наши выражения, конвертируем их обратно в JavaScript. В этом случае это будет this.component user.name. Это значит, что мы вытаскиваем user.name из компонента, сравниваем его с предыдущим значением, которое так же является свойством. Если значение изменилось – мы обновляем текстовый узел. В конце мы сводим все к представлением со структурой данных. В ней только свойства. Нет никаких массивов, Map, везде используется быстрый доступ через свойства. Это значительно ускоряет процесс. Скоро я покажу вам цифры, чтобы вы могли убедиться в этом.

Вопрос вот в чем: как мы это делаем?

Скажем, кому-нибудь нужно создать строку, которая оценивает этот новый класс. Как это делается? Мы просто применяем то, что мы делали в реализации 101 в нашей текущей реализации. Суть вот в чем: Если раньше мы создавали DOM узлы, сейчас мы создаем код для создания DOM узлов. Если раньше мы сравнивали элементы, сейчас мы создаем код для сравнения элементов. И наконец, Если раньше мы обращались к экземплярам директив или узлам DOM, сейчас мы храним свойства там, где хранятся экземпляры директив и узлы DOM. В таком случае код выглядит вот как.

Раньше, у нас был наш ngelement, сейчас у нас есть compileElement. На самом деле эти классы сейчас существуют в компиляторе. Там есть compileElement, compileView и так далее. Отображение будет таким: раньше у нас был элемент DOM, сейчас же у нас есть только свойство, в котором хранится элемент DOM. Раньше мы вызвали document.createElement, сейчас же мы создаем строку с этой новой строковой интерполяцией, которая отлично подходит для создания кода, в котором мы говорим, что this.document + название его свойства равнозначен document.createElement с названием АСД. И наконец, если раньше мы вызывали appendChild, то сейчас мы создаем код для присоединения дочернего элемента к родительскому. То же самое происходит и с поиском директив-зависимостей. Все происходит по такому же алгоритму, только сейчас для этих целей мы создаем код.

Если сейчас мы посмотрим на показатели, то увидим, что сейчас мы гораздо увеличили скорость. Если раньше наш показатель был 2,7, то сейчас он составляет 1,5. Это почти в два раза быстрее. ViewCache, по-прежнему, остается чуть быстрее. Но мы исключили вариант с его использованием, и вы уже знаете причины нашего решения. Мы отлично справились, и могли бы уже закончить. Но нет.

Динамическая (Just in Time) компиляция

Итак, вначале мы говорили про динамическую (Just in Time) компиляцию. Динамическая – это значит, что мы компилируем в браузере.

Напомним, это работает примерно так: у вас есть какие-то входящие данные, которые находятся на вашем сервере. Браузер их загружает и забирает, анализирует все, создает исходный класс view. Теперь нам нужно оценить этот исходный код для того, чтобы получить еще один класс. После этого мы можем создать этот класс, и далее мы получаем работающее приложение. С этой частью возникают определенные проблемы:
  1. Первая проблема в том, что нам нужно анализировать и создавать код внутри браузера. Это занимает какое-то время, в зависимости от того, сколько у нас компонентов. Мы должны пройти все символы. Конечно, это происходит достаточно быстро. И все же, на это тоже нужно время. Поэтому ваша страница будет загружаться не самым быстрым образом.
  2. Вторая проблема – это то, что анализатор должен находиться в браузере, поэтому нужно загрузить весь Angular компилятор в браузер. Поэтому, чем больше свойств мы добавляем и чем больше мы создаем кода, тем больше становиться размер.
  3. Следующая проблема – это использование eval. При использовании eval вы можете сделать ошибки, из-за которых кто-то может взломать ваш сайт. Поэтому вам не стоит использовать eval, даже если вы думаете, что с вашим кодом все в порядке. (примечание, — детальнее о том почему стоит избегать использование eval читайте тут)
  4. Еще одной проблемой является то, что сейчас браузер добавляет политику защиты содержимого в качестве отличительной особенности (возможно, вы знаете об этом). С таким раскладом, сервер может дать указание браузеру, что не нужно вообще оценивать ту или иную страницу. Для браузера это может означать, что на этой странице не нужно запускать Angular вообще. Это не очень хорошо.
  5. Следующая проблема, с которой мы столкнулись, это минификация кода. Если вы хотите минифицировать код (а я надеюсь, что вы так и делаете, чтобы предоставлять клиенту как можно меньше кода), существуют кое-какие уловки, которые вы можете применить:
    1. Во-первых, вы можете переименовать переменные, обычно это безопасно, потому что вы можете определить, где используется та или другая переменная.
    2. Во-вторых, вы можете переименовать свойства объектов. Это сложнее, поскольку вы должны знать, где же именно используется тот или иной объект. Компилятор Closure поддерживает такую функцию (она называется «улучшенная минификация»), мы его использовали в Google и использовали часто.
Итак, если мы используем улучшенную минификацию во время работы компилятора, происходит вот что. Есть наши компоненты, наша разметка, загружаются в браузер, браузер анализирует шаблон и создает класс view. Пока все идет нормально. Браузер использует user.name, компонент также содержит user.name, просто этот user.name минифицирован с помощью технологии улучшенной минификации. Таким образом, компонент называется, скажем, С1, а мой пользователь внезапно оказывается просто U, а имя – N. Проблема в том, что минификатор не знает о моем шаблоне. Ведь в шаблоне по-прежнему остался user.name. Итак, шаблон исполняется, по-прежнему создает user.name, которого просто не существует в компоненте. Есть определенные решения этой проблемы. Вы можете указать компоненту, что это свойство минифицировать не нужно. Но это не то, что нам нужно. Нам нужно, чтобы мы могли минифицировать это свойство, но с оперативной компиляцией и оценкой это работать не будет.

Статическая (Ahead of Time) компиляция

Именно по этой причине, следующим нашим шагом стало появление статической (Ahead of Time) компиляции. Она работает следующим образом.

Снова у нас есть входные данные, которые анализируются на сервере, и класс view также создается на сервере. Тогда браузер просто подхватывает их, загружает как обычный текст сценария (как вы загружаете свой обычный код JavaScript), и затем просто создает нужные элементы. Такой способ компиляции отлично подходит, потому что: Анализ происходит на сервере (а поэтому происходит быстро), компилятор не нужно переносить в браузер (и это тоже отлично). Также мы больше не используем оценку, ведь это скрипт. Поэтому такая компиляция подойдет для любого браузера. Также статическая компиляция отлично подходит для улучшенной минификации, потому что теперь мы создаем класс view на сервере, и если мы запустим минификатор, то сможем также минифицировать и наши классы view. Теперь, когда минификатор исполнит свою работу, мы получим переименованные свойства в классах. Отлично, теперь мы можем использовать улучшенную минификацию. Поэтому, наши показатели скорости упали еще ниже.

Недостатки статической компиляции

Итак, теперь у нас есть статическая компиляция. Теперь все отлично, да? Но как всегда, существуют и недостатки. Первая проблема состоит в том, что с использованием статической компиляции нам нужно создавать другой код. Для оценки в браузере нужно создавать код по стандарту ES5. Вы создаете код, который использует локальные переменные, или который получает аргументы, переданные в функцию. Вы не используете require.js или что-либо в этом роде. Поскольку код генерируется на сервере, то нужно было генерировать код TypeScript по двум причинам:
  • Во-первых, мы хотели проверять типы ваших выражений (существуют ли они в компонентах).
  • Во-вторых, мы хотели эффективно использовать систему модулей TypeScript. Мы хотели создать импорт, чтобы уже вы могли выбирать, какие системы модулей вы хотите использовать. Создание импорта — это гораздо удобнее со стороны возможностей генерации кода, чем думать о require.js, system.js, Google Closure, системе модулей и так далее.
  • В конце концов, мы также хотели применить код стандарта ES6 2016.

Как нам удалось обеспечить поддержку ES6 2016?

На самом деле, если вы знакомы с компиляторами, то существует общий шаблон. Вместо создания строк создается структура данных, похожая на выводимые данные, но эту структуру данных, эту АСД, можно сериализовать в разные выходные данные. АСД содержит такие возможности, как объявление переменной, вызов методов и так далее, плюс типы. Потом для ES5 мы просто сериализуем это все без типов, а для TypeScript сериализуем с типами. Это выглядит примерно так: наш сгенерированный АСД вывод, внутри объявленные переменные (мы указываем declare var name EL). Это создаст код var el в TypeScript и создаст тип. В ES5 тип будет опущен. Далее мы можем вызвать метод. Сначала мы прочитаем переменную document (поскольку это глобальная переменная). И потом для нее мы сможем вызвать метод createElement с этими аргументами. Мы разместили literal со значением «div», потому что, если вы анализируете строки, то должны правильно их экранировать. Значение может содержать кавычки, поэтому при чтении кода нужно их экранировать, пропускать. Поэтому, именно таким образом мы можем это сделать. Хорошей новостью можно назвать то, что теперь наш сгенерированный код одинаково выглядит как на сервере, так и в браузере. Никаких различных частей кода. Вторая проблема, с которой мы столкнулись при разработке статического компилятора, это выделение метаданных. Взгляните на этот код.

В чем проблема этого кода? Скажем, у нас есть какая-то директива, которая имеет зависимость от cookies, и если у вас есть cookies, директива выполняет что-то другое. Это работает. Вы можете скомпилировать. Супер. Но это не работает со статической компиляцией. Если подумать, почему так? Если это все спустить до уровня ES5, вы получите именно такой код. Что, в конечном счете, делает декоратор? Он добавляет свойство вашему конструктору для метаданных. В конце он просто добавляет SomeDir с примечаниями. Проблема в том, что если вы запустите это на сервере, оно не будет работать. Ведь на сервере нет document. Что же делать? Можно предложить построить среду браузера на сервере, объявить переменную document, переменную window и так далее. В некоторых случаях это сработает, но в большинстве – нет. Второй способ (мы же теперь хорошо разбираемся в АСД, так?) – обработать АСД и вынуть из него метаданные без оценки кода. В АСД этого можно представить как-то так.

Таким образом, наш класс SomeDir в АСД может иметь свойство decorators, которое обращается к тому элементу, который вы вызываете (это выражение, где определена директива плюс аргументы). Происходит следующее. Мы вытаскиваем метаданные в JSON файлы, дальше наш статический компилятор берет эти файлы и из них создает шаблон. Очевидно, здесь есть ограничения. Мы не оцениваем JavaScript код напрямую, поэтому вы не можете делать все то, что вы привыкли делать в браузере. Итак, наш статический компилятор ограничивает нас, но вы можете поместить примечание. Но если вы воспользуетесь приведенным выше методом, это сработает во всех случаях. Хорошо, давайте снова остановимся на тестах производительности.

Это – простая написанная нами программа. И время ее загрузки сократилось очень значительно. Все потому, что мы больше не проводим анализ, а также потому, что компилятор Angular 2 больше не загружается. Это почти в три раза быстрее. Размер также сократился с уже минифицированных в формате gzip 144 килобайт до 49. Для сравнения, библиотека React с улучшенной минификацией сейчас весит 46кб.

А теперь немного наглядных примеров

Допустим, у нас есть компонент Angular, у нас есть ngForm и ngModel. ngModel в качестве зависимости имеет ngForm.

Добавим сюда NGC – это модули _node, которые охватывают компилятор TypeScript, поскольку при вытаскивании и поддержке метаданных эти модули зависят от TypeScript. И если мы посмотрим на сгенерированный код, то увидим, что он выглядит очень знакомо. У нас есть user.name. Если его значение меняется, мы обновляем входные данные директивы. Мы просто сравниваем с предыдущим значением и устанавливаем его. В этом есть хорошая сторона. Допустим, в своем шаблоне я меняю user.name на wrongName. Наш шаблон обращается к user.name, а не к user. wrongName. Теперь, когда мы посмотрим на сгенерированный код, TypeScript выдаст ошибку.

Потому что эти представления имеют типы, основаны на типе компонента. И теперь при их компиляции вы будете обнаруживать ошибки своего кода, просто потому что мы использовали TypeScript. Ничего другого нам не понадобилось. Мы хорошо справились, но мы стремимся стать еще лучше. Наша цель – достичь размера 10 кб gzip. Размер некоторых наших прототипов составляет 25 кб и у меня есть несколько идей, как сделать компилятор еще меньше. Далее, мы хотим стать еще быстрее, чем наша отправная точка Baseline. Мы осознаем, что это еще не предел, и мы можем быть еще быстрее, чем Baseline. Вы не заметите никаких изменений. Вы будете осуществлять изменения, генерировать разный код. Единственное – вы увидите разницу только в скорости.

В качестве заключения

Мы говорили про производительность, про разные аспекты производительности. Мы обсуждали входные данные. Мы узнали, что такое анализ, АСД (AST). Я рассказывал о том, как мы можем представить шаблон и как его реализовать. Мы узнали, что document.createElement отлично подходит для фреймворка Angular. Мы узнали, что быстрый доступ по свойствам и скрытые классы – это отличные инструменты для оптимизации вашего кода. Мы узнали, что генерация кода (если сделать это правильно, то есть не только с помощью оценки, но и с поддержкой оффлайн, а также вывод АСД) – это отличная и мощная вещь. Это поможет вам в генерации скрытых классов. Мы поговорили о статической (Ahead Of Time) и динамической (Just In Time) компиляции, а также о вещах, которые можно оптимизировать. И наконец, мы посмотрели наглядный пример. На слайде есть ссылка на мою презентацию. Огромное спасибо за внимание. Теги:

habr.com


Смотрите также