Pull to refresh

Comments 73

UFO just landed and posted this here

Тут нужно понимать, что это непродашнреади решение. Тут нет заморочек с кэшированием модулей, сжатием файлов и сокрашения размера бандра (Особенно для wasm-модуля).

Размеры бандлов:

  • shell = вендоры (~1Mb uncompressed) + код (~55Kb uncompressed)

  • react_counter = вендоры (~140Kb uncompessed) + код (~70Kb uncompressed)

  • yew_counter = wasm (~2.4Mb uncompressed = 600Kb compressed) + обвязка (130Кb uncompressed)

А как это по скорости, выигрыш есть хоть какой-то, если сложный ui интерфейс?

Что имеется ввиду под сложным кейсом (для всех он разный) ?

Могу привести личный пример. Я неболшой дробдаун, по скорости особых просадок незаметил, единственный момент может вырасти время первой загрузки модуля, даже если он ассинхронный. Но это все решается кэшированием и прогоном через компилятор в более строгом режиме.

Нужно понимать, я использовал такоей пример не для того, чтобы показать какой WebAssembly быстрый. А скорее, что он на нем можно решать не только задачи связанные со сложными алгоритмами, но и верстать UI. К тому же, Rust-имеет более надежную систему типов чем TypeScript, что может помочь в обнаружении ошибок.

По моему достаточно четко сформулировал вопрос.

Могу детализировать, например это таблицы котировок ставок на сайте букмейкера, которые обновляются раз в секунду. Согласитесь, это не дропдаун замерять на производительноcть :)

Спасибо за уточнение:)

Приведенный вами комплект очень сложный и написать его производительную версию бывает не просто, используя React.

Что на счет Yew. Фронтенд на Yew обещает быть эффективным, но в данном примере утверждать не могу Могу предложить посмотреть на что-то отдаленно похожее в yew-examples.

Я в проде еще не использовал фронтенд на Yew или любом другом фрецмворке/библиотеке на WebAssembly поэтому такого детального опыта у меня нет. Посоветовал спросить у pkirill, он более подробно может сказать о производительности WebAssembly в таких сложных сценариях :)

Код на низкоуровневом языке компилируется с помощью мощных компиляторов (например, Emscripten) и превращается в бинарный формат

Emscripten это же не компилятор, компилятор там llvm. Emscripten это набор библиотек напоминающих stdlib + обвязка на JS упрощающая.

Полностью с тобой согласен. Ты более подробно раскрыл:)

Я пишу фронт на java (sudu-editor), и там у меня тоже есть примеры интеропа с Wasm, но я там не использовал ни обвязок ни библиотек emscripten. В целом это опционально. А без компилятора никак

Круто, что ты заметил такой глубокий нюанс:)

После твоего комментария так и чешутся руки поправить текст

На счет emscripten и его библиотек, и опционального использования сильно не углублялся. Спасибо что подсветил.

На сколько я помню в Yew тоже можно от него оказаться. Но у меня были сложности с встраиванием его как микрофронтенд. Поэтому решил не заморачиваться.

Можно писать фронт на java?

Спасибо. Ща заценим. Если будут вопросы, отпишусь.

Если это работает, то зачем тогда jetbrains продвигает KMM (kotlin multiplatform) ?

kotlin multiplatform - это только про ui.

WebAssembly намного шире. Возможно использовать библиотеку для криптографии или обработку видео. И можно это писать на разных языках. Плюс это стандарт. Он поддерживается и развивается несколькими браузерами, а котлин зависит только от jetbrains.

Не только. Как раз в первых версиях предлагалось писать только data слой кроссплатформенный, а ui - нативный каждый под свою платформу.

Теперь вроде бы можно на Compose (jetpack compose) писать Ui и для iOS.

Есть open source проекта на wasm, покрывающий мобилки+десктоп+веб ?

Но кстати про отдельный слой не знал, видимо потому что не пишу на Java или Kotlin:)

В любом случае все кейсы покрыть нет возможности.

Tairu может покрыть все платформы.

electronjs может покрыть десктоп.

Если пишешь на react, то с некоторыми особенностями можно тоже все платформы покрыть.

Можно даже сделать проще написать pwa приложение и оно будет работать на всех платформах.

Вариантов сделать одно и тоже сейчас очень много. Но лучше использовать тот, который не зависит от одного вендора.

Чтобы посмотреть на production решение и почитать код. Понять насколько легко или сложно вести такой проект

Имеется ввиду проект, который собирается под несколько платформ?

Тут зависит от того не чем его писать. Я так понимаю на Java?

Я могу рассказать зачем. Я в JB работал 10 лет. Но это очень долго. Например затем чтобы нельзя было использовать java. Kotlin не совместим с java: категорически нельзя использовать java в KT native или в KT JS. Понятно чтобы продвигать KT. Автор TeaVM тоже там работал :) но как узнал "политику" партии ушёл. Т.к. у него было желание сделать именно компилятор из байт кода, но это не совместимо с политикой KT.

А какова эта политика? Сразу транслировать в ассемблер платформы? Это специально, чтобы нельзя было совмещать с java и сделать такой вендор Лок?

Просто я как разработчик устал уже от всех этих новых модных штук(часто не доделанных, где чтобы сделать хелловорлд надо попотеть)

эта политика чтобы больше покупали IDEA

А вот в чем дело!

Тогда хотелось бы узнать, а что использовали из модных штук?:)

Хочется узнать об опыте)

Это специально, чтобы нельзя было совмещать с java и сделать такой вендор Лок?

Именно так

Я на самом деле копаю ещё глубже, я делаю такой фронт чтоб работал и на десктопе и на айфоне, везде. Просто писать фронт под DOM сильно проще.

Можете скинуть пример , может из вашей IDE. Посмотреть

Может чтобы не сильно копать, ссылку на какой нибудь типичный код в проекте скините??

Да там он там весь типичный :)

компилятор там llvm

Не холивара ради а точности понимания для. llvm - вроде как платформа для создания компиляторов, а не сам компилятор. Вот у меня смотрю - компилятор clang на MacOS, возможно это опция и у вас другой.

Да, там тоже clang, но другой. :)

Это clang от llvm.org, а у вас от Apple.

У меня 3 clang, получаетя:

  1. /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang

  2. /usr/local/Cellar/llvm/17.0.5/bin

  3. /Users/user1/emsdk/upstream/bin

Третий, как я понимаю, как раз от emscripten.

2 и 3 это одно и тоже

clang в emscripten это просто релиз от llvm.org, тот что второй тоже умеет собирать Wasm таргеты

В том смысле что для того чтобы собирать WASM таргеты именно clang входящий в emscripten не является обязательным условием, стандартный clang от llvm.org поддерживает WASM из коробки. emscripten - это именно набор библиотек и генератор обвязки JS, напирмер в нём реализован "void * operator new(unsigned);" и.т.д. Но и генереная обвязка JS тоже не есть обязательное условие, я например, на java декларирую API WASM модулей.

Например вот https://github.com/SuduIDE/sudu-editor/blob/master/wasm-test/src/main/java/org/sudu/experiments/demo/wasm/WasmTest.java#L19

Недостатки

? Исполняется в основном потоке

Webassembly прекрасно исполняется и не только в основном потоке, а так же на любых других (Worker) потоках.

Да, я тут не стал добавлять про использование Worker’ах. Я имел ввиду то, что он конкурирует с исполняется в одном потеке с JavaScript, если ничего с ним не делать.

Ну понятно что вызов синхронный, как и обратный вызов JS из Wasm. Все в одном стеке

Да, я тут именно это и имел ввиду. Скорее опирался на новые веяния фронтеда. Если кто-то пишет про Worker’ы сразу указывает, что он у отдельном потоке исполняется и вызываться с JS с помощью механизма сообщений.

Извините, никак не могу понять? Какой смысл использовать Rust поверх среды со сборщиком мусора, если главная идея создания Rust - это эффективная и безопасная работа с памятью, благодаря эффективному использования стека (по сравнению с java/Javascript, алоцируя объекты/структуры прямо на стеке) и контролю жизненного цикла с помощью компилятора (по сравнению с C++)

Или wasm rust всё-таки может работать с памятью как обычно, но внешние JS объекты не пытается контролировать?

Давайте разбираться:)

Если мы говорим об эффективновности кода, то за нее отвечает среда запуска WebAssembly (в данном случае это браузер) и компилятор, с помощью которого код был скомпилирован в WebAssembly).

Если мы говорим о жизненном цикле (выделени и освобожении памяти) при написании кода, то тут ничего не меняется, если вы пишите на Rust.

Если мы говорим об его контроле памяти во время то тут в дело вступает WebAssembly. Благодаря устройству ее WebAssembly может эффективно читать и писать только в выделенную ему память. Это позволяет единственному web-приложению использовать множество
независимых библиотек (использующих WebAssembly) которые могут иметь
отдельные и полностью изолированные друг от друга диапазоны памяти. Подробнее тут.

Если мы говорим об управлению стеком. То особенность формата WebAssembly как раз в том, что этот формат стековый. Внутри рантайма, который запускает и исполняет WebAssembly стек свой и управление и выделение памятью происходит отдельно для JS кода со сборкой мусора и для WebAssembly.

Смыл использовать код на С, С++, и Rust огромный. Например переиспользование библиотек

Я пишу клиенту много кода на c#. Клиент захотел еще себе веб-страничку маленькую сделать и я переиспользовал уже написанный код в веб-страничке, используя Blazor, который в wasm собирается. Бонусом мне не приходится выходить из привычной среды и не приходится использовать JS

По-умолчанию JS-код JITится под капотом во всё тот же wasm и делает всякие оптимизации а ля вызов типизированных вариантов функции. Но, с некоторой вероятностью может случиться деоптимизация и код будет интерпретироваться как обычно. Чтобы не ждать результатов JIT и иметь некоторый стабильный уровень производительности вы можете сразу сделать оптимизированную версию. Rust в этом случае просто как один из самых приятных вариантов написания кода - строгая типизация, алгебраические типы, одна из передовых инструментариев и вот это вот всё. Есть варианты писать на более специализированных AssemblyScript или Moonbit, например.

С точки зрения Rust управление памятью остаётся каким и было изначально - была у вас статичная инициализация всего и вся - в wasm так и будет; были арены - будут и в wasm. GC в раст особо никому не нужен был, но если вы его сделаете, то и в васм он тоже будет, если повезёт. В остальном wasm ведёт примерно также как и нативный код.

Интероперабельность с JS происходит через импорты и копирование строк просто потому, что wasm ничего не знает про API JS. Несмотря на это производительность местами получается более стабильной нежели на чистом JS. в работе есть некоторое количество вариантов типизированного ABI для wasm, что по идее сократит несколько накладные расходы, но они пока ещё в процессе.

Утверждается, что скорость выполнения близка к нативным приложениям... Где можно посмотреть сравнение, например с плюсами? По моему пониманию минимум в 2 раза медленнее, т.к. все равно нужно транслировать бинарный формат в инструкции процессора?

Скорость очень хорошая

все равно нужно транслировать бинарный формат в инструкции процессора

Это, конечно, надо, беэ этого сложно. Но надо отдать должное что WASM именно так изначально проектировался чтобы эта трансляция была очень очень быстрой, в отличие от трансляции JS.

И в трансляция идёт тоьлко 1 раз на загрузке модуля, а потом модуль исполняется уже продолжительное время и никакой трансляции там уже нет.

PSPDFkit приводит "интересное" сравнение производительности JS и WASM...
Цитирую:
Примечательно, что в Edge и Safari из-за отсутствия некоторых важных оптимизаций тест WebAssembly выполнялся дольше, чем аналог на JavaScript. Производительность WebAssembly и JavaScript в Chrome отличается незначительно. Наибольшая разница в скорости выполнения тестов WebAssembly и JavaScript зафиксирована в Firefox. При тестировании выполнялись различные процедуры обработки PDF-файлов и замерялось как производительность непосредственного выполнения операций, так и суммарное время с учётом загрузки и компиляции псевдокода WASM.

Т.е. сильно зависит от браузера, точнее его VM.

Таки не так всё красиво с WASM...
Про "нативную" скорость лучше помолчать.

Все зависит от ... :)

Для JS поведение браузеров тоже может разнится в некторых специфических случая. Нативная скорость плучается не всегда. Поэтому и указано близкую к нативной. Безусловно есть свои особенности и у исполения WebAssembly.

Тут идет речь скорее про то, что VM старается приблизить программу на нативном языке в исполняемый модуль WebAssembly. А не про то, что она всегда будет нативной и быстро исполнятся.

Максимальная производительность WebAssembly равна максимальной производительности
JavaScript, но написать оптимизированный по памяти код иногда проще на
WebAssembly

В статье есть важное дополнение. Я бы посоветовал вам почитать статью про использование WebAssembly и сравнение скоростей . :)

Доступ к DOM и Browser API. WebAssembly напрямую не может обращаться к DOM или браузерному API. Все вызовы API внутри Wasm происходят через JavaScript (компиляторами добавляется специальная прослойка для исполнения JavaScript-кода).

Это да, но зачем писать это в достоинствах? Вот, наоборот, доступ к DOM напрямую, избегая связанных с JS накладных расходов - это было бы достоинством. А так это выглядит примерно как лет 30 назад вылядела бы фраза про Windows: "Программы на Pascal и C не могут обращаться напрямую к WinAPI. Все вызовы WinAPI внутри Pascal/C присходят через среду выполнения Visual Basic (компиляторами добавляется специальная прослойка для исполнения кода для этой среды)".

IMHO правильное наименование этому решению - компромис: между вохможностью доступа к DOM вообще и безопасностью/трудоемкостью реализции интерфейса доступа.

PS А вообще я уже видел в жизни попытки реализовать работу в браузере программ на других языках, компилируемых в JavaVM bytecode (Java Applets) и .NET IL (Silverlight) - не то, чтобы они закончились совсем уж провалом, но, в целом, не взлетели. Но шуму вокруг было не меньше.

В достоинства я это добавил потому, что есть возможность обращаться к DOM и браузерному API. К примеру, если мы бы брали Worker’ы, то они не могут работать с DOM, а браузерное API у него доступно не все. Да с хаками, но можно это главный посыл был. А про связь с JS для общего понимания, чтобы читатели, не знавшие об этом сразу понимали текущую картину.

IMHO правильное наименование этому решению - компромис: между вохможностью доступа к DOM вообще и безопасностью/трудоемкостью реализции интерфейса доступа.

Да, безопастность одно из главных причин. Я думаю, что именно поэтому сейчас есть возможность доступа только через JS. Плюс для запуска все равно нужен JS. Поэтому без накладных расходов никак.

PS А вообще я уже видел в жизни попытки реализовать работу в браузере программ на других языках, компилируемых в JavaVM bytecode (Java Applets) и .NET IL (Silverlight) - не то, чтобы они закончились совсем уж провалом, но, в целом, не взлетели. Но шуму вокруг было не меньше.

Очень интересное замечание. Есть много причин почему они не взлетели и почему может не взлететь WebAssembly. Вы будто правило расшифровали цитату, которую я оставил в конце:)

почему может не взлететь WebAssembly

С моей точки зрения WebAssembly уже взлетел и его отлично применяют. А Java Applets и Silverlight не взлетели из за огромного числа дыр в безопастности, которые в WebAssembly изначально при проектировании были тщательно проработаны.

Ну а на замену Java Applets пришли отличные AOT компиляторы компилирующие приложения в JS: https://habr.com/en/articles/240999/ (а с тех пор это всё очень сильно развивается, почти 10 лет прошло)

Еще есть отличная статья про WebAssembly от автора TeaVM: https://habr.com/en/articles/757182/

Я в этой технологии новичок и не могу знать все нюансы на данной момент. На как и в любой технологии все зависит от многого количества факторов. Да, Wasm сейчас развивается в семимильными шагами учитывая, что он разрабатывается как стандарт (перичеслять все плюсы еще раз не будут). Но тут вопрос скорее в дальнейшем развитии и стратегии. Если они будут добавлятья новые крутые фичи, возможно в ближайшее время не нужно будет использовать JS для запуска или писать кучу обвязок. Тогда его популярность значительно вырастет. Но нельзя не отметить что на данном этаме она достачно высока (список поддерживаемых языков достачно большой).

На счет статьи спасибо:)

Извините, телефон чудит

https://github.com/SuduIDE/sudu-editor/tree/master/wasm-test/src/main/java/org/sudu/experiments/demo/wasm

Обвязок вроде немного. Но кажется, что есть скрытые хитрости в org.sudu.experiments:)

Где найти все что лежит в org.sudu.experiments ?

Поверь, никаких хитростей, всё в репе, всё там, всё open source

Я правильно понимаю, что все это обвязка для org.teavm ?

Ну да это же java код для веба. Но на JS этот самый пример не будет больше, скорее даже сильно меньше

Я не очень разбираюсь в синтаксисе Java. Поэтому исходники этой либы изучать не полез. Подскажи, во что он перегоняет Java? В строки или в более сложные структуры?

В JS. Так же как и TS compiler перегоняет TS в JS

То есть по сути вся обвязка превращается в JS. А есть пример архитектуры? Очень интересно как связывается с модулем на wasm конкретно в Java

Вот эта репа - самый отличный пример. Там очень понятный readme как собрать. Ещё немного примеров в репе самого teavm. Посмотрите мой доклад, там с пояснениями и картинками

https://youtu.be/QHbYXDobo3k?si=81ZNJleJ4nNuGI1u

Спасибо, сохранил для просмотра:)

Но тут вопрос скорее в дальнейшем развитии и стратегии.

Прям вот сейчас там около десятка пропозалов - гц, интерфейс типы, мультитрединг и синхронизация, SIMD не так давно появился в основных браузерах без флагов, WASI описывается/стандартизуется.

Есть вот такой FAQ в котором есть нужные ссылки по теме. Они маленько устарели и актуальные где смотреть не подскажу.

Есть список пропозалов.

P.S. Оказывается в хроме уже появился GC.

Сейчас он широко распространяется в отрасли и поддерживается многими языками, в том числе и со сборкой мусора (Garbage Collection). Совсем недавно поддержка стандарта появилась в Google Chrome и Mozilla Firefox.

Да это я уже указал в статье :)

Остальные поизучаю, спасибо)

А Java Applets и Silverlight не взлетели из за огромного числа дыр в безопастности, которые в WebAssembly изначально при проектировании были тщательно проработаны.

Утверждение мне кажется сомнительным, поскольку безопасность (сама по себе, вне контекста рекламной раскрутки) ценится на рынке невысоко ("безопасность народу не нужна").
Скорее, IMHO неуспех предыдущих попыток (куда, кстати, можно ещё добавить и Flash) был вызван тем, что они не слишком много добавляли ценности сайтам интернета, создаваяпри этом определенные неудобства, связанными с необходимостью дополнительной установки компонентов.
По крайней мере, этой добавляемой ценности не хватало, чтобы преодолеть сопротивление конкурентов того производителя, который их продвигал.

А вот вокруг WebAssembly сложился консенсус основных поставщиков технологий, поэтому его ожидаемая судьба лучше, да.
Но все-таки IMHO прямой доступ к отображаемому (DOM) позволил бы предоставлять ещё больше ценности.

С моей колокольни было бы круто иметь доступ к WebGL например. И там по сути даже не нужны JSObjects, там по факту везде int типы (см Angle)

Ну а доступ к дому очень сложен, там есть доступ к JS объектам, а их лучше держать подальше от wasm

На а количество дыр и лазеек в Java Applets было огромное. Сам работал в Sun Microsystems :)

Хорошо что это изгнали из веба

Sign up to leave a comment.