JS线程和UI线程是同一个线程吗?

前言

我又回来了,今天是2021年7月10号,周末,这篇随笔是一个月前发布的,现在回头看已经我已经有了更近一步的认知。这一周我阅读了谷歌开发者网站关于web优化的种种,之前的迷惑迎刃而解。UI 线程属于渲染引擎,关于渲染引擎可以看我写的这篇文章了解:浏览器渲染机制
我直接开门见山:是的,它们是共用一个线程,这个线程称之为主线程。JS 可以在如今的浏览器通过 Web Worker 开启子线程

也不能说之前写的这些全然无用,还是具有很大的参考意义。我将会红字标出

一、是同一个线程

该线程称之为主线程(Main thread),以下来自前端的权威——MDN官网的说法:【关于这一点,还是得看权威啊】

The main thread is where a browser processes user events and paints. By default, the browser uses a single thread to run all the JavaScript in your page, as well as to perform layout, reflows, and garbage collection. This means that long-running JavaScript functions can block the thread, leading to an unresponsive page and a bad user experience.

Unless intentionally using a web worker, such as a service worker, JavaScript runs on the main thread, so it's easy for a script to cause delays in event processing or painting. The less work required of the main thread, the more that thread can respond to user events, paint, and generally be responsive to the user.

其中我标记它所说的重点部分,布局呈现、重绘,这里明显是UI的范畴。
MDN的说法就是页面布局和js是在一个主线程内实现的。子线程是web worker,这个知识点超纲了,这里不讨论。

二、不是同一个线程

在大部分的博客、知识问答里,大多都说是不同的线程,基本说法相同。【嗨~鱼龙混杂啊,网上】
但是都承认一点,UI线程和js线程是互斥的。

三、二者皆而有之

以下是来自stackoverflow的一个高分回答:

JavaScript, the language, is nearly silent on the topic of threading. Whether it's single- or multi-threaded is a matter of the environment in which it runs. There are single-threaded JavaScript environments, and multi-threaded JavaScript environments. The only real requirement the specification makes is that a thread have a job queue and that once a job (a unit of code to run, like a call to an event handler) is started, it runs to completion on the thread before another job from that queue is started. That is, JavaScript has run-to-completion semantics.

JavaScript on browsers isn't single-threaded and hasn't been for years. There is one main thread (the thread the UI is handled on), and any number of web worker threads. The web workers don't have direct access to the UI, they send messaegs to the UI thread, and it does the UI updates. The threads don't directly share data, they share data explicitly via messaging. This separation makes programming multi-threaded code dramatically simpler and less error-prone than if multiple threads had access to the UI and the same common data area. (Writing correct multi-threaded code where any thread can access anything at any time is hard.)

UI 线程和 js 线程是不是同一个线程已然不重要了,重要的是他们是否满足了ECMAScript的规范,关于其在浏览器的规范点击这里【我觉得这一点超级棒,还是得看规范,可是规范贼多,头晕】
无论怎么样,只需记住UI的渲染和js代码的执行是互斥的,就已经足够了。

总结

想到这个规范,我想起了之前图灵给阮一峰的那份关于异步机制的批注,也有个规范的实现问题。有时候我们纠结的东西,它们都有各自的实现方式,但是目的都是一样的。【图灵中关于规范实现的,让我触动很久】

还有一件事,看到知乎有人根据CSS的transition动画,js不影响其绘制,就认定 js 和 UI 其是两个线程。
其实吧,这是谷歌自己的优化,谷歌开发者频道有讲解,12年的视频了,点这个链接This excellent Google I/O talk
上述的优化在很多浏览器都实现了,在IE9貌似实现了。【这是对的,在我的 浏览器渲染机制 中的性能章节有讲述】

posted @ 2021-06-07 15:26  Sebastian·S·Pan  阅读(615)  评论(0编辑  收藏  举报