浏览器的运行和工作原理

浏览器是多线程的,js是单线程的。
js在浏览器中可以是多线程的。

浏览器的的三个常驻的线程

  1. JavaScript引擎线程,是基于事件驱动单线程执行的。
  2. GUI渲染线程,和JavaScript引擎是互斥的。当JS引擎执行时GUI线程会被挂起,GUI的更新也会被保存在一个队列中,等到JS引擎空闲时才有机会被执行,这就是JS阻塞页面加载。
  3. 页面事件触发线程,当一个事件被触发时,该线程会把事件添加到任务队列的队尾,等待JS引擎的处理。

浏览器的组成

在这里插入图片描述

  1. 用户界面 - 包括地址栏、 前进/后退按钮、 书签菜单等。 除了浏览器主窗口显示的请求的页面外,其他显示的各个部分都属于用户界面。
  2. 浏览器引擎 - 在用户界面和呈现引擎之间传送指令。
  3. 渲染引擎 - 负责显示请求的内容。 如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。
  4. 网络 - 用于网络调用,如 HTTP 请求。 其接口与平台无关,为所有平台提供底层实现。
  5. 用户界面后端 - 用于绘制基本的窗口小部件,比如组合框和窗口。 其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
  6. JavaScript 解释器 - 用于解析和执行 JavaScript 代码。
  7. 数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术

内核

浏览器内核分成两部分:渲染引擎和js引擎,由于js引擎越来越独立,内核就倾向于只指渲染引擎,负责请求网络页面资源加以解析排版并呈现给用户,所以渲染引擎也称为浏览器内核。

  1. firefox使用gecko引擎
  2. IE使用Trident引擎,2015年微软推出自己新的浏览器,原名叫斯巴达,后改名edge,使用edge引擎
  3. opera最早使用Presto引擎,后来弃用
  4. chrome\safari\opera使用webkit引擎,13年chrome和opera开始使用Blink引擎
  5. UC使用U3引擎
  6. QQ浏览器和微信内核使用X5引擎,16年开始使用Blink引擎

前端处理流程

即经典面试题:一个页面从输入URL到页面加载显示完成,整个过程中都发生了什么

  1. 用户在地址栏输入域名,DNS(Domain Name System,域名解析系统)服务器根据输入的域名查找对应IP。
  2. 浏览器和远程web服务器通过三次握手协商来建立一个TCP/IP连接。
    该握手包括一个同步报文,一个同步-应答报文和一个应答报文。该握手首先由客户端尝试建立起通信,然后服务端响应并接受客户端的请求,最后由客户端发起该请求已经被接受的报文。
  3. 一旦TCP/IP连接建立,浏览器会通过该连接向远程服务器发送HTTP的GET请求,远程服务器找到资源并使用HTTP响应返回请求资源。
  4. 浏览器开始下载资源并进行解码
  5. 浏览器解析收到的响应并根据响应的内容(假如是HTML文件)进行构建DOM树,构建render树,渲染render树等过程

渲染引擎工作流程

一个渲染引擎主要包括:HTML解析器,CSS解析器,javascript引擎,布局layout模块,绘图模块
①解析HTML生成DOM树(DOM树的生成过程中可能会被CSS和JS的加载执行阻塞)
②解析CSS生成CSSOM规则树
(划重点!!!Dom树和CSSOM两者不是解析完再渲染的,而是边解析边进行渲染的!)
③将DOM树与CSSOM规则树合并在一起生成渲染树
④遍历渲染树开始布局,计算每个节点的位置大小信息
⑤将渲染树每个节点绘制到屏幕

在这里插入图片描述
语义解析:
reflow(回流):当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。

repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。

注意:
(1)display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,所以,如果某个节点最开始是不显示的,设为display:none是更优的。
(2)display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
(3)有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

HTML解析

HTML 解析器的任务是将 HTML 标记解析成解析树。 HTML 的词汇和语法在 W3C 组织创建的规范中进行了定义,html不能简单的用解析所需的上下文无关文法来定义。浏览器为html定制了专属的解析器。 Html5规范中描述了这个解析算法,算法包括两个阶段——符号化(标记化)和构建树
在这里插入图片描述

阻塞解析

  1. 在Dom树解析的过程中,遇到link会去进行请求资源,这个过程不会阻塞Dom的解析;
  2. 遇到script标签,则会将解析停下来,去执行js代码;
  3. css加载会阻塞后面js语句的执行,而js又会阻塞DOM树的解析,因此解析被阻塞的时长更长了(解决方法:<script><link>同时在头部的话,让<script>在上)
  4. 这里需要注意img标签是不会阻塞Dom的解析的,虽然他也有src标签去请求外部资源

阻塞渲染

  1. css加载会阻塞render树的渲染
  2. css加载会阻塞后面js语句的执行
  3. js的执行会阻塞render树的渲染
 为了避免让用户看到长时间的白屏时间,我们应该尽可能的提高css加载速度,比如可以使用以下几种方法::
1、将一些css代码,js代码写在html文件内联标签里,减少下载时间
2、尽量减小文件大小,缩减代码量有时不太实际,业务就需要那么多代码,但可以通过webpack,将代码压缩成一行,实现文件大小的缩减
3、可以将一些不需要在HTML解析阶段用到的JavaScript外部文件引入的script标签加上async或者defer,使得能异步加载,不阻塞页面构建

这里要注意的是,虽然async和defer都可以做到异步,但还有一些差异,使用async标志的脚本文件一旦加载完成,会立即执行;而使用了defer标记的脚本文件,需要等到DOMContentLoaded事件之后执行。
在这里插入图片描述
绿色线是页面解析
蓝色线是JS下载
红色线是JS执行
我们可以明显看到defer和async的脚本下载都是异步进行的,而两者区别是defer要在页面解析完成后执行脚本,async是下载完脚本立刻执行脚本,同时async会影响脚本的解析。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值