从浏览器进程到JS编译执行

进程和线程

一、进程

定义:进程是正在运行的程序的实例,它代表CPU所能处理的单个任务,是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)。

组成:每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。

  1. 文本区域存储处理器执行的代码;
  2. 数据区域存储变量和进程执行期间使用的动态分配的内存;
  3. 堆栈区域存储着活动过程调用的指令和本地变量。
二、线程

定义: 线程是进程中的一个实体,是被系统独立调度和分派的基本单位。

组成:一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

三、进程和线程的关系
  1. 任何时刻,单个CPU总是运行一个进程,其他进程处于非运行状态。
  2. 一个进程可以包括多个线程。
  3. 线程不拥有自己的系统资源,但是可以和同属一个进程的其它线程共享该进程所拥有的全部资源。同时,由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。
  4. 一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。线程也有就绪、阻塞和运行三种基本状态。
  5. 进程中的某一块内存区域,可能只能供给固定数目的线程使用。当某一内存区域只能由一个线程使用时,这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。
  6. “互斥锁”(Mutual exclusion,缩写 Mutex):防止多个线程同时读写某一块内存区域。
  7. “信号量”(Semaphore):用来保证多个线程不会互相冲突。

浏览器是多进程的

一、浏览器主要包含哪些进程?
  1. Browser进程:浏览器的主进程(负责协调、主控),只有一个。

作用是:

  • 负责浏览器界面显示,与用户交互。如前进,后退等
  • 负责各个页面的管理,创建和销毁其他进程
  • 将Renderer进程得到的内存中的Bitmap,绘制到用户界面上
  • 网络资源的管理,下载等
  1. 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建

  2. GPU进程:最多一个,用于3D绘制等

  3. 浏览器渲染进程(浏览器内核)(Renderer进程,内部是多线程的):

  • 默认每个Tab页面一个进程,互不影响
  • 渲染器进程中包含用于操作HTML,JavaScript,CSS,图片和其他内容的复杂的逻辑。
  • 每个渲染器进程都运行在沙箱内,这意味着它对磁盘、网络和显示器没有直接的访问权限。
  • 所有跟网络应用的交互,包括用户输入事件和屏幕绘制都必须通过Browser进程。这可以让浏览器进程监视渲染器的可疑行为,一旦发现其从事破坏活动就将其终止。

一般来说,在浏览器中打开一个网页相当于新起了一个浏览器渲染进程。
浏览器也由自己的优化策略:允许两个相关的且属于同一站点的网页共享同一个渲染器进程。

二、浏览器多进程的优势
  • 避免单个页面崩溃影响整个浏览器
  • 避免第三方插件崩溃影响整个浏览器
  • 多进程充分利用多核优势
  • 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
三、浏览器渲染进程(浏览器内核)
  1. GUI渲染线程
  • 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
  • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。
  • 注意,GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  1. JS引擎线程(JS内核)
  • 负责处理Javascript脚本程序,运行代码。
  • JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序。
  • 注意,GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
  1. 事件触发线程
  • 归属于浏览器而不是JS引擎,用来控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)。
  • 当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中。
  • 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。
  • 注意,由于JS的单线程关系,这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)
  1. 定时触发器线程
  • 传说中的setInterval与setTimeout所在线程。
  • 浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)。
  • 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)。
  • 注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
  1. 异步http请求线程
  • 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求。
  • 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,再由JavaScript引擎执行。
四、主进程(Browser进程)对渲染进程(Render进程)的控制过程
  1. Browser进程收到用户请求,获取页面内容(譬如通过网络下载资源),随后将该任务通过RendererHost接口传递给Render进程。此过程可大致分为一下几个步骤:
  • URL 解析
  1. 首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。
  2. 由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。
  3. 浏览器还会进行一些额外的操作,比如安全检查、访问限制。
  • DNS 查询
  1. 浏览器缓存----浏览器会缓存DNS记录一段时间。有趣的是操作系统没有告诉浏览器存储DNS记录的时间,这样不同浏览器会记录他们各自固定的一个时间(2分钟到30分钟不等)
  2. 系统缓存----如果在浏览器缓存中没有找到需要的记录,浏览器会做一个系统调用(gethostbyname)。这样便可获得系统缓存中的记录。
  3. 路由器缓存----接着前面的查询请求发向路由器,他一般会有自己的DNS缓存
  4. ISP DNs缓存----接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
  5. 递归搜索----你的ISP的DNS服务器从域名服务器开始进行递归搜索,从com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。
  • TCP 连接
  1. 应用层:发送 HTTP 请求。浏览器只能发送 GET、POST 方法,而打开网页使用的是 GET 方法。
  2. 传输层:TCP 传输报文。在建立连接前,会先进行 TCP 三次握手。
  3. 网络层:IP协议查询Mac地址。
    以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。
  4. 链路层:以太网协议。
    广播发送数据。直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。
  • 处理请求
    在这里插入图片描述
  • 接受响应
    浏览器接收到来自服务器的响应资源后,会对资源进行分析。
    首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。
    如果响应资源进行了压缩(比如 gzip),还需要进行解压。
    然后,对响应资源做缓存。
    接下来,根据响应资源里的 MIME[3] 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。
  1. Renderer进程的Renderer接口收到消息,简单解释后,交给渲染线程,然后开始渲染
  • 渲染线程接收请求,加载网页并渲染网页,这其中可能需要Browser进程获取资源和需要GPU进程来帮助渲染
  • 当然可能会有JS线程操作DOM(这样可能会造成回流并重绘)
  • 最后Render进程将结果传递给Browser进程
  1. Browser进程接收到结果并将结果绘制出来。
  • HTML 解析
    浏览器需要根据文件指定编码(例如UTF-8)将接收到的响应内容转换成字符串,也就是HTML 代码。
    预解析:提前加载资源,减少处理时间,它会识别一些会请求资源的属性,比如img标签的src属性,并将这个请求加到请求队列中。
    符号化是词法分析的过程,将输入解析成符号,HTML 符号包括,开始标签、结束标签、属性名和属性值。它通过一个状态机去识别符号的状态,比如遇到<,>状态都会产生变化。
    生成Dom树。
  • CSS 解析
    浏览器下载css文件,将css文件解析为样式表对象,并来用渲染dom tree。该对象包含css规则,该规则包含选择器和声明对象。
    css元素遍历的顺序,是从树的低端向上遍历。
  • 渲染树
    浏览器结合 DOM 树和 CSSOM 树构建 Render 树,并计算布局属性
  • 布局与绘制
    确定渲染树种所有节点的几何属性,比如:位置、大小等等,最后输入一个盒子模型,它能精准地捕获到每个元素在屏幕内的准确位置与大小。
    然后遍历渲染树,调用渲染器的 paint() 方法在屏幕上显示其内容。
    浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。
五、JS进程编译执行
  1. 词法分析

JS 脚本加载完毕后,会首先进入语法分析阶段,它首先会分析代码块的语法是否正确,不正确则抛出“语法错误”,停止执行。

  1. 预编译

JS有三种运行环境:全局环境、函数环境、eval 。
每进入一个不同的运行环境都会创建一个对应的执行上下文,根据不同的上下文环境,形成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是当前执行上下文。
创建执行上下文:创建变量对象,建立作用域链,确定 This 指向

  1. 执行

参考资料:
1.http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
2. https://www.cnblogs.com/cangqinglang/p/8963557.html
3. https://www.cnblogs.com/tutuj/p/11025042.html
4. http://lynnelv.github.io/js-event-loop-browser
5. https://www.cnblogs.com/jin-zhe/p/11586327.html
6. https://zhuanlan.zhihu.com/p/43369093

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值