为什么浏览器渲染进程不使用多线程的方式?

191 天前
 heroisuseless

在网上查了一下,说是如果多个线程同时修改 DOM ,可能会导致竞态条件和不可预测的结果。但是微信小程序用的就是双线程啊?所以浏览器用单线程最本质的原因是什么?以及微信小程序为什么要使用双线程?

5310 次点击
所在节点    浏览器
27 条回复
Danswerme
191 天前
微信小程序的双线程是指渲染层和逻辑层由不同的线程管理。

https://developers.weixin.qq.com/community/develop/article/doc/0000461093c4d8782ff7cf7d95b413
UnluckyNinja
191 天前
渲染层两者不都是单线程吗,想另开逻辑线程浏览器也可以用 worker ,worker 不能直接操作 dom
IvanLi127
191 天前
GUI 渲染一般都是单线程的,小程序也是。
chrome 浏览器的 js 执行是在独立线程的,小程序也是。
小程序和 chrome 一样,js 执行完需要改界面也是委托给渲染线程渲染。至少在这层面来说他们没有你说的区别。
heroisuseless
191 天前
@IvanLi127 我比较好奇为什么浏览器会设计成这样,微信小程序又设计成那样,以及浏览器为什么不设计成微信小程序这样的
ShineyWang
191 天前
GUI 有单独的页面更新和渲染逻辑
windows 上我就遇到过另一个线程修改页面导致控件花屏的
IvanLi127
191 天前
@heroisuseless 我搜了下网上关于小程序双线程的文章,感觉是说的浏览器和 chrome 之类的现代浏览器是不同的。浏览器那么多,你说的是哪个?
coolcoffee
191 天前
微信小程序的方式只是同一个页面中渲染和逻辑是分离的,UI 层面本质上还是 webview 在绘制,这个 Android 手机上打开调试模式就可以看到页面栈或者 tab 页面都是一个独立的 webview 。

我所了解的除了浏览器渲染,其他像 iOS 原生、Android 原生、Unity 游戏开发都是只能在 UI 线程也称主线程上操作。

最阻碍技术推进的原因肯定是复杂度和收益不成正比。比如本来只通过主线程操作可以进行脏检查来加快一帧数据渲染,但是多线程下面就歇菜了。
tcper
190 天前
小程序的双线程,本质上就是阉割了 webview ,通过他们的框架/IDE/runtime 将逻辑放在他们定制的逻辑线程里执行,然后通过 setData 通知 webview 更新,这么做他们的理由就是内容可控、安全什么的,当然有一定的道理。

所以说小程序所谓的双线程是没有太多技术创新的,因为只是嫁接在 webview 上实现的功能,而且他们的目的也不是技术创新,只是为了实现自身可控的 runtime 。
powersee
190 天前
几乎所有 GUI 渲染都是单线程的,多线程渲染很容易出现死锁、竞争等问题。
araraloren
190 天前
多线程带来的问题大于能带来的好处,除非有更好的架构真的能让你的程序有特定的优点。
shadowyue
190 天前
你别想复杂了,现实生活中画画这个行为就无法多人合作。
你见过有十个画师同时画一张色图吗?
A 画师绘制巨乳的时候,别人就只能去画美腿。
能优化的只有分图层,分模块,这一部分 GPU 级别就已经做了很多优化了。
现实世界做不到的事情,程序上也做不到。代码也是现实世界的映射。
kaedeair
190 天前
所有的 gui 程序中更新界面的工作都只能交给一个线程
leonshaw
190 天前
因为一个线程够了
4kingRAS
190 天前
我刚学编程时深入研究过这个问题,不只是浏览器这么做,任何涉及 UI 的框架都是单线程模型,QT, Android ,Swing ,WPF ,MFC 等等等等。结论其实就很简单,也很笼统,就是多线程就是不好的设计,有时候为了加速不得已才引入的多线程。平时开发都是能不多线程就不多线程。

几个链接自己研究去吧


https://zhuanlan.zhihu.com/p/44639688


https://flylib.com/books/en/2.558.1/why_are_guis_single_threaded_.html


https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/threading-model?view=netframeworkdesktop-4.8
4kingRAS
190 天前
微信小程序那个问题是为了实现热更新使用了 web 技术,而 webview UI 和 js 都在一个线程,JS 里执行一些耗时逻辑,UI 不就直接卡死了,所以分了双线程 UI 和 逻辑
R4rvZ6agNVWr56V0
190 天前
thevita
190 天前
本质就是 小程序不想让你操作 DOM, 只提供封装后的给你, UI 的实现就可以有私有实现(比如 暴露一些 wx 内部的 API/控件 什么的出去)

浏览器为什么不这么设计: 因为原来没有这样的需求

这里 独立的 JS 线程 就是 个 没有 web api javascript instance (因为所谓的 “多个线程同时修改 DOM ,可能会导致竞态条件和不可预测的结果”,就是 web api 不提供线程安全性),现代 web 浏览器里也是有的,就是 Web Worker ,

只是小程序,的与 UI 线程的通信/交互啊什么的都是封装好了的,Web Worker 里你得自己来
ZztGqk
190 天前
不是有 worker 么,只是没有好用的协程切换工具,相比之下原生安卓的配合 kt 的协程是个不错的设计。在 js 这你只能通过 ipc 来实现 worker 通信。
zhbhun
190 天前
问题 1:"在网上查了一下,说是如果多个线程同时修改 DOM ,可能会导致竞态条件和不可预测的结果。但是微信小程序用的就是双线程啊?"
回答:微信小程序的双线程指的是逻辑线程和渲染线程,其中逻辑线程一样也是无法直接同步修改 DOM 的,需要通过 bridge 通信的方式告诉渲染线程来操作 DOM 。其实浏览器也可以做类似的事情,就是把逻辑代码放 web worker 来执行(类似小程序的逻辑线程),现在的 js 线程只接收 web worker 传来的信息进行渲染。社区也有人探索类似的方案,比如
https://github.com/web-perf/react-worker-dom ,就是把 react 搬到 web worker 上运行。

问题 2:“所以浏览器用单线程最本质的原因是什么?”
回答:个人感觉更多是因为早期 JS 就是个脚本语言,主打就是要简单易用,如果引入了多线程会变得更加复杂,当时也没有这个需求。

问题 3:微信小程序为什么要使用双线程?
回答:上面说的 react-worker-dom 虽然类似小程序采用了双线程,但是咋没有流行呢?主要还是因为浏览器的性能瓶颈在 DOM 的渲染上。如果要在浏览器上做一个类似原生应用或微信小程序的页面切换,很容易出现页面切换时卡顿的问题。如果有尝试用过 ionic 来开发 hybrid app ,你会发现页面的切换始终会有存在掉帧的问题,特别是页面 DOM 数量多了。而微信小程序直接每个页面就是新的一个 webview ,交给原生来切换。
另外,客户端那边操作 UI 也必须是在主线程上的,不允许在其他线程直接操作 UI ,客户端为什么更流畅,主要还是因为 JS 本身性能有差距,还有就是 DOM 的渲染性能比原生差很多。记得早起还有人尝试过放弃 DOM ,自己用 canvas 来做一套渲染引擎来优化渲染性能。
codehz
190 天前
微信小程序和 react native 的方案导致了如果直接实现动画,会比较“不跟手”,即存在操作延迟,对于按钮这类交互控件倒是没有啥影响,但滚动的时候就会较为明显,于是微信小程序和 react-native 都各自发明了在 ui 线程里跑代码的方案

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1113556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX