最近在迁移公司 C/S 架构程序( C++、三维软件),想往浏览器端迁移,目前正在施行的方案是用 emscripten 编译的 webassembly 模块。公司程序用了大量的三方库比如:gdal 、ffmpeg 、opengles ,三方库又依赖了大量其他的库,比如 gdal 依赖了 geos 、proj 、curl 、libtiff 、sqlite3 等。因此编译采用的是静态链接,即所有.a 最终生成的是一个.wasm 文件。我这里基本用了最新的版本,以防对 webassembly 缺乏支持。那么问题来了:问题 1:基于如此巨量的三方库以及自有实现代码,这个 wasm 文件会很巨大(百兆体量),浏览器能加载的出来吗,或者此种体量是否规范?问题 2:据说 webassembly 使用内存上限有限制,大概 4GB ,有方法能突破限制吗?我司程序就是个吃内存的家伙问题 3:如此多的三方库,是要一个个验证能否在浏览器上运行测试用例吗?还是说只要经过 emscripten 编译过,就基本认定在浏览器端运行基本没有问题?问题 4:性能衰减问题,大概是多少体量,自我感觉能效不高,怕迁移完毕卡成狗。

有层想表达的意思是:C++代码使用标准库、使用 pthread 、使用脱离系统 api 的方式,使用 wasm 内置文件系统,首先能正常运行在 windows 、linux 下,那么用 emsctipten 编译出来,是否就意味着无需验证,也能运行于浏览器?按照我的理解,一旦 C++内部编译成功,无关运行平台,运行结果也是能正常

我这里就是单纯用 C++技术,实现能在浏览器端运行起来的不带界面的三维图形程序,前端技术基本不考虑,这个交给前端二次开发人员调用我们提供的接口来实现。我们和前端唯一交互就是暴露的接口,键鼠我们已经内部抱走

这...图啥啊

只能说客户端被浏览器蚕食的太厉害了

搞个简单版本运营看看咯

emscripten 对很多库支持并不好,比如 curl 就不太好编译。wasm 只适合中等偏小的软件,运行巨型商业软件够呛,代码估计要大改。

curl 我编出来.a 了,gdal 也编出来了,但之前公司用的 opengl ,要改 opengles ,因此目前还跑不起来,所以趁机问问。

性能损耗应该是比较严重的,ffmpeg 是一个计算密集型的应用,wasm 版本的 ffmpeg 在转码方面,有时候只有 10%的速度。

那你比较厉害,正常来说 curl 用的是标准 socket ,这在 wasm 浏览器里,都是不被支持的。我以前遇到的最大问题,是内存管理方面。emscripten 粘合层,用了一种很奇怪的方法处理 fopen/fwrite ,文件大于 2 百兆就有问题,反正很折腾。

4g 内存这个目前无解.我司的程序目前也是身受其害.

“只能说客户端被浏览器蚕食的太厉害了” 还是没有 Get 到真正的原因,公司是希望以后这块的软件都通过浏览器作为媒介来使用,因为它随时可用,方便快捷,不用下客户端?但假设你真正编译为了 wasm ,大小并不比原生应用小。当然,我只是作为旁观者提出的疑问😂。

我们这边做 Web 视频编辑器的,也是大量使用 wasm 场景,感觉这里问题提的挺好的。

另外对于产品设计方面,看到贵司的软件是 C++三维软件,我假设是一款生产力软件,作为用户,我用客户端在 PC 上使用,明显比在浏览器上使用更加放心😂。

#11 1. wasm 体积不能太大,会影响网页首屏时间,这个要压缩到 10 到 20m 左右,然后利用客户端缓存。所以不建议是所有功能都打包进来,只包括 js 或浏览器接口无法使用的功能会好一些。2.确实有3.验证挺麻烦的,我们也是限制了浏览器版本,比如 safari 无法访问,chrome 和 edge 特定版本以上之类的;4.项目劣化会挺明显,而且前端同学不懂 wasm 的话,很难优化,所以我们已经把很多功能都使用 js 实现一遍了,这样效果最好。

对于通用计算来说,性能可以认为是降低到 1/3~1/5 ; simd/gpu 加速的部分性能下降就更多了,至少降一个量级。

你司的三维软件是不是卖不出去??搞这幺蛾子

你 wasm 打包压缩了吗,压缩完还 100 多 M ?

mp.weixin.qq.com/s/1XmH55nqs7wavsWJNT-tSwB 站 有 ffmpeg 编译成 wasm 的案例, 并有相关 git 地址

wasm 其实是非常有用的, 服务器计算挪动到客户端计算,大大减轻了服务端的压力和资源消耗。

基本要大改,完全重写。

那一般情况呢, 1.大小问题可以通过进度条规避,毕竟大型软件,对加载时间可以有一定的宽容; 4.软件设计基本无需外部前端参与,完全由内部 C++暴露接口供外部调用,前端只需要做界面美化和接口调用的事,可以理解为我们提供了一个二次开发的 sdk

我司跟 3D 上 web 和他们一样,目前感觉也还好。不过我们主要使用 vtk ,代码确实进行了大量整改,就速度来说其实还好。可能我们功能没有他们那么复杂。当然 Ai 这些只有上云了。

说白了浏览器端二次开发者多,客户端二次开发式微了

这么严重么?看资料是原生的 1/3~2/3

#20 一般情况下,纯计算能力,wasm 效率能到 native 的 50%都够呛。毕竟 wasm 还是一个虚拟机,还得交给浏览器解释执行。而且现阶段 wasm 对于 pthread 的支持还是有点磕磕绊绊,很多开源项目的 wasm ,我看他们的处理方式是直接改成单线程保平安。

"那么用 emsctipten 编译出来,是否就意味着无需验证,也能运行于浏览器?"验证很简单,写个单元测试跑一下就行了。把对 wasm 的内心期望减半,再减半,就比较符合浏览器里运行的真实情况。

内存 4GB 的原因是因为编译到 wasm32 位的操作,最大就支持 4gb 内存,想要突破就只能使用 wasm64 位

编译到 wasm64 位就没有 4gb 内存的限制

00f.net/2023/01/04/webassembly-benchmark-2023/ 这有个通用计算的测试接近你的资料,平均下降到 43%,但是这是最快的 wasm 实现的结果。实际浏览器可能会再慢一些。 ffmpegwasm.netlify.app/docs/performance/ 这有个 Chrome+ffmpeg.wasm 的性能测试,平均下降到 8%,差了一个量级。

大佬,xorg-x11-server 和 openresty 有静态编译姿势吗

就算能跑,你觉得 serve 一个 100m 的 wasm 文件给浏览器合适吗?能编译到 wasm 的代码,可以认为就是可以运行的。但代码可以运行,不代表代码链接/调用的 API 也被支持。所以代码可以重用,其他都得重写。

提到 wasm ,我也有个问题:一个使用了 wasm 的网页,如果被 iframe 嵌入到另一个网页,还能正常访问到 wasm 文件并顺利运行么?

v8.dev/blog/4gb-wasm-memory

emscripten 文档上大量篇幅是讲 porting 和 optimizing webgl, 可见坑不少,祝楼主好运可能不是很恰当的例子,有些图形库说是支持 emscripten 编译,可是桌面上是调的 opengl4.6 ,用 emscripten 编译就使用 emscripten 自带的 gl 头文件了,如果你的 shader 不是针对 es 300 写的运行起来就挂了

github.com/WebAssembly/memory64/issues/42

我觉得你想把这些搬到浏览器运行之前,可以先考虑发几个版本的 electron 编译版试试水,能移植的移植,能改写的改写,再考虑浏览器。electron 也是完整浏览器,也能支持内置 wasm 以及原生从底层原生一步跨到纯浏览器 wasm, 步子太大,容易扯到蛋

成功的项目基本没有全程 wasm 的,线上大多数都是 web 界面加部分重逻辑重计算部分走 wasm 调用。当然也有类似的尝试,但我还没见过 full wasm 的商业产品。

没问题

我建议用 threejs 重现桌面版的 api ,然后再考虑 wasm 移植一些 c 功能。

改单线程不用 Webworker 遇到计算密集型不会卡死 UI 么

如果你引用的所有库都能直接源码级跨 Win/Linux 两个系统,那大概率直接用 emscripten 编译到 WebAssembly 是能用的。比如去年谷歌那边就说 SQLite 用浏览器的 OPFS 后端跑通了,但这样的库还是太少。

已有 webgl 产品线,我们这个属于 C++原生线,得弄些突破成果

好消息的三方库用的多,但方法用的又不多,纯属贪图其中某几个 API ,那感觉还有点戏

大佬细说,编译时加上什么标识呢

只要你的库有 configure 或者 cmake ,编出来应该不难啊

多线程这块用的是 C++标准库,实际内部调用走的还是 pthread ,初步实验感觉没什么问题

已针对性剔除 OpenGL ,改用 OpenGLES 友好子集,应该问题不大

感觉你要改设计,全部搬进 wasm 会崩溃的。建议 web 的版本先做简单的尝试,剥离最主要的功能,极简设计,看看效果。很多计算是不是可以用后端服务实现,这样不需要移植到浏览器上。

Google earth 网页版?

wasm 很多实现,有点扯,比如网络请求转移成 fetch , 太恶心了, 拿证书都拿不到,