Оглавление

    Почему Flutter использует Dart, а не Kotlin или JavaScript

    Привет! Меня зовут Артём Зайцев, я руководитель Flutter-отдела в Surf

    Я и многие мои коллеги вышли из мобильной разработки, где господствуют Kotlin и Swift. Это очень «сахарные» языки: лаконичные, красивые, с элегантными конструкциями. Переход от них к Dart вызывает боль: «Зачем мне этот похожий на JS язык с динамической типизацией, когда у меня был Kotlin?» — думал я при первой встрече.

    При первом знакомстве Dart вызывает крайне противоречивые чувства у большинства мобильных разработчиков. Поэтому во время конференций и вебинаров мы постоянно слышим вопрос: «Почему Flutter использует именно Dart?». В статье я хочу дать ответ на этот вопрос.

    Откуда взялся Dart

    Однажды мой коллега сказал: «Откуда, блин, взялся этот Dart? Я реально ничего не слышал о нём до появления Flutter».

    И многие тоже ничего не слышали. А ведь Dart существует уже давно: если верить Википедии, его разрабатывают с 2011 года. Изначально он планировался как замена JavaScript от Google. Dart имел динамическую типизацию, был очень похож на JS и… на нём никто не писал, кроме разве что Wrike — долгое время они были единственной компанией, использующей этот язык.

    Основную известность Dart приобрёл благодаря кроссплатформенному фреймворку Flutter.

    Какой язык мог бы быть у Flutter вместо Dart

    Давайте немного поразмышляем: какой язык мог бы занять место Dart? В голову приходят несколько кандидатов, потому что они довольно популярны:

    1. Kotlin. Знакомый язык и де-факто стандарт для Android-разработчиков. Куча сахара и красота, буквально идеальный язык. Продукт JetBrains. Компилируемый.
    2. JavaScript. Обеспечил бы поток веб-разработчиков во Flutter. Негативно воспринимается многими мобильщиками. Интерпретируемый.
    3. Swift. Проприетарный язык Apple — кажется, вряд ли он подойдёт фреймворку от Google. Компилируемый.
    4. TypeScript. По сути это обертка над JS от Microsoft. Строгая типизация, но те же минусы, что у JS.

    По моему субъективному мнению здесь можно выделить Kotlin — уж очень я его люблю. Но у него нет тех свойств, что смогли бы обеспечить:

    • подгрузку кода в приложение на лету в режиме отладки;
    • синтаксис, понятный для людей с любых платформ;
    • быстрый сборщик мусора;
    • принадлежность к Google;
    • открытость кода и общение с командой напрямую.

    Пройдёмся по этим пунктам подробнее.

    Особенности Dart

    Компиляция и выполнение кода на Dart

    В целом методы компиляции можно разделить на три типа.

    Компиляция в промежуточный код. Основана на концепции виртуальной машины (VM), которая представляет собой продвинутый интерпретатор, эмулирующий аппаратное обеспечение внутри программного обеспечения. Виртуальная машина упрощает портирование языка для новых аппаратных платформ. В таком случае язык ввода для VM зачастую представляет собой промежуточный код. Например, код на языке программирования (скажем, на Java) компилируется в промежуточный код (байт-код Java), а затем исполняется на VM (JVM).

    Just-in-time (JIT) компиляция. JIT-компиляторы используют метод компиляции во время работы программы, «на лету». Они существенно ускоряют цикл разработки, но программа может притормаживать и выполняться медленнее. С JIT-компилятором она запускается медленнее, потому что перед выполнением кода ему нужно одновременно успеть проанализировать и скомпилировать его. Согласно исследованиям многие пользователи скорее всего откажутся пользоваться приложением, если на его запуск уходит больше пары секунд.

    Ahead-of-time (AOT) компиляция. AOT-компиляторы замедляют цикл разработки — промежуток времени, через который можно выполнить программу после внесения в неё изменений, чтобы посмотреть результат изменений. Но в результате AOT-компиляции разработчик получает программу, которая работает более предсказуемо, без перерывов на анализ и компиляцию в рантайме. Ещё такие программы, запускаются быстрее, потому что они уже скомпилированы.

    Казалось бы, причём здесь Dart? Его разработчики провели грандиозную работу над продвинутыми компиляторами и виртуальными машинами: движком V8 для JavaScript и Strongtalk для Smalltalk — для интерпретируемых языков, компилятором Hotspot для Java — для компилируемых языков. На основе полученного опыта они постарались сделать Dart необычайно гибким с точки зрения методов компиляции и выполнения.

    В итоге Dart отлично подходит как для AOT-, так и для JIT-компиляции. Поддержка обоих методов компиляции обеспечивает значительное преимущество для Dart и в особенности для Flutter.

    К JIT-компиляции обращаются при разработке и используют самый быстрый компилятор. Затем, когда приложение готово к выпуску, используют AOT-компиляцию. В результате, благодаря продвинутым инструментам и компиляторам, Dart берёт лучшее от двух миров: чрезвычайно быстрый цикл разработки, быстрое выполнение и запуск.

    На этом гибкость Dart с точки зрения компиляции и выполнения не ограничивается. Так, Dart можно компилировать в JavaScript, если нужно выполнить программу в браузере. В итоге получается переиспользовать код для мобильного приложения в web и наоборот. Некоторым разработчикам удаётся переиспользовать целых 70% кода в мобильных и web-приложениях. Ещё Dart можно применять для разработки серверных приложений: для этого потребуется компилировать его в нативный код или в JavaScript и использовать с node.js.

    И, наконец, для Dart существует отдельная виртуальная машина — DartVM — которая использует язык Dart в качестве промежуточного, по сути выступая в роли интерпретатора.Dart можно компилировать методами AOT или JIT, интерпретировать или компилировать в другие языки. Это даёт разработчику мега-фичу под названием Hot Reload. С ней можно практически мгновенно и без потери состояния подгрузить код в приложение в режиме отладки. Это невероятно ускоряет процесс разработки и позволяет избежать нудной пересборки приложения для просмотра каждого изменения. А в релизе программа получит высокую производительность благодаря AOT-компиляции.

    Сбор мусора

    Hot Reload — крутая фича, но её используют только разработчики в дебаг-режиме. В чём тогда выгода Dart для уже готового приложения? Ведь конечная цель — это удобство для пользователей.

    Здесь вступает в игру другое полезное свойство языка — его сборщик мусора. Да, самим сборщиком сейчас мало кого удивишь. Но здесь есть свои особенности, благодаря которым Flutter обеспечивает быструю работу и 60 FPS. Это даёт разработчикам возможность создавать крутые мобильные приложения с быстрым и отзывчивым пользовательским интерфейсом и секси-анимациями. Отчасти именно поэтому Flutter стал кроссплатформой, которая смогла завоевать доверие разработчиков.

    Давайте вспомним, как работает Flutter: всё в нём — виджеты. А виджеты — это по сути объекты. Их много, и они пересоздаются с огромной скоростью при каждом изменении кода. Поэтому здесь нужен не просто сборщик мусора, а суперсборщик мусора.

    В Dart используется продвинутая схема сбора мусора и выделение памяти на основе поколений объектов. Она особенно быстро выделяет память для большого количества объектов с коротким жизненным циклом. Это идеально для реактивных пользовательских интерфейсов вроде Flutter, где неизменяемое дерево виджетов пересобирается для каждого кадра.Благодаря такому сборщику Flutter приятен для разработки пользовательских интерфейсов в декларативном стиле. Мы используем конструкторы, создавая объекты, и описываем с помощью них верстку. Причём сами виджеты достаточно легковесны (это тоже важно), и представляют собой лишь информацию для отрисовки. Самой отрисовкой занимаются уже другие слои.

    Понятный синтаксис

    Выше я говорил, что переход с Kotlin на Dart был болью. Да, это так. Но самое интересное в другом: хоть мне и не хватало «сахара», я мог писать на Dart в тот же день. Наш опыт показывает, что члены команды могут писать на Dart и работать с Flutter уже через пару недель, если  они перешли из другого стека, и через три-четыре недели, если они совсем новички. Причём освоение синтаксиса занимало всего несколько дней.

    Dart очень прост и максимально близок любому разработчику, знакомому с Java/C#/JavaScript. У него хорошая и читаемая документация, а также подробный тур по языку. Благодаря этому можно научиться писать на Flutter достаточно быстро.

    Ну и конечно в синтаксис Dart привносит изменения сам Flutter. Несколько фич в языке появились именно благодаря фреймворку и коммуникации команд Dart и Flutter — все они работают внутри Google.

    Dart — это Google

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

    Открытый код

    Dart — это опенсорс. Он популярен как внутри Google, так и за его пределами. В Google его используют для Ads, Flutter, Fuchsia и других проектов — сейчас он среди наиболее быстро развивающихся языков. За пределами компании в репозиторий Dart коммитит более 100 сторонних разработчиков.

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

    Заключение

    Перечисленные причины конечно же субъективны, но основаны на том, как развивается Flutter и Dart. Истину знают только в Google. 

    Dart позволяет Flutter быть именно таким, какой он есть — крутым фреймворком для создания классных кроссплатформенных приложений. В Dart сложились вместе все факторы: он вполне современный и обладает всеми необходимыми свойствами, прост в освоении, принадлежит Google. Идеальный кандидат для кроссплатформенного фреймворка, который изменит мир.