从输入URL到页面加载完成期间经历了什么?(细节篇--JS运行机制)

(上接总览篇)

浏览器多进程与JS单线程

进程和线程的区分

试想一下某地区有很多工厂,工厂间是相互独立的,各工厂有独立资源,工厂中有很多工人,一个或多个工人完成任务,条理很清晰有木有。进程和线程的关系就类似于工厂和工人,工厂资源相当于系统分配的一块独立内存,工厂相互独立意味着进程相互独立,工厂内有一个或多个工人去完成任务相当于一个进程由一个或多个线程组成去完成任务。

官方术语来说,进程是CPU资源分配的最小单元(是能拥有资源和独立运行的最小单位),线程是CPU调度的最小单位(建立在进程基础上的一次程序运行单位),单线程与多线程都是针对在同一个进程内而言的。

浏览器是多进程的,浏览器能够运行是因为系统给它的进程分配了资源,每打开一个Tab页就相当于创建了一个独立的浏览器进程。浏览器主要包含以下进程:

1、浏览器主进程,负责协调主控,只有一个

  • 负责浏览器页面显示,用户交互,如前进后退等
  • 负责各个页面的管理、创建和销毁进程
  • 网络资源的管理下载等

2、第三方插件进程,每种类型插件对应一个进程,使用时才创建

3、GPU进程,最多一个,用于3D绘制等

4、浏览器渲染进程(浏览器内核),内部是多线程的,主要用于页面渲染、脚本执行、事件处理等

重点介绍浏览器内核即渲染进程,页面的渲染、JS的执行、事件的循环都在这个进程内进行。浏览器内核是多线程的,主要包含以下线程:

1、GUI渲染线程

  • 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
  • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行
  • GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻结),GUI更新会被保存到一个队列中等JS引擎空闲时立即被执行。

2、JS引擎线程(JS内核)

  • 负责处理JavaScript脚本程序
  • JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页上只有一个JS线程在运行JS程序
  • JS引擎线程与GUI渲染线程是互斥的,因此如果JS执行时间过长会造成页面渲染不连贯,导致页面渲染加载阻塞。

3、事件触发线程

  • 用来控制事件循环
  • 当JS引擎执行代码块如setTimeOut时(也可能来自浏览器内核的其它线程,如鼠标点击、ajax异步请求等),会将对应任务添加到事件线程中
  • 符合条件的事件出发时,该线程会把事件添加到待处理的队列队尾,等待JS引擎处理

4、定时触发器线程

5、异步http请求线程

JS运行机制分析

  • JS分为同步任务和异步任务
  • 同步任务都在主线程上执行,形成一个执行栈
  • 主线程外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果就在任务队列中放置一个事件
  • 执行栈中的所有同步任务执行完毕,系统会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。


猜你喜欢

转载自blog.csdn.net/didudidudu/article/details/80305284