前几日写了一篇文章,介绍了js阻塞页面加载的问题。当时是通过例子来验证的。今天,我介绍一下浏览器内核,从原理上介绍一下js阻塞页面加载的原因。
浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。
1. javascript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。
2. GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
3. 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。
由上文蓝色标注的文字可以知道,当浏览器在执行JS程序的时候,GUI渲染线程会被保存在一个队列中,直到JS程序执行完成。这样就造成了页面的渲染,就是所说的JS阻塞页面加载问题。
很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行 onreadystatechange所设置的函数.
相关推荐
阅读这份论文能深入理解JavaScript多线程的底层机制和最佳实践。 总的来说,JavaScript模拟多线程是为了提升Web应用的性能和用户体验,尽管与传统的多线程有所不同,但通过合理利用各种技术,可以有效地处理复杂的...
本文将深入探讨JavaScript的单线程模型以及与之相关的并发机制。 在计算机编程中,线程是程序执行的基本单元,一个进程可以包含多个线程。多线程意味着程序可以在同一时间执行多个不同的任务,而单线程则表示只有一...
虽然原生JavaScript是基于事件循环的单线程语言,但可以通过一些技巧来模拟多线程的效果,例如利用`setTimeout`或`setInterval`等异步机制。本文将介绍一种通过利用GIF图像加载事件来模拟多线程的方法。 #### GIF ...
**Service Workers** 则是一种更高级的多线程机制,主要用于离线存储、推送通知和缓存策略。Service Workers运行在独立的线程上,可以拦截网络请求,使得应用能在离线状态下仍然可以响应。此外,Service Workers还...
"一个JavaScript多线程函数库"的目标就是提供这样的解决方案,允许开发者并行执行多个JS函数,提高应用性能。这个库可能利用Web Workers或者其他的并发策略,如Promise.all、async/await等,来实现后台处理任务,而...
JavaScript,作为一种广泛应用于Web开发的脚本语言,一直以来都是单线程执行的,这限制了其在处理大量计算任务或长时间运行操作时的性能。然而,随着技术的发展,JavaScript已经引入了多线程功能,以应对现代Web应用...
3. **错误处理**:线程执行过程中可能出现错误,`Concurrent.Thread.js` 提供了错误处理机制,可以捕获并处理线程内的异常,避免了程序的意外中断。 4. **线程池管理**:`Concurrent.Thread.js` 还引入了线程池的...
JavaScript定时器是编程中...总结,JavaScript定时器在单线程环境下运行,它们通过事件循环机制来异步执行任务。理解这个机制以及如何有效地使用setTimeout和setInterval,是每个JavaScript开发者必须掌握的基础技能。
Node.js作为一个基于Chrome V8引擎的JavaScript运行环境,它的默认设计是单线程的,主要依赖异步I/O和事件驱动来实现高效的非阻塞I/O操作。然而,对于CPU密集型的任务,这种模式可能会导致性能瓶颈,因为所有计算都...
此外,对于更复杂的交互需求,如等待JavaScript异步操作完成,可以利用JavaScript的回调函数或者Promise机制,配合C#的事件或异步编程模型(如async/await)来实现。 总之,Winform应用中的多线程调用JavaScript...
JavaScript(简称JS)是Web开发中的关键语言,其运行机制对于理解高性能的前端应用至关重要。在浏览器环境中,JS代码的执行涉及到多个线程协同工作,这些线程共同构成了浏览器的运行机制。 首先,我们来详细了解GUI...
多线程也有其挑战,比如线程间的数据共享可能导致竞态条件、死锁等问题,需要使用锁或其他同步机制来避免。此外,线程创建、销毁和管理也消耗资源,过多的线程可能会导致系统性能下降。 在实际编程中,如何选择单...
"FireBreath_多线程及调用JS例子"这个压缩包显然包含了关于如何在FireBreath插件中实现多线程以及与JavaScript交互的示例代码。 多线程在软件开发中是非常重要的一个概念,特别是在处理耗时任务或者需要并行处理...
总的来说,JavaScript通过单线程、事件循环和异步任务队列的机制,实现了看似多线程的效果。理解这一机制对于编写高性能、响应式的Web应用至关重要。开发者需要谨慎处理可能导致阻塞的长时间运行任务,充分利用异步...
然而,随着技术的发展,开发者们找到了在JS中利用多线程的方法,Concurrent.Thread就是一个这样的库,它允许我们在JavaScript中创建和管理多线程,从而提升性能并解决复杂计算的问题。 **1. Concurrent.Thread概述*...
本文将深入探讨JavaScript的单线程和多线程概念,解释它们如何影响程序的执行,以及如何在实际开发中利用这些特性。 JavaScript的单线程和多线程模型各有优势和挑战。开发者需要根据应用的具体需求,合理选择并发...
本文将深入探讨JavaScript的多线程实现,特别是通过Web Workers进行异步处理的机制。 首先,理解JavaScript的单线程模型至关重要。在浏览器环境中,JavaScript引擎(如V8)是单线程的,所有的代码都在同一个线程上...
3. **异步编程**:除了使用传统线程,许多现代编程语言提供了异步编程模型,如Java的`CompletableFuture`,C#的`async/await`,JavaScript的回调函数或Promise。这些模型允许非阻塞I/O操作,进一步优化UI性能。 4. ...