Принцип архитектуры мини-программы WeChat

Архитектура внешний интерфейс JavaScript Апплет WeChat
Принцип архитектуры мини-программы WeChat

предисловие

Вчера читала в кругу друзей.Говорят,что некоторые люди тратят деньги на покупку звезд.Не знаю,правда это или нет? Я думал, что это просто шутка. Статья, которую я прочитал сегодня утром, была опубликована Baidu EUX@田光宇.

Текст начинается здесь~~

Апплет WeChat

Апплет WeChat содержит следующие четыре типа файлов:

  • js

  • JSON-файл конфигурации

  • xml-файл, специфичный для апплета wxml

  • css для апплета wxss

<view>
    <text class="window">{{ text }}</text>
</view>
Page({
  data:{
    text:"这是一个页面"
  },
  onLoad:function(options){
    // 页面初始化 options为页面跳转所带来的参数
  },
  // ........
})

Апплет WeChat может динамически изменять страницу только с помощью своего синтаксиса шаблона mvvm, а сам js не поддерживает операции BOM и DOM.

Архитектура апплета Wechat с точки зрения инструментов разработки

Разархивируйте приложение прямо на стороне Mac и найдите папку app.nw, которая является исходным кодом инструмента разработки. Вы можете узнать, что проект написан nw.js, найдите запись приложения в файле package.json: app/html/index.html. Запись js — это dist/app.js, и мы можем видеть общую логику всего редактора.

Но что нас волнует, так это процесс сборки, в папке weapp есть файл build.js. Я не нашел никакой полезной информации, я видел только модуль загрузки, включая ограничение по размеру и имя пакета загрузки.

По этой причине сам апплет WeChat похож на RN. Он упакован на родном языке на стороне сервера. Однако в ходе теста границы Android было обнаружено, что апплет WeChat вообще не является нативным контентом. Кроме того, мы пишем синтаксис WeChat в инструменте разработки и можем просмотреть его напрямую. Должна быть проблема.

вырос таким

процесс компиляции

Продолжайте находить скомпилированные шаблоны в папке trans.

  • TransWxmlToJs из wxml в js

  • TransWxssToCss из wxss в css

  • Конфигурация страницы шаблона transConfigToPf

  • трансвксмлтохтмл из wxml в html

  • трансМенеджер менеджер

Используемый контент:

  • Выяснилось, что использовался шаблон: app.nw/app/dist/weapp/tpl/pageFrameTpl.js, app.mw/app.dist.weapp/tpl/appserviceTpl.js.

  • исполняемая программа wcc, wcc используется для преобразования пользовательского тега в wxml в virtual_dom

  • Исполняемая программа wcsc используется для преобразования wxss в код css, используемый модулем представления.Метод использования: wcsc xxx.wxss

В шаблоне мы обнаружили использование файла WAWebview.js, файла WAService.js. В transWxmlToJs мы находим функцию события generateFuncReady. Сравните функцию, которая регистрирует это событие в WAWebview.js.

Попробуем скомпилировать файл input.xml с помощью wcc.

wcc -d input.xml

Генерируется скрипт:

window.__wcc_version__ = 'v0.6vv_20161230_fbi'
var $gwxc
var $gaic = 
$gwx = function (path, global) {
    function _(a, b) {
        b && a.children.push(b);
    }
    ....

С помощью кода мы обнаружили, что вызов функции $gwx сгенерирует другую функцию с возвращаемым значением (при условии, что путь заполнен правильно), поэтому выполняем следующий код:

$gwx("input.xml")("test")

дает следующее:

{
    "tag": "wx-page",
    "children": [
        {
            "tag": "wx-view",
            "attr": {
                "class": "section"
            },
            "children": [
                {
                    "tag": "wx-input",
                    "attr": {
                        "autoFocus": true,
                        "placeholder": "这是一个可以自动聚焦的input"
                    },
                    "children": []
                }
            ]
        }
    ]
}

Это должен быть объект, похожий на виртуальный дом, переданный WAWebivew.js для рендеринга, с тегами wx-view, wx-input.

WAWebview.js

  1. На данный момент код предоставляет инструменты совместимости, а также представлен weixinjsbridge.

  2. Далее следует объект Reporter, роль которого заключается в отправке статистики ошибок и производительности на серверную часть.

  1. Основной объект wx содержит API под объектом wx. Но количество API здесь намного меньше, чем количество официальной документации по API.

Мы можем найти в коде, что API, зарегистрированный под wx, в конечном итоге вызовет метод WeixinJSBridge, этот метод. Его следует вводить сбоку при упаковке. Однако мы также можем найти определение этого метода в WAServeice.js.

Итак, мы пришли к выводу, что WAService.js — это код, используемый редактором для принятия обратного вызова метода wx.

  1. Объект wxparser обеспечивает операции сопоставления между объектами элементов dom и wx, а также предоставляет функции управления операциями элементов и управления событиями.

  2. Соединение является обработкой элегантных объектов, включая регистрацию глобальных событий Weixinjsbridge, реализацию алгоритма виртуального DOM, впрыск стиля и т. Д. Ввести важное содержание нескольких компонентов

Exparser.registerBehavior Зарегистрированная компонентное поведение базового компонента для наследства компонентов.

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

Здесь мы видим, что компоненты: wx-video, wx-canvas, wx-contact-button, wx-map, wx-textarea и другие поведения содержат атрибут «wx-native». Означает ли это, что такие компоненты нативно реализованы нативными? Мы включили пограничный досмотр и обнаружили, что такие комплектующие действительно являются родными комплектующими.

Подводя итог, можно сказать, что некоторые компоненты интерфейса апплета WeChat реализованы в нативных методах, а слой нативных компонентов находится над слоем WebView. Большинство из них по-прежнему реализованы с интерфейсом, что объясняет ошибку в апплете WeChat.

Поскольку scroll-view является интерфейсной реализацией и использует в ней нативные компоненты, отслеживать прокрутку невозможно.

WeixinJSBridge

Компонентам нужны данные для рендеринга. Глядя на документацию, мы знаем, что API для отправки запросов — это wx.request, из приведенного выше анализа мы знаем, что wx.request на самом деле вызывает WeixinJSBridge. Теперь смотрим на WeixinJSBridge

WeixinJSBridge фактически отправляет код для обработки запроса данных; если текущая среда — ios, то вызовите window.webkit.messageHandlers.invokeHandler.postMessage из WKWebview. Если среда Android, вызовите WeixinJSCore.invokeHandler (при вызове по умолчанию будет отображаться текущий идентификатор веб-просмотра).

WAService.js

В рассмотренном нами анализе WeixinJSBridge.js мы не обнаружили интерфейсной реализации связи, возможностей маршрутизации и иерархии привязки данных. При ближайшем рассмотрении был найден файл WAService.js. Просмотрите исходный код файла WAService.js:

  • В самом начале кода тот же модуль, совместимый с WeixinJSBridge, что и WAWebview.js

  • Затем есть модуль Reporter, который аналогичен WAWebview.js.

  • Более богатый модуль интерфейса wx, чем wx в WAWebview.js. (Остальное wx api здесь)

  • модуль appServiceEngine, предоставляющий интерфейсы Page, App, GetApp

  • Добавление интерфейса AMD требует определения объекта окна

Таким образом, основные функции, реализованные WAService.js:

  • App() запись апплета; Page() запись страницы

  • wx API;

  • Страницы имеют области видимости, обеспечивающие модульность

  • Привязка данных, распределение событий, управление жизненным циклом, управление маршрутизацией

Здесь мы приходим к выводу, что архитектурная схема апплета:

Весь апплет состоит из двух веб-представлений, а код разделен на уровень пользовательского интерфейса и уровень логики. Уровень пользовательского интерфейса работает в первом WebView, выполняя операции DOM и реагируя на интерактивные события, которые содержат код WAWebview.js и скомпилированное содержимое. Слой логики выполняется (во втором веб-представлении) в отдельном движке JS (iOS: JavaScriptCore, android: анализатор JS X5; совместно именуемые JSore; инструменты разработки, ядро ​​nwjs Chrome), код WAService.js и бизнес-логика.

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

Обсуждение архитектуры

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

Поискав в интернете, нашел действительно один проект, использующий эту архитектуру: куда перейти на последний фреймворк YIS

YIS использует небольшую программную архитектуру, которая разделена на логический уровень и уровень пользовательского интерфейса. Слой пользовательского интерфейса работает в WebView, а уровень логики — в отдельном движке JS. Соответственно, код всего приложения также разделен на две большие части, одна часть выполняется в WebView, а другая — в JS-движке. Механизм JS вычисляет структуру DOM и выводит ее в WebView, а WebView перенаправляет событие щелчка пользователя в механизм JS.

Подход этого проекта очень похож на подход Xiaocheng, единственное, чего не хватает, так это отсутствия нативных компонентов. Однако в официальной документации введения нет.

некоторые взгляды

Традиционное отображение веб-страницы должно пройти несколько этапов:

  • инициализация веб-просмотра

  • Загрузить HTML, CSS, JS

  • Скомпилировать JS

  • Расчет рендеринга

  • DOM Path

После использования архитектуры апплета мы можем разобрать описанный выше процесс на две части для параллельного выполнения: часть веб-просмотра:

  • инициализация веб-просмотра

  • Загрузить HTML, CSS, JS (после разделения сильно уменьшается объем)

  • Скомпилировать JS

  • Дождитесь данных, которые нужны странице

  • десериализовать данные

  • Выполнить патч

  • визуализировать страницу

  • жду больше новостей

раздел jscore:

  • инициализация

  • Загрузите код фреймворка js

  • скомпилировать js

  • Загрузить код бизнес-логики js

  • скомпилировать js

  • Рассчитайте виртуальную структуру DOM выше сгиба

  • сериализовать данные, передавать

  • Дождитесь сообщения веб-просмотра или собственного сообщения

Таким образом, процесс рендеринга и логический процесс разделяются и обрабатываются параллельно: скорость рендеринга первого экрана увеличивается, при однопоточной модели время работы js слишком велико, а UI зависает. Он полностью управляется данными, не может напрямую манипулировать DOM и избегает низкокачественного кода. webview и jscore могут предварительно

Конечно, у этой архитектуры есть и некоторые недостатки:

  • Не может гибко управлять DOM и не может добиться более сложных теплых эффектов любви.

  • Некоторые представления, связанные с NA, имеют ограничения на использование, например, в прокрутке WeChat не может быть текстового поля.

  • Размер страницы, количество открытых страниц ограничены

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

использованная литература

  • Каков принцип реализации нижнего уровня апплета WeChat?

  • Анализ архитектуры апплета WeChat, анализ принципа работы

  • Анализ архитектуры мини-программы WeChat

Об авторе этой статьи: @田光宇 Исходный текст: http://eux.baidu.com//blog/fe/Принцип архитектуры апплета WeChat

Наконец, EUX поделился:

[Выпуск 1078] Вырезать Вырезать Вырезать Вырезать в передней части

рекомендуется вам:

[Ошибка 1382] Потихоньку раскрывает тайну WebAssembly

【Выпуск 1380】Как думать как программист — Опыт решения проблем