首页 > 其他分享 >基于WebAssembly开发网页端

基于WebAssembly开发网页端

时间:2024-04-13 17:44:49浏览次数:26  
标签:WebAssembly 基于 网页 Qt no skip feature dev

基于WebAssembly开发网页端

来源  https://zhuanlan.zhihu.com/p/162082688

 

序言

Qt for WebAssembly,是Qt在2018年发布的技术,于5.12加入到Qt,官方对此技术介绍如下:

https://www.qt.io/blog/2018/05/22/qt-for-webassembly

简单的说,这是一个让Qt程序可以直接跑在web中的一个方法,具体流程如下:

使用Emscripten作为platfrom静态编译Qt工程,把整个工程和Qt环境打包编译成wasm可执行文件,配合html套壳一起加载到浏览器中,然后浏览器会提供一个虚拟化环境运行wasm,程序运行起来后所有的图形结果通过一个canvas输出。

相比之前WebGL技术这样的远程运行技术,这一次WebAssembly是真的把Qt程序跑在了浏览器本地上,实现了性能,效果的保证。总体靠谱得多。

关于WebAssembly详细描述和资料,这里不再累述,请直接参考Qt官方文档:

如果你想真的通过WebAssembly开发程序,我也建议务必看完以下链接里所有资料,这会帮你节约很多时间

https://wiki.qt.io/Qt_for_WebAssembly

https://www.qt.io/cn/blog/2019/01/18/getting-started-qt-webassembly

https://www.youtube.com/watch?v=W3WC-VpKdGQ&t=1319s

作为一个面世2年的技术,这项技术已经被多位前辈介绍,但是大多都是草草带过没有涉及很多细节,因此本文会相对整体介绍,看完本文后可以构建一个比较满意的工程。


环境准备

系统:Ubuntu 18.04 64bit

注:我是在虚拟机里面安装的是原版系统,并且进行了常规更新(update/upgrade),我建议为了避免奇怪的环境问题,尽量使用虚拟机安装环境,虽然Qt支持Windows和macOS下使用WebAssembly,但是我不建议在这两个系统下操作。

注2:请不要过多担心系统问题,因为编译后的产物例如wasm、html,都是跨平台的,无所谓是通过哪个系统编译出来的。

Qt源码:qt-everywhere-src-5.14.2.tar.xz

源码下载地址:http://download.qt.io/archive/qt/5.14/5.14.2/single/

环境配置参数

sudo apt-get install vim git

sudo apt-get install gcc g++ make libgl1-mesa-dev libglu1-mesa-dev libssl1.0-dev

sudo apt-get install libssl-dev

sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libxkbcommon-x11-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev

sudo apt-get install python

sudo apt-get install openjdk-8-jdk

Emscripten配置

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
git pull

./emsdk install sdk-fastcomp-1.38.30-64bit
./emsdk activate sdk-fastcomp-1.38.30-64bit

source ./emsdk_env.sh
em++ --version

注:Emscripten和Qt是有版本对应关系,版本不匹配可能导致编译失败以及运行时奇怪问题,具体对应关系请参考本文开头发的参考链接。我使用的Qt5.14.2配套Emscripten1.38.27Emscripten1.38.30

注2:source ./emsdk_env.sh是每次打开终端后必须执行的,他会初始化Emscripten环境

Qt编译参数

xz -d ./qt-everywhere-src-5.14.2.tar.xz
tar -xvf ./qt-everywhere-src-5.14.2.tar
cd qt-everywhere-src-5.14.2

./configure -prefix ~/Develop/qt5.14.2_web -confirm-license -opensource -xplatform wasm-emscripten          -nomake tools -nomake examples -nomake tests -skip qt3d -skip qtcharts -skip qtdatavis3d -skip qtdoc -skip qtgamepad -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtremoteobjects -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qttools -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebview -skip qtwinextras          -no-feature-accessibility -no-feature-appstore-compliant -no-feature-big_codecs -no-feature-calendarwidget -no-feature-colordialog -no-feature-d3d12 -no-feature-filesystemwatcher -no-feature-fontcombobox -no-feature-fontdialog -no-feature-ftp -no-feature-imageformat_xbm -no-feature-lcdnumber -no-feature-library -no-feature-multiprocess -no-feature-pdf -no-feature-printdialog -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-qml-debug -no-feature-qml-devtools -no-feature-qml-worker-script -no-feature-qml-xml-http-request -no-feature-quick-designer -no-feature-sha3-fast -no-feature-sharedmemory -no-feature-socks5 -no-feature-udpsocket -no-feature-whatsthis -no-feature-wizard -no-feature-xml-schema -no-feature-xmlstreamwriter

make -j6
make install

注:我的配置参数特别长,因为我对Qt进行了裁剪,这个裁剪能缩减大约1mb的wasm文件体积,如果你觉得没必要可以去掉-no-feature开头的那批参数

注2:相比编译桌面版Qt,WebAssembly版的Qt程序HTTPS请求依托浏览器环境,因此这里不需要配置ssl相关参数。也就是说编译时不需要配置ssl环境就可以用HTTPS

使用

若一切成功,依次执行qmake -vem++ -v应该可以看到以下信息


编译工程

和编译普通Qt工程一样,切换到源码目录,直接执行这2个命令就行了

qmake
make -j3

但是因为WebAssembly和静态编译原因,编译会特别慢,一个简单的工程会需要编译几分钟,这里耐心等待就行了

编译好后,我们一共需要从工程目录中提取5个文件,如下:

注:我的工程名为test

qtloader.js
qtlogo.svg
test.html
test.js
test.wasm

其中test.jstest.wasm是对应Qt工程的主要产物,每次Qt工程重新编译后都要更新这2个文件,这两个文件也不建议进行二次修改,直接用就行了。

如果要对页面进行美化,直接修改test.html就行了

因为不支持直接从文件打开,所以如果要对页面进行访问,最简单的方法就是用python开启一个web服务器

python3 -m http.server

然后在浏览器(例如Ubuntu自带的火狐)中直接打开http://127.0.0.1:8000/test.html就能看到程序了

我这里有一个已经挂在网上的WebAssembly程序,可以直接打开看下效果

https://web.jasonserver.com:10035/test/test.html


优化

截止上一步,一个简单的web程序就构建完成了,但是我们还有几步完善过程要走

中文字体裁剪

目前Qt for WebAssembly这边有一个缺陷就是无法使用浏览器或者说客户宿主机的字体,简单的数字和英文Qt有处理可以显示但是中文全部是小方块。根据静态编译的思路我们也不太会把整个中文字体都打包到资源文件里,毕竟中文字体基本都10mb+,就算打包进去加载速度也会被大幅度拖慢。因此我们需要对字体进行裁剪,我使用的是一个在线裁剪工具,配合常用2000字汉字表。

https://font-subset.disidu.com
https://wenku.baidu.com/view/3d2bd02b453610661ed9f40a.html

注:如果百度不让你复制,一个最简单的破解方法就是打开页面后禁用页面JS,然后再复制,就行了

我裁剪了SourceHanSansCN-Medium字体,裁剪前10mb+,裁剪后才300多kb,打包进资源文件完全可以接受

然后如果要在Qt里支持这个字体,在main函数里增加一行代码就行了

QFontDatabase::addApplicationFont( ":/SourceHanSansCN-Medium.subset.otf" );

压缩

为什么要压缩,因为wasm文件真的有点大。我这里一个简单工程编译出来就有18.2mb,这个对于一个web而言有点大了,在实际网络环境中可能需要10秒左右才能加载完成。

至于如何压缩,这个东西就有点坑了,最初我不熟悉web的压缩体系看了半天没看懂,只看官方说可以压缩却没说怎么压缩,最后才知道这个是WebServer自带功能,不需要开发者手动压缩

比如说我们可以使用nginx部署web,在nginx配置文件中配置开启glib压缩,我的配置如下:

gzip on;
gzip_min_length 32k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 3;
gzip_types text/plain text/css text/xml application/xml application/json text/javascript application/javascript application/octet-stream;

然后这个压缩就全自动的完成了。

大致流程就是浏览器在请求资源文件的时候会说明自己支持的压缩方式,然后服务器如果可以匹配到这个压缩方式就会压缩好数据再返回给浏览器。

可以看到开启glib压缩后,18.2mb下降到了7.3mb,还是比较可观的,缩减了几倍的网络传输消耗

如果追求更高压缩率可以使用brotli,本文不再介绍。注意这个压缩方法不是每个浏览器都支持,比如说Safari就不支持

ico

ico这个东西很多地方都用得到,web这里需要一个favicon.ico建议还是准备下

ico建议弄多分辨率版本,推荐工具gfie

我在html中配置ico方式为:

<link rel="shortcut icon" type="image/ico" href="favicon.ico">
<link rel="apple-touch-icon" href="favicon.ico">
<link rel="icon" type="image/ico" href="favicon.ico">

PWA

现在Web已经可以做的和应用程序一样,在桌面有一个小图标,进入后只有本身的页面没有浏览器框架,这依托于PWA标准

具体参考如下:

https://developer.mozilla.org/zh-CN/docs/Web/Manifest

简单的说这里只要一个manifest.json配置文件,我的配置如下:

{
    "name": "Test",
    "short_name": "Test",
    "start_url": "test.html",
    "display": "standalone",
    "background_color": "#000e27",
    "theme_color": "#000e27",
    "description": "Qt for WebAssembly Test",
    "icons": [{
      "src": "favicon.ico",
      "sizes": "256x256 64x64 48x48 32x32 24x24 16x16",
      "type": "image/x-icon"
    }],
    "related_applications": [{
      "platform": "web"
    }]
}

iOS状态栏修改

虽然我们有了PWA,但是iOS这边还是有一些私有标准需要单独写html兼容,我的配置如下:

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes"> 
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

问题

目前来说Qt for WebAssembly还是有一些问题,这作为一个成长中的框架和平台我们是接受的,在我测试中我注意到几个主要问题,还是有必要单独说下,这些问题理论上在将来都会慢慢解决,希望能尽快了。

多线程

目前多线程支持是几乎没有的。为什么说几乎没有是因为在一些组合下还是可以用多线程,但是限制特别多,例如要挑浏览器,以及对参数有特别要求。这对于web这样一个高兼容性的设计多少有些背道而驰。

移动端兼容性

我尝试了几个安卓手机,自带的浏览器以及一些第三方浏览器都不支持WebAssembly技术,因此根本无法打开页面。但是微信里面自带浏览器却可以打开。总的来说在安卓上兼容性比较差。

但是iOS没有这个问题,基本上所有浏览器都支持。

High-DPI

在桌面浏览器平台High-DPI缩放没有问题,但是在iOS上和部分安卓上缩放是异常的,具体的bug我已经反馈给Qt,可以通过Qt的bug系统来追踪这个问题修复情况。这个问题会导致在iOS下消耗大量无意义的资源进而导致卡顿。老设备上甚至无法正常加载页面。

https://bugreports.qt.io/browse/QTBUG-85662

注:示例工程也一起传到这里了,需要的可以直接去下载

@2x和@3x图片渲染异常

我在Bug系统里也找到了这个反馈,截止发文还是没修复。因此目前程序中无法使用@2x和@3x的图片

https://bugreports.qt.io/browse/QTBUG-79378

 

HTTPS

若要部署到https到web server上面,可能会报错

Application exit (TypeError: undefined is not an object (evaluating'handle[name]'))

我不清楚这是Qt到bug还是什么原因,但是我看Qt的在线示例也有这个问题。要避免这个问题需要修改js文件,找到projectname.js里找到这一行

functionBody+=" var rv = handle[name]("argsList");\n";

改成

functionBody+=" if(handle){var rv = handle[name]("+argsList+");}\n";

这个问题也提交Qt了,可以到这里追踪问题修复

https://bugreports.qt.io/browse/QTBUG-85736

 

============= End

 

标签:WebAssembly,基于,网页,Qt,no,skip,feature,dev
From: https://www.cnblogs.com/lsgxeva/p/18133130

相关文章

  • 基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类
    基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类简单的三层全连接神经网络导入了PyTorch相关的库,定义了一个名为SimpleNet的类,继承自nn.Module,这个神经网络有三个全连接层,分别是layer1、layer2和layer3。在初始化函数__init__中,指定了输入维度in_dim、两个隐藏层的神......
  • 基于阿里云、七牛云、宝塔面板,从零开始用Halo搭建个人博客网站
    目录目录目录购买服务器环境要求硬件配置CPU内存磁盘网络软件环境JRE(JavaRuntimeEnvironment)MySQL(可选)Web服务器(可选)Wget(可选)VIM(可选)浏览器支持名词解释~(符号)运行包工作目录购买域名服务器安装配置远程连接阿里云网页连接Xshell程序连接博客安装进行Halo的安装准备正式安装Hal......
  • 基于 Scriptable 从零开始美化iOS桌面(一)
    今天我为大家带来新的作品,iOS17桌面组件神器(Scriptable)原创脚本,精美作品分享!喜欢的话就点关注吧!更多脚本正在路上...*script:ONE-Progress.js*version:1.0.0*author:Nicolas-kings*date:2021-03-06*github:https://github.com/Nico......
  • 基于开源IM即时通讯框架MobileIMSDK:RainbowChat v11.5版已发布
    关于MobileIMSDKMobileIMSDK是一套专门为移动端开发的开源IM即时通讯框架,超轻量级、高度提炼,一套API优雅支持UDP 、TCP 、WebSocket 三种协议,支持iOS、Android、H5、小程序、Uniapp、标准Java平台,服务端基于Netty编写。工程开源地址是:1)Gitee码云地址:https://gitee.com/ja......
  • 基于codesys的看门狗操作
    循环任务CODESYS支持多种任务类型,其中最为常见的任务类型是循环任务,循环任务是指任务函数被每隔一段时间调用一次,而且任务应该在任务间隔时间内执行完。但是如果任务没有在规定的时间内执行完怎么办呢?看门狗对于只有打工命的工控技术来说,是永远没有躺平一说,于是“祭出”看门狗......
  • G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板
    本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。 MYC-YT113i核心板及开发板真正的国产核心板,100%国产物料认证国产T113-i处理器配备2*[email protected],RISC-V外置DDR3接口、支持视频......
  • 基于 Scriptable 从零开始美化iOS桌面(集合篇)
    Scriptable脚本合集iOS桌面组件神器(Scriptable)原创脚本,精美作品收集、分享!如果喜欢,欢迎点个⭐️Star⭐️给予小支持,感谢您的使用!喜欢这个项目?有好的脚本?请考虑留言来帮助完善它!如果您使用过程中发现有问题或可以改进的流程,请提出Issue或Pullrequest!......
  • 基于Web的二手房交易系统
    墨刀、Axure和Mockplus适用领域及优缺点墨刀(MockingBot):适用领域:墨刀主要定位于移动端原型设计,特别适合移动应用和微信小程序的快速原型制作。优点:操作简便:界面直观,新手上手快,拖拽式操作使得设计过程高效。动效丰富:提供多种动效,方便设计师制作生动的交互效果。缺点:自......
  • 基于QUBO模型的多体分子对接
    技术背景本文分享内容来自于最新的一篇名为Multibodymoleculardockingonaquantumannealer的文章,这篇文章的核心思想,是使用QUBO(二次受限二元优化)模型来求解一个分子对接问题:分子对接如果我们考虑空间中有\(N\)个分子,这\(N\)个分子可以摆放在任意的位置,以任意的角度。那......
  • 基于香橙派AIpro将开源框架模型转换为昇腾模型
    本文分享自华为云社区《如何基于香橙派AIpro将开源框架模型转换为昇腾模型》,作者:昇腾CANN。在前面的介绍中,我们知道了如何基于香橙派AIpro开发AI推理应用,也大致了解到在推理之前,需要把原始网络模型(可能是PyTorch的、TensorFlow,可能是Caffe的等等)转换成.om模型,然后才能调......