28.从chrome消息队列谈unity3d的UI框架设计_时讯
2023-03-06 15:42:16 来源:程序员客栈
(资料图片)
1 缘起
在UI架构圈,MVC是一个著名的小团伙,其中M是被偷窥重度成瘾者,不过我们一般称之为观察者,毕竟读书人的事,怎么能叫偷呢对吧。
M喜欢散播自己的花边小新闻,屁大点儿事,都会翻译成小道消息重大事件散播出去。VC则是俩狗仔,不管M出了啥事,总能第一时间闻到消息,摇旗呐喊。
这种玩法同时满足了M和狗仔们的大多数需求,因此很快在UI架构圈流行开来。去年我用unity3d设计过一版UI框架,也是基于MVC模式。
本来这样也挺好,M出自己的名,狗仔追自己的星。但M太秀了,有时候一股脑爆出一大波新闻,让狗仔们忙得应接不暇,有时候又波澜不惊,让狗仔们急得抓耳挠腮。
2 取经MVC模式中,M抛出的事件默认都是同步处理的。这带来了一些问题:如果同一帧内收到并处理太多事件的话,可能由于处理时间太长,导致游戏卡顿。
最近的学习研究chrome浏览器的一些架构设计,发现跟unity3d游戏设计有一些相似相溶的地方,随手做了一番对比:
Unity3d | Chrome |
---|---|
消息队列 | 消息队列 |
定时任务 | setTimeout(), 延迟队列 |
观察者 | MutationObserver |
Task/Coroutine | Promise |
async/await | async/await |
游戏渲染帧 | requestAnimationFrame() |
早期的js对dom事件的支持并不友好,只能通过setTimeout()轮询处理。这种方式简单粗暴,但也有一些问题:如果轮询间隔时间过短,则大部分情况下CPU在空转;而如果轮询间隔时间过长,则dom事件会得不到及时响应。
2000年的时候js引入了Mutation Event,采用观察者模式,当dom发生变化时立刻触发相应事件。Mutation Event属于同步回调模式,解决了实时响应的问题,但也为页面展示带来了性能隐患。当我们使用js大量修改dom结构时,会频繁抛出事件,如果所有的dom事件都同步处理,势必会导致页面卡顿。
也因此,Mutation Event被反对使用,并逐渐从web标准事件中被移除。dom4之后推荐使用MutationObserver,其作出的改进其实主要就一点:把所有的dom事件统一放入到微任务消息队列中,在每一帧的结尾一次性触发。通过异步回调解决性能问题,通过微任务解决实时性问题。
3 消息队列chrome中的异步任务体系都是基于消息队列完成的,包括dom事件、fetch网络请求、promise异步任务等等。
js中的异步任务还细分为了宏任务与微任务,其中只有MutationObserver 和promise是微任务,其它的像setTimeout()之类的都是宏任务。
宏任务由宿主(比如chrome中的window对象)维护,但js引擎需要有自己的异步任务体系,因此引入了微任务队列。
后端也有消息队列,比如Kafka、RocketMQ等,但与chrome把消息队列主要用于异步任务处理不同,后端消息队列最重要的作用主要有三:定序 (Ordering),分离式数据库 (Unbundling Database)、重放 (Replay)。以首字母可简记为:OUR。
我们在做unity3d框架设计的时候,其实也有大量使用消息队列用于处理异步任务。
比如处理网络协议:通常的做法是单独起一个网络线程,接收网络协议,并把它们放到消息队列中,然后由主线程按顺序异步处理这些网络协议。
再比如Coroutine库:可以把所有的协程对象按顺序放入到一个消息队列中,每一帧按顺序遍历它们,并调用它们的next()方法。
这中间还诞生过一个很有趣的技巧:放置于消息队列中的消息,往往对先后顺序有要求,但对处理时间并不敏感。如果发现当前帧已经占用了太长的时间,可以直接跳出当前帧处理过程,把剩余的消息推迟到下一帧去处理。即无需每一帧都清空当前消息队列,从而可以缓解游戏卡顿的问题。我把这个小技巧称为分帧。
4 缘落但UI框架遇到的问题又略有不同。游戏中有很多非常复杂的UI,比如背包,在加载结束之后,需要按需初始化大量的控件。初始化控件的逻辑是游戏业务逻辑,而不是框架底层逻辑,因此很难完全封装在框架中。另外,初始化过程通常是在一帧内完成的,数量越多越有可能导致游戏卡顿。
针对这个问题,通用优化方案是将这些控件预先拖到一个MonoBehaviour脚本中,从而在加载的时候同步完成初始化过程。这个方案不是本文的重点,因此不再更多展开。另外,这个方案只能解决静态控件的初始化问题,对于背包这种需要根据服务器协议初始化大量动态控件的复杂UI起不到优化效果。
基于前述消息队列和分帧的思想,再参考MonoBehaviour的Start()方法可以配置成协程,我这里提一个新的优化思路:把UI框架中用于控件初始化的OnLoaded()方法设计为协程,这样当遇到大量控件需要初始化的时候,可以支持分帧处理,从而缓解因为大量初始化动态控件导致的卡帧。
这个设计会带来一些新的问题,其中一个是:很多UI事件会有先后顺序要求,比如UI框架中的OnOpened()方法应该在OnLoaded()方法之后回调。但将OnLoaded()方法修改为协程后,就可能发生OnLoaded()方法未完全回调完成,就回调到了OnOpened()方法的情况。这需要进一步调整UI框架逻辑,以约束UI事件之间的先后顺序关系。
5 缘尽相逢是缘,相知是福,再不关注,就真的缘尽了老板。
5 References本文提到的UI框架位于unicorn库中,unicorn-examples示例代码
18 | 宏任务和微任务:不是所有任务都是一个待遇
相关阅读
- (2023-03-06)28.从chrome消息队列谈unity3d的UI框架设计_时讯
- (2023-03-06)买国债的钱能取一部分吗?买国债收益如何?
- (2023-03-06)海马汽车标志|环球热讯
- (2023-03-06)政金债和国债有何区别?信用债是什么意思?
- (2023-03-06)固收加基金保本吗?固收加基金值得买吗?
- (2023-03-06)什么是两年定开基金?定开基金怎么赎回?
热点推荐
- (2023-03-06)28.从chrome消息队列谈unity3d的UI框架设计_时讯
- (2023-03-06)国家发改委:政策工具箱里有很多工具应对制约消费的不利因素
- (2023-03-06)FXDD:欧元、英镑和日元最新走势分析(2023年3月6日)
- (2023-03-06)今日美元/加元汇率走势图分析(3月6日)
- (2023-03-06)英镑/日元今日行情走势交易策略(2023年3月6日)
- (2023-03-06)今日亚盘、欧盘、美盘重要关注数据回顾及预测(2023年3月6日)
最近更新
- (2023-03-06)28.从chrome消息队列谈unity3d的UI框架设计_时讯
- (2023-03-06)国家发改委:政策工具箱里有很多工具应对制约消费的不利因素
- (2023-03-06)FXDD:欧元、英镑和日元最新走势分析(2023年3月6日)
- (2023-03-06)今日美元/加元汇率走势图分析(3月6日)
- (2023-03-06)英镑/日元今日行情走势交易策略(2023年3月6日)
- (2023-03-06)今日亚盘、欧盘、美盘重要关注数据回顾及预测(2023年3月6日)
- (2023-03-06)机构称美元强势正消退,欧元兑美元和英镑兑美元前景乐观!
- (2023-03-06)中国积极财政政策“加力”基调下 “双升”意味着什么?|环球热议
- (2023-03-06)国家发改委:有序推进电信、互联网、教育、文化、医疗等领域开放 每日动态
- (2023-03-06)世界微动态丨2022年烟草行业实现工商税利总额超过1.4万亿元
- (2023-03-06)数字人民币新增“微信支付”钱包快付,已支持部分微信小程序
- (2023-03-06)黄金ETF可以随时买卖吗?散户买etf最大优点是什么?
- (2023-03-06)买国债的钱能取一部分吗?买国债收益如何?
- (2023-03-06)多元创新业务助力释放消费潜力 京东国际为跨境电商市场贡献新动能|环球简讯
- (2023-03-06)海马汽车标志|环球热讯
- (2023-03-06)政金债和国债有何区别?信用债是什么意思?
- (2023-03-06)固收加基金保本吗?固收加基金值得买吗?
- (2023-03-06)世界聚焦:若持续突破这一阻力、期金有望再大涨40美元 机构:黄金、白银、原油和铜最新技术前景分析
- (2023-03-06)金价涨势放缓或陷震荡 重磅数据来袭
- (2023-03-06)全球关注:金价因美元走强和加息担忧而走低
- (2023-03-06)受美元疲软影响,黄金价格上涨,有望在五周内首次上涨
- (2023-03-06)今日聚焦!若突破关键阻力、金价有望飙升至1900美元 知名机构:美元、黄金和美债收益率走势分析
- (2023-03-06)让“有色”更“绿色” 世界观察
- (2023-03-06)每日热闻!如何推动工业稳增长?传统产业怎么改造提升?
- (2023-03-06)当前通讯!银保监会:进一步做好联合授信试点工作
- (2023-03-06)国家发改委:进一步优化投资结构,集中力量办好国家层面的大事难事急事
- (2023-03-06)什么是两年定开基金?定开基金怎么赎回?
- (2023-03-06)基金限购在多个平台购买吗?基金限购是什么信号?
- (2023-03-06)惊蛰代表的寓意是什么?惊蛰天气一般每天多少度?
- (2023-03-06)腋毛刮了会有狐臭吗?用脱毛膏脱腋毛对身体有害吗?