One Что такое мини-программа
Ⅰ Концепция мини-программы
Апплет WeChat является создателем апплета, 9 января 2017 года WeChat официально запустил апплет. Прежде чем изучать техническую архитектуру мини-программ, давайте посмотрим, что такое мини-программы. «Мини-программы WeChat — это совершенно новый способ подключения пользователей и сервисов, которые можно легко приобретать и распространять в WeChat, обеспечивая при этом превосходный пользовательский опыт».
Это введение вызывает такое же чувство, как если бы я видел его раньше. Существует также онлайн-версия апплета WeChat: «Небольшая программа — это приложение, которое можно использовать без загрузки и установки, и оно реализует мечту «применимо у вас под рукой», и пользователи могут открывать приложение, проводя пальцем по экрану или выполняя поиск. Он также воплощает в себе концепцию «запустил и ушел», и пользователям не нужно беспокоиться о том, не установить ли слишком много приложений. Приложения будут вездесущими, всегда доступными, их не нужно устанавливать или удалять. "
Эта концепция более ясна.Можно увидеть, что апплет представляет собой множество экземпляров, работающих в хост-приложении, и сам апплет также является подключаемым внешним приложением.
Ⅱ Апплет с точки зрения пользователя
Давайте посмотрим на апплет с точки зрения взаимодействия с пользователем:
(фигура 1)iOS: с точки зрения независимости апплета (переключение между апплетом и апплетом, между апплетом и хост-приложением) базовое взаимодействие между апплетом BATT и апплетом China Merchants Bank аналогично. Android: с точки зрения взаимодействия апплет BATT можно рассматривать как независимое приложение, которое существует независимо в фоновом режиме (мультипроцесс) и может переключаться между апплетом и апплетом, между апплетом и хост-приложением. Интуитивно можно понять, что такая маленькая программа — это маленькое программное приложение. Апплет China Merchants Bank сосуществует с хост-приложением, то есть в процессе нельзя переключаться между апплетом и апплетом или между апплетом и хост-приложением. Этот тип апплета можно интуитивно понять как страницу апплета.
BATT: WeChat, Alipay, Toutiao, мини-программа Baidu. Поскольку взаимодействие похоже, они вызываются вместе.
Следовательно, с точки зрения пользователя интерактивный опыт BATT более выгоден. С точки зрения понимания концепции небольших программ понимание каждого приложения отличается, но это не влияет на использование функционального уровня.
Ⅲ Мини-программы с точки зрения платформы
Почему WeChat, самое раннее приложение мини-программ, создал эту штуку? Что именно он делает? На мой взгляд, основная цель по-прежнему заключается в контроле за целью, используя для достижения несколько средств, основной контроль заключается в двух аспектах:
Управление пользовательским интерфейсом: взяв за пример WeChat, WeChat определяет набор DSL вместо использования HTML для разработки страниц. Таким образом, разработчикам нельзя позволить развиваться по своему желанию, кроме как в рамках DSL WeChat. Конкретное преобразование DSL, написанное разработчиком, и метод рендеринга определяются платформой WeChat. На основе этого пользовательского DSL вы можете лучше выполнять работу по управлению кодом, такую как внесение запросов в белый список, сканирование кода и т. д.
Контроль услуг: взяв в качестве примера WeChat, услуги, предоставляемые хост-платформой в WeChat (такие как: оплата, спорт WeChat, карты и купоны, счета-фактуры, информация об учетной записи пользователя и т. д.), имеют разрешения как для сторонних пользователей, так и для третьих лиц. -партийные пользователи.контроль потребностей. Цель также состоит в том, чтобы не позволить апплету доступа вызывать базовые службы WeChat по своему желанию без механизма авторизации.
Техническая архитектура двух мини-программ
Основываясь на требованиях к опыту с точки зрения пользователя и требованиях к управлению и контролю с точки зрения платформы, давайте посмотрим, что технически сделал апплет на основе BATT для достижения этих целей.
Ⅰ Процесс рендеринга
На следующем рисунке показан процесс рендеринга апплета, включающий некоторые технические параметры, которые будут упомянуты в следующих частях:
(фигура 2)Ⅱ Основные технические моменты
- DSL (язык домена):
Прежде чем мы поговорим о DSL, давайте посмотрим, что нужно сделать для компиляции кода. Будь то интерпретируемый язык (JS, Ruby, Python) или компилируемый язык (Java, C++, C#), есть общая часть, которая анализирует исходный код в AST (абстрактное синтаксическое дерево). AST не только способен структурировать исходный код, но и играет ключевую роль в семантическом анализе. AST используется не только в интерпретаторах и компиляторах, но также широко используется в статическом анализе кода, например, когда мы рефакторим код, мы надеемся извлечь общие модули, чтобы уменьшить повторяющийся код и облегчить повторное использование. В настоящее время наш простой метод сравнения строк будет более односторонним и не может достичь эффекта, поэтому более полезно генерировать AST. Другой пример приложения будет более информативным для нашего проекта DSL: транскодеры. На следующей диаграмме показаны основные этапы преобразования кода одного языка в код другого языка:
(Рисунок 3: Изображение взято из Интернета)Исходный код сначала анализируется в AST. Перед разбором это текст, который следует правилам языка. После разбора он становится той же древовидной структурой, что и входной текст. Этот процесс обратим. Затем перейдите и замените AST.Этот процесс аналогичен генерации дерева DOM для внешнего интерфейса.Наконец, скомпилированный код генерируется в соответствии с измененным AST. Возьмем в качестве примера JS, используем acorn для генерации AST, а также можем использовать другие парсеры, такие как: babylon, esprima и т. д. Ниже приведен простой пример (ограничено пространством, дерево AST справа не полностью расширен, читатели могут использовать astexplorer для получения результатов):
(Рисунок 4)Так как контейнер рендеринга апплета может быть контейнером Webview, нативным контейнером или контейнером Flutter (хотя Flutter тоже является нативным рендерингом, чтобы отличить его от нативного Native, здесь он отделен, то же самое ниже), поэтому мы можем извлечь уроки из предыдущего конвертера кода.Идея использования AST для сглаживания разницы между конкретными контейнерами рендеринга, на следующем рисунке представлена общая идея преобразования DSL:
(Рисунок 5)Приведенная выше конструкция не завершена, предстоит еще много работы. Мы можем просто разделить обработку DSL на время компиляции и время выполнения.Время компиляции отвечает за предварительную компиляцию кода DSL в целевой код, и целевой код может выполняться в соответствующей среде выполнения. Функция сгенерированного объектного кода заключается в том, что фактический код может быть выполнен через параметры текущей среды в определенной среде выполнения.Простое понимание — это адаптер, который работает в среде с несколькими рендерингами.
Написание с нуля, безусловно, нереально для времени компиляции. Во-первых, продолжим тему AST выше, выше было упомянуто несколько парсеров AST: acorn, babylon, esprima. Конечно, есть много других, таких как: cherow, espree, Shift и т. д. Так что нам не нужно строить еще одно колесо, давайте возьмем в качестве примера babylon, потому что babylon используется в babel, он будет синхронизирован с последними функциями JS, а API хорошо разработан и прост в использовании. Babel — это компилятор js (не просто набор инструментов, поддерживаемый ES6, иначе он становится пакетом поддержки, подобным Android), который можно использовать для сжатия кода, преобразования синтаксиса и т. д. Для процесса генерации объектного кода: парсинг (babylon), трансформация (babel-traverse) имеет хорошую поддержку. Поскольку разные контейнеры рендеринга имеют разные библиотеки компонентов и API, а компоненты или API с одной и той же функцией используются по-разному, необходимо инкапсулировать код слоя адаптации.
Для среды выполнения необходимо только сгенерировать код конкретной среды рендеринга из кода адаптации, сгенерированного при компиляции, и выполнить его. Это похоже на логику Babel, преобразующую новую версию кода ECMAScript в старую версию кода.
- Родной рендеринг
С точки зрения производительности лучше визуализировать апплет в собственном режиме, чем использовать Webview в качестве контейнера для рендеринга. Дизайн DSL может хорошо защитить реализацию фактического рендеринга нижнего слоя.Вы можете использовать Native, H5 или их комбинацию.Переключение механизма нижнего рендеринга не повлияет на внешний доступ разработчиков апплета. . В настоящее время очень популярна технология мобильного кроссплатформенного нативного рендеринга, и чаще всего используются Weex/RN/Flutter. На рынке есть случаи небольших программ на базе Weex и RN, ведь Flutter — восходящая звезда, и случаев использования Flutter в качестве движка рендеринга нет.
- Многопроцессорность Android:
Ранее в разделе «Мини-программы с точки зрения пользователя» мы видели, что решение BATT позволяет мини-программам действительно работать как приложения. Поскольку приложение iOS не может запустить новый процесс, чтобы сам апплет работал в независимом процессе, апплет в iOS может использовать только один и тот же процесс с хост-приложением. Для Android все по-другому.Апплет занимает независимый процесс.С точки зрения безопасности приложение апплета второй и третьей стороны изолировано от основного процесса приложения, и проблемы апплета не повлияют на хост-приложение. Кроме того, с точки зрения производительности апплеты не совместно используют память хост-приложения. Исходя из фактической работы приложения апплета BATT, он в основном управляет пятью процессами, открытыми в фоновом режиме, для поддержания активности.Вы можете использовать пять действий контейнера для визуализации апплета в своем собственном процессе, а некоторые имеют ограничение по времени поддержания активности в фоновом режиме. Открытие нового апплета закроет процесс апплета, который был открыт первым, тем самым достигнув цели эффективного горячего запуска.
- Многопоточность:
Логическая изоляция рендеринга: Прежде всего, прежде чем говорить о конкретной многопоточности, давайте поговорим о логике и рендеринге апплета. Логика и рендеринг апплета разделены.Конечно, с функционального уровня этого можно добиться и без разделения. Упомянутое здесь разделение логики и рендеринга означает, что логика апплета выполняется в потоке отдельной среды JS, нужен только движок JS, а рендеринг выполняется в потоке Webview. Разделение логики и рендеринга на два потока имеет несколько преимуществ: во-первых, логику и код рендеринга можно разделить без связывания, а во-вторых, логические потоки и потоки рендеринга можно выполнять параллельно, а выполнение JS не будет блокировать пользовательский интерфейс. Третье — дополнить цель управления пользовательским интерфейсом, упомянутую выше.В логическом потоке JS работает в движке JS, а не в веб-просмотре, что ограничивает возможность работы с DOM путем внедрения кода JS, любого API, связанного с пользовательским интерфейсом. невозможно изменить его через JS, который достигает цели управления пользовательским интерфейсом вместе с DSL. Четвертое преимущество заключается в том, что несколько страниц апплета используют одну и ту же среду выполнения логики JS, которая может легко и эффективно обмениваться данными.
(Изображение 6)На приведенном выше рисунке показан процесс связи логического уровня и уровня представления, и связь передается через мост, и используется режим публикации/подписки. Уровень представления передает событие, инициируя событие пользовательского интерфейса, передавая событие через мост на нативный уровень, затем передавая событие через мост на логический уровень, логический уровень обрабатывает событие для передачи данных, затем передает данные через мост на Родной, а затем вернуться к представлению мостом Слой визуализируется.
оптимизация: После того, как логика и рендеринг разделены, логический поток должен отправлять данные в поток рендеринга, а поток рендеринга должен отправлять события в логический поток, которые все должны быть сериализованы в строки для передачи. Это вызовет проблемы, частая передача данных, а одна большая передача данных приведет к проблемам с производительностью. В ответ на эту проблему стоит изучить идею дизайна апплета Alipay.Апплет Alipay переработал виртуальную машину V8, так что логика и рендеринг имеют собственную локальную среду выполнения для хранения частных модулей и данных. Он также предоставляет Shared Heap общей глобальной среды выполнения для обмена данными, что по-прежнему обеспечивает изоляцию логики и рендеринга и снижает затраты на сериализацию и передачу.
- Предварительная загрузка:
Разработчик апплета сделал множество оптимизаций в приложении апплета, таких как: предварительная загрузка данных. С момента, когда пользователь нажимает на страницу, до onload() новой страницы будет задержка 100-300 мс. Это время задержки можно использовать для предварительной загрузки данных. Упомянутая здесь предварительная загрузка апплета при запуске находится на уровне структуры рендеринга апплета. Оптимизация iOS предварительно загрузит еще один wkwebview, чем фактический апплет рендеринга, и поместит его в фоновый режим.Открытие нового апплета будет напрямую отображать предварительно загруженный wkwebview напрямую, экономя время инициализации; реализация на Android немного сложнее, но это еще пространство Чтобы изменить время, с момента запуска хост-приложения Android будет запущен зарезервированный процесс.При открытии нового апплета этот процесс будет занят, и новый процесс будет предварительно загружен до верхнего предела пятого процесс открыт.
- Оффлайн пакет (подпакет):
Основная цель механизма автономных пакетов состоит в том, чтобы разрешить замену ресурсов страницы с сетевого ввода-вывода на локальный ввод-вывод при открытии апплета. По сути, это вытягивание или комбинирование push-pull из сети перед открытием приложения, а пресеты и другие методы позволяют автономным пакетам быть локальными перед открытием апплета. В обязанности модуля автономного пакета входит: обновление, распаковка, сохранение, чтение и проверка и т. д. Конечно, он также может выполнять двоичные дифференциальные пакеты. При работе с механизмом офлайн-пакета также необходимо учитывать проблему того, что весь апплет как офлайн-пакет будет влиять на эффективность, поэтому здесь необходимо добавить схему подпакетов.Оффлайн-пакет можно разделить на основной пакет и несколько подпакетов.Пакет в основном включает в себя: ресурсы первого экрана, общедоступный код, информацию о связанных подпакетах и т. д. Подпакеты могут содержать ресурсы страниц вторичных страниц. Таким образом можно повысить скорость открытия первого экрана и достичь цели загрузки по требованию, как показано на следующем рисунке:
(Рисунок 7)Ⅲ Технический отбор
- IDE
Платформа апплета имеет собственную IDE. В текущей ситуации с многосистемной платформой определенно лучше выбрать кроссплатформенную настольную технологию для разработки IDE апплета. Здесь я выбрал Electron и NW.JS, чтобы сделать сравнение:
(Рисунок 8)Проще говоря, оба протокола с открытым исходным кодом относительно дружелюбны, если вы обращаете внимание на безопасность кода или совместимы с требованиями XP, выбирайте NW.JS, который также является выбором отечественных производителей, если сравнивать с точки зрения поддержки разработки , выберите Электрон.
- JS-движок
Как упоминалось ранее, уровень логики имеет отдельную среду JS, что также показывает с точки зрения управления и контроля, что это также может предотвратить риск изменения пользовательского интерфейса JS. С точки зрения выбора технологии iOS может использовать встроенный JScore.Хотя JS-движок wkwebview на iOS имеет большую JIT-оптимизацию, чем JScore, скорость выполнения намного выше, но по сравнению с дополнительным введением JS-движка, используется встроенный движок JS. Имеет неотъемлемое преимущество стабильности и не увеличивает размер пакета. В этом разделе некоторые люди могут упомянуть, что Flutter представил механизм рендеринга skia в iOS.Преимущество введения Skia во Flutter в iOS заключается в том, что он использует тот же механизм рендеринга, что и движок skia, поставляемый с Android, который будет иметь лучший пользовательский интерфейс. совместимость продвигать. Проблема совместимости с движком js намного меньше. Для Android вариантов больше, вот сравнение основных движков JS:
(Рисунок 9)Старая версия апплета WeChat использует JScore, новая версия использует V8; переработанный V8 используется для апплета Alipay; апплет Toutiao также использует V8; видно, что процент побед V8 по-прежнему очень высок, и соглашение об открытом исходном коде тоже относительно дружелюбен.
Три эпилога
Эта статья представляет собой введение в реализацию архитектуры рендеринга апплета.Что касается самой платформы апплета, то есть некоторые другие функции и точки оптимизации, такие как: маршрутизация апплета, загрузка пакетов отладки, статистика скрытых точек, оптимизация виртуального дома. , так далее. Эта статья знакомит только с некоторыми основными процессами и техническими моментами. Чтобы действительно построить идеальную платформу апплета, необходимо рассмотреть еще много деталей. С точки зрения разработчиков апплета, есть также возможности для оптимизации, такие как: каркасный экран. Создание небольшой программной платформы требует комплексного применения нескольких платформ и многочисленных технических возможностей для постоянного улучшения.С появлением новых технологий в будущем к небольшим программам будет применяться больше технологий.
об авторе
Ван Лихан, присоединившийся к команде в сентябре 2018 года, работал в Alibaba и Sohu Changyou. В настоящее время он отвечает за создание мобильной платформы разработки Minsheng Technology Company.