Ведущий: Думаю, многие слышали о 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,Следите за обновлениями.
использованная литература
- Введение в веб-сборку
- Загрузите и запустите код WebAssembly
- Практика WebAssembly в почтовом ящике предприятия
- Загрузите и установите — Документация Emscripten 1.38.38
- Узнайте кое-что о WebP
- проект с открытым исходным кодом libwebp
Личный публичный аккаунт: Оценка фронтенд-разработки