关于我对webview的一些看法

作者:xiaojinao | 分类:tech

最近在研究 webview 应用框架。试了三种方案,记录一下实际体验。

需求

方案一:C webview

webview/webview 是个很轻量的 C 库,Windows 基于 WebView2,macOS 用 WebKit。

基础用法很简单:

#define WEBVIEW_HEADER
#include "webview.h"

webview_t w = webview_create(0, NULL);
webview_set_html(w, "<h1>Hello</h1>");
webview_run(w);
webview_destroy(w);

但到自定义标题栏就开始折腾了。库本身不提供隐藏标题栏的接口,你得自己创建一个 popup 父窗口把 WebView2 嵌进去,然后手写 WM_NCCALCSIZE、WM_SIZE、拖拽消息处理,大概一百多行 C 代码。而且旧版单头文件还有白屏问题,需要自己改库代码 SetWindowPos 居中。新版虽然好了不少,但还是得自己糊 Win32。

结论:轻量(200KB),适合熟悉 Win32 的人,但自定义标题栏成本不低。

方案二:Tauri(Rust + 前端)

Tauri 2 的做法就省心多了。配置里关掉原生装饰:

{
  "app": {
    "windows": [{ "decorations": false }]
  }
}

HTML 里加个属性就能拖拽:

<div data-tauri-drag-region>
  <span>自定义标题栏</span>
  <button data-removed="window.__TAURI__.window.getCurrent().minimize()">—</button>
  <button data-removed="window.__TAURI__.window.getCurrent().close()">✕</button>
</div>

拖拽、双击最大化全是原生行为,不需要你写任何底层逻辑。按钮调内置 API,一行一个功能。

编译出来 8MB,启动快。跨平台也是原生支持。

结论:开发体验最好,标题栏功能开箱即用。

方案三:pywebview + Nuitka

Python 版 webview,写起来也快:

import webview
window = webview.create_window('标题', html=html, frameless=True, js_api=Api())
webview.start()

标题栏用 CSS -webkit-app-region: drag 拖拽,按钮调 window.minimize() 这些。

但打包坑比较多。Nuitka 的 pywebview 插件会排除 win32 平台模块,编译时得加 --disable-plugin=pywebview。打包出来 13MB exe + 依赖 DLL 总共 28MB,启动也比前两个慢。

结论:Python 开发确实快,但分发体积大、启动慢、打包有坑。

对比

C webview Tauri pywebview+Nuitka
exe 大小 200KB 8MB 13MB
分发总大小 200KB 8MB ~28MB
启动速度 最快 快 较慢
标题栏实现 手写 Win32 API data-tauri-drag-region -webkit-app-region + CSS
拖拽 WM_NCLBUTTONDOWN 原生 CSS 属性
按钮功能 ShowWindow window.__TAURI__ pywebview Window API
开发门槛 高(需要 Win32 经验) 低(前端思维) 低(Python 思维)
打包复杂度 无 低 有坑

个人看法

试下来觉得 Tauri 最方便。标题栏这块 Tauri 当基础设施做了,CSS 属性控制拖拽区、JS API 控制窗口行为,不需要跟 Win32 打交道。虽然打包体积比 C 方案大,但开发省的时间值这个差价。