微信小程序中的双线程模型,聊聊什么是什么
发表时间:2023-11-08 18:41:58
文章来源:炫佑科技
浏览次数:180
菏泽炫佑科技 菏泽炫佑小程序开发 菏泽炫佑app制作 炫佑科技
有过微信小程序开发经验的朋友应该都知道“双线程模型”的概念。 本文简单总结了双线程模型的一些科普知识。 知识很浅薄。 如果有任何错误,请指正。
我曾在“小程序云开发”团队工作。 在一些外部培训和技术分享中,经常被问到这样一个问题:“微信小程序和Web网站的主要技术区别是什么?”,在编程语言和范式方面,小程序开发和Web前端非常相似端开发(例如都使用语言,WXML/WXSS,与HTML/CSS非常相似等),但并不直接使用原生前端技术。 【相关学习推荐:小程序开发教程】
与Web网站相比,微信上托管的小程序需要考虑安全、性能等因素,保证小程序不会给微信App本身带来安全风险,同时尽量做到性能和用户体验接近尽可能到本机应用程序。 这就是小程序不直接使用浏览器的线程模型而必须自己构建双线程模型的两个主要原因。
那么什么是小程序的双线程模型呢?
理解新概念或新技术的*好方法就是为其提供参考。 因此,要了解小程序的线程模型,首先必须对浏览器的线程模型有一定的了解。
浏览器是多进程的
可能每个前端工程师刚入行时都不止一次被面试官问过“你是如何理解前端的单线程的?” 因为前端的核心技能之一就是单线程语言,所以充分理解并掌握 JS 的单线程运行模式是对一个前端工程师*基本的要求。 然而,有一个很多初学者容易陷入的误区:错误地将“单线程”理解为“浏览器单线程”。
事实上,浏览器的内部架构非常复杂,但却采用了一种互斥、阻塞的管理模式来处理GUI渲染线程和逻辑脚本线程,这引起了一些开发的误解。
以浏览器为例,点击右上角的设置按钮,然后进入“更多工具”->“任务管理器”,你会看到这样的弹窗:
可以看到开启了多个进程,包括浏览器进程、网络进程、GPU进程等,这些都是常见的进程。 请注意,上图中有两个选项卡进程。 为每个标签页打开一个独立的渲染进程( )。 每个进程的资源(CPU、内存等)和行为(UI、逻辑等)相互交互。 不共享,因此即使一个选项卡崩溃,也不会影响其他选项卡。
在每个选项卡进程中,浏览器都会将不同的任务交给相应的线程。 例如,GUI渲染线程负责将HTML渲染成可视化UI; 引擎线程负责解析并运行代码逻辑; 并由调度的触发线程负责处理。 /定时器等
还有一件事,这里有一个非常令人困惑的地方。 其实 / 并不是语言的一部分,而是运行时(*初是浏览器,后来 Node.js 也支持)提供的能力。
GUI渲染线程和引擎线程是互斥的,在执行过程中会阻塞UI的渲染。 即使脚本执行时间过长,页面也会长时间无响应,然后崩溃。 这正是GUI渲染线程和引擎线程之间的区别。 互斥和阻塞的线程管理方式让一些前端开发认为浏览器是单线程的。
那么为什么要设计成单线程呢?
创始人仅用了 10 天就创造了这种语言。 他*初的想法是在浏览器中提供一些简单的脚本逻辑来处理用户交互、DOM操作等,所以设计必须遵循两点:
在语法方面,它借鉴了Java,但去掉了很多复杂的设置,比如类型声明、模块系统(后来添加)等。
在运行机制上,它不像Java那样提供多线程能力。 主要原因是为了避免多线程DOM操作引起的UI冲突。 例如,如果多个线程同时操作同一个DOM,那么浏览器应该如何确定使用哪个线程来产生*终的UI效果呢? 这是一个经典的线程安全(也称为线程同步)问题。 多线程编程领域有很多解决方案,比如添加锁机制,但这带来了更多的复杂度,与简单易用的设计初衷相矛盾。
这也解释了为什么GUI渲染线程和引擎线程是互斥的:代码有修改DOM的权限。
代码执行时,GUI渲染线程会被挂起,等待引擎线程空闲后再执行,避免渲染时反复修改DOM带来不必要的渲染压力。 使用互斥模式等待代码执行完成可以保证渲染的是*终的执行结果。 因此,浏览器的空闲时间就成为衡量网站性能的重要指标之一。 空闲时间多说明逻辑不密集,DOM变化频率低。 在这种情况下,浏览器可以更加快速、流畅地响应用户的交互行为。 ,如下所示:
React Fiber 使用空闲时间来处理分片任务。
后来,HTML5 被引入 Web,提供了多线程执行代码的能力。 不过,与其他编程语言不同的是,线程并不是与主线程并行,而是一种主从(-Slave)的多线程模型。
里面的代码不能操作DOM,可以理解为线程安全的。 记住这一点,这是后面讨论小程序双线程模型的重要基础。
那么微信小程序为什么不直接使用浏览器的线程模型呢? 这就需要从产品和技术两个角度来比较小程序和网站的区别。
为什么小程序不使用浏览器的线程模型?
刚接触小程序开发时候,我常常“嫌弃”它相对于 Web 来说能力较弱,相对于 Vue 来说语法过于简单。 当时我几乎感觉小程序是微信凭借其庞大的用户数实现的技术垄断。
不过,随着对技术和产品的不断深入了解,我对小程序态度也发生了变化,从“不喜欢”变成了敬佩,因为在充分了解小程序的产品定位后微信小程序开发技术选型,我发现双线程模型是小程序等产品场景的*优解决方案。 那么小程序是一个什么样的产品呢?
小程序的宿主是微信,但小程序版本的迭代是独立的,升级和更新不依赖于宿主。 这与 Web 网站相同。 换句话说,小程序继承了Web的一些优点,但它不是Web。 目前Web相关的技术已经相当全面,可以承载一些非常大的应用,比如3D地图、游戏等。
小程序的定位是小、美、用完就走。 它并不追求微信中所有的Web能力,所以在能力上肯定是不如Web的。 它还具有微信提供的一些原生能力,例如原生组件、系统级和微信生态API等。
另外,“小程序-微信”之间的关系不同于“网站-浏览器”之间的关系。 前者更接近该类在线编程平台(类中简称平台)中各个程序案例(简称案例)与平台之间的关系。
从技术角度来看,平台的核心考虑之一是在为案件提供足够的能力的同时,保证案件的逻辑不会危及平台的安全。 想象一下微信小程序中的双线程模型,聊聊什么是什么,如果你可以在互联网上编写一个程序来获取私人信息,也许第二天就会崩溃并解雇所有员工。
在这样的产品基调下做出了技术选型之后,接下来就是架构师和程序员的工作了。
我们以此为例。 如果让你设计这样一个编程平台,你会使用什么技术? 也许您的**个想法是使用它,因为您可以使用其中的所有 Web 功能。 事实上,它确实是用来呈现程序的效果,但输入的代码不会完全复制到计算机上运行。 相反,代码在注入计算机之前将经过编译过程。 这样做的出发点主要是出于安全考虑,在编译过程中消除了一些危险代码; 其次,这还可以支持平台中更多的语言,例如。 当然,还有性能。 性能问题是个老生常谈的问题,就不详细说了。
因此,不仅需要使用它,还需要引入额外的编译器。 我们必须确保每种情况下的代码都是线程安全的。 *基本的就是禁止程序操作网站的DOM。 有两种方法可以实现此目的:
Web是线程安全的,里面的代码无法获取和对象,因此无法操作DOM。 另外,由于 的线程安全特性,内部的代码在运行时不会阻塞外部的 GUI 渲染线程,两者可以并行运行。
DOM 是 Web 规范的一部分。 设置模式以防止获取节点,从而无法操作其中的 DOM。
两者相比,DOM的兼容性比Web差,距离大规模使用的日期还很远,所以Web解决方案更加现实。
这就形成了一个简单的双线程模型:线程负责计算,将结果传递给主线程,主线程负责渲染。
然而,该模型存在严重的性能问题。 Web 消耗大量资源。 除了计算消耗之外,与主线程的通信过程也会造成严重的性能损失。
那么有没有一种方法可以实现和Web一样的线程安全,同时兼顾性能和保证良好的用户体验呢? 这就是微信小程序使用双线程模型的主要目的。
安全高效的双线程模型
虽然前面用这类编程平台来类比,但小程序的技术要求和小程序并不完全相同。 主要区别在于小程序不需要支持所有HTML标签,只提供有限数量的UI组件。 根据小程序产品定位,我们可以总结出小程序的主要技术要求如下。 (任何新技术或架构都是为了解决特定问题而设计的,所以有必要了解小程序的主要技术要求。)
渲染线程和逻辑线程
小程序的双线程是指渲染线程和逻辑线程。 这两个线程分别负责渲染 UI 和执行代码。 如下所示:
渲染线程用于渲染和呈现UI。 它是一个完整的类似浏览器的运行环境,并且具有自行运行的能力。 不过,小程序并没有把逻辑脚本放进去运行。 相反,它将逻辑层分离成并行线程,并使用客户端提供的引擎来运行代码。 、iOS和是腾讯X5内核和IDE工具nwjs提供的环境。
逻辑线程是一个只能运行的沙箱环境,不提供与DOM操作相关的API,因此无法直接操作UI,只能通过更新数据来异步更新UI。
事件驱动的沟通
注意上图中渲染线程和逻辑线程之间的通信方式。 与Vue/React不同的是,小程序的渲染层和逻辑层之间的通信并不直接在两者之间传递数据或事件,而是由Act作为中介进行转发。
整个过程是一个典型的事件驱动模型:
这种数据驱动的UI模型是前端编程领域比较推崇的编程范式。 如果你是一个拥有5年以上开发经验的前端开发,那么相信你**次接触这个模式时一定会有些不适。 ,因为在此之前,操作DOM几乎是一个“行业规则”。 甚至有很多前端入门的书籍、博客和教材都是从DOM操作入手的。 现在看来,这些确实已经过时了。
一方面,这种逻辑和渲染分离的线程划分模式可以保证逻辑线程沙箱中运行的代码是线程安全的。 另一方面,由于渲染线程的计算量很小,保证了对用户交互的快速响应。 改善了用户体验。
总的来说,与浏览器的线程模型相比,小程序的双线程模型从性能和安全角度都解决或避免了Web令人担忧的性能,同时实现了与Web相同的线程安全。 推动。 综上所述,双线程模式是针对浏览器现有进程和线程管理模式限制的小程序特定场景下的一种改进的架构方案。
总结
在我看来,程序员的核心能力和竞争力不是完全理解某种语言或框架的API,而是了解这些语言和框架的底层原理。 对于一个小程序开发来说,工作中遇到技术问题时的解决方案往往是基于底层原理(更直接一点,当你找工作面试的时候,没有人会问你小程序的语法)。
通过了解小程序双线程模型的背景、设计、通信等,希望大家能够对小程序底层架构有更深入的了解,有需要的也可以作为参考以便后续工作中类似场景。 当然,理解小程序的双线程模型并不是唯一的目标。 这些知识在一定程度上可以为日常开发工作提供一些启发,主要是在性能方面:
炫佑科技专注互联网开发小程序开发-app开发-软件开发-网站制作等