Расширенная третья серия WebAssembly: апплет WeChat поддерживает решение WebAssembly от webP

WebAssembly

Ведущий: Думаю, многие слышали о Webassembly, которая объединяет несколько крупных компаний, таких как Google, Microsoft, Mozilla, Apple, которые запускаются на общем бинарном и текстовом формате для веб-ориентированности. Давайте шаг за шагом раскроем тайну Webassembly и лично применим приложение Webassembly в реальном бизнесе.

1. Введение

пройти через«Webassembly Advanced Series 1: что такое WebAssembly?»а также«WebAssembly Advanced Series II: где находится WebAssembly на этапе компиляции»После того, как эти две статьи получат глубокое понимание происхождения, преимуществ и применимых сценариев WebAssembly, следующим шагом будет проверка правды на практике.Давайте работать вместе, чтобы применить WebAssembly в сценарии апплета WeChat, чтобы среда апплета WeChat поддерживает декодирование формата webP ( Коллеги, которые не знают или не слышали о webP, просьба перейти на"Узнайте кое-что о WebP").

2. Рабочий процесс WebAssembly

Прежде чем мы начнем, давайте сначала разберемся, как загружать и запускать код WebAssembly: код или библиотека функций, разработанная на языках высокого уровня, таких как C / C++ / Rust / Java -> компиляция Emscripten -> файл wasm -> в сочетании с WebAssembly JS API -> запуск просмотра в среде сервера, как показано на следующем рисунке:

Проще говоря, компиляция внешнего процесса LLVM/Emscripten может получить файлы wasm и склеить js. Затем загрузите wasm через Glue js и преобразуйте его в формат arrayBuffer. Сразу после компиляции и создания экземпляра JavaScript можно использовать для связи с WebAssembly.

Подробный процесс и API, вызываемый каждым процессом, показаны на следующем рисунке:

3. Среда браузера поддерживает webP

После понимания рабочего процесса WebAssembly не ясно, с чего начать? Вы можете перейти на официальный сайт github, чтобы посмотретьпроект с открытым исходным кодом libwebp, Google полностью поддерживает компиляцию исходного кода libwebp в две версии wasm и asm.js. Для систем, не поддерживающих WebAssembly, или браузеров, несовместимых с WebAssembly, можно перейти на использование asm.js с небольшой потерей производительности. Конкретные этапы компиляции показаны на следующем рисунке:

После компиляции мы можем получить wasm-файл и склеить JS. Затем мы можем запустить локальную службу с помощью «python -m SimpleHTTPServer 8080», введите в адресной строке браузераhttp://localhost:8080Затем вы можете увидеть картинку после декодирования webP.

Наконец, давайте подытожим весь процесс.

(1) Скомпилируйте библиотеку декодирования libwebp с помощью инструментов LLVM/Emscripten/CMake, чтобы получить файлы wasm и склеить JS.

(2) Клей JS относится к памяти, а после компиляции, загрузки и создания файла WASM экспортирует объект модуля.

(3) Используйте метод WebpToSDL для объекта Module для декодирования webP и преобразования его в Canvas для рендеринга и отображения в браузере для представления конечного изображения.

4. Среда апплета WeChat поддерживает webP

Среды, которые мини-программы WeChat используют для выполнения скриптов и рендеринга компонентов, отличаются на Android/iOS.

В Android код JavaScript, запускающий апплеты, логический уровень микроканалаV8, слой представления рендерится саморазработанным движком XWeb на базе ядра Mobile Chrome 67, который, естественно, поддерживает формат webP; на iOS код JavaScript слоя логики апплета WeChat выполняется вJavaScriptCore, слой представления обрабатывается WKWebView, а ядро ​​браузера Safari не поддерживает формат webP.

Из содержания Раздела 3 мы знаем, что среда браузера уже может поддерживать webP, поэтому напрямую кидаем предварительно скомпилированный файл wasm и склеиваем JS в рабочую среду апплета WeChat, а затем запускаем его. Слишком молод, слишком прост!

Идея того, что среда браузера поддерживает webP, заключается в том, что libwebp декодирует webP -> рендеринг и отображение изображения холста jpg/png/gif, что изменило структуру исходного компонента изображения.

Компоненты, предоставляемые разработчикам апплетом WeChat, не могут изменять свою первоначальную структуру, поэтому другой способ мышления состоит в том, что libwebp декодирует webP -> данные rgb jpg/png/gif -> jpg/png/gif base64 -> возвращает в JS и назначьте его источнику изображения для рендеринга и отображения.

Ниже я перечислю некоторые ямки и точки оптимизации, встречающиеся во всем процессе, начиная от компиляции wasm-файла и склеивания JS с libwebp до его запуска через среду апплета WeChat:

(1) При компиляции CMakeLists.txt необходимо добавить параметр "-O3", что значительно повышает скорость компиляции.

(2) Параметр «-s USE_PTHREADS=0» необходимо добавить при компиляции CMakeLists.txt, поскольку браузер iOS Safari не совместим с общим буфером ShareArrayBuffer.

(3) Опция "-s ALLOW_MEMORY_GROWTH=1" должна быть добавлена ​​при компиляции CMakeLists.txt, цель состоит в том, чтобы решить проблему OOM при декодировании изображений webP сверхбольшого разрешения.

(4) Из-за совместимости среды апплета WeChat удаление кода, связанного с SDL, добавленного во время компиляции libwebp в JS-коде клея, может сэкономить около 100 КБ пространства.

(5) Удалите код, связанный с ENVIRONMENT_IS_NODE/ENVIRONMENT_IS_SHELL, в связующем JS, поскольку среда апплета WeChat не используется.

(6) Из-за проблемы совместимости браузера iOS Safari метод потоковой компиляции и создания экземпляров в Glue JS удален и заменен методом непотоковой компиляции и создания экземпляров.

(7) Поскольку WebAssembly не интегрирован с

(8) При компиляции CMakeLists.txt необходимо добавить параметр «-s USE_LIBPNG=1», чтобы скомпилировать библиотеку libpng.a, а затем преобразовать данные rgb, полученные декодированием webP, в данные памяти png с помощью библиотеки декодирования png, а затем преобразовать его в base64.Передать его в JS и, наконец, назначить его для изображения src для рендеринга и отображения. Сложность в том, что есть проблема на этапе преобразования данных памяти rgb в png, но wasm не может отлаживать код. Он может только отладить точку останова, создав проект VS libpng. Наконец, установлено, что data_size передан в когда rgb преобразуется в png, данные равны 0. .

(9) Когда новый код WebAssembly.Memory в Glue JS запускается в среде апплета WeChat, он сообщит об ошибке «отказано в создании объекта веб-сборки без 'unsafe-eval'», которая должна быть установлена ​​в CSP на странице- frame.html Добавьте unsafe-eval, чтобы решить эту проблему.

Пройдя через столько ям, я наконец могу поддерживать webP в среде апплета WeChat. Измеренная производительность WebAssembly превосходит JavaScript при декодировании webP в разных форматах и ​​разрешениях.

5. Пишите в конце

Хотя производительность декодирования WebAssembly намного выше, чем у JavaScript, она сильно отстает от производительности декодирования клиента, когда он сталкивается с webP с очень большими разрешениями (такими как 1920 x 1080 и т. д.). После всестороннего сравнения производительности и совместимости различных решений мы все же выбрали решение, основанное на пользовательском клиентском протоколе iOS webphttps.Общие шаги следующие:

(1) Во-первых, базовая библиотека апплета WeChat определяет, что, когда разработчик использует формат webP для компонента изображения, необходимо добавить заголовок webp, например webp, в источник изображения.example.png.

(2) Затем клиент перехватывает запрос webphttps через протокол NSURLProtocol и загружает соответствующие данные webP для декодирования.

(3) Наконец, декодированные данные изображения отправляются обратно в браузер для рендеринга и отображения.

В итоге мы завершили реализацию среды апплета WeChat для поддержки webP,Следите за обновлениями.

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

  1. Введение в веб-сборку
  2. Загрузите и запустите код WebAssembly
  3. Практика WebAssembly в почтовом ящике предприятия
  4. Загрузите и установите — Документация Emscripten 1.38.38
  5. Узнайте кое-что о WebP
  6. проект с открытым исходным кодом libwebp

Личный публичный аккаунт: Оценка фронтенд-разработки