浏览器问题汇总(上)

本文详细探讨了浏览器的工作机制,包括浏览器架构、HTTP请求流程、导航过程、渲染流程、界面图层和V8引擎执行JavaScript的步骤。此外,还讨论了重绘与重排的优化策略,浏览器缓存机制以及跨页签通信的方法。

1.浏览器架构组成时什么?

谷歌浏览器是多进程架构,在启动浏览器之后创建的进程大致有:

  • 浏览器主进程:负责界面显示,用户交互,子进程管理,同时提供存储等功能;
  • 渲染进程:负责将html,css,javascript编译合成为用户可查阅和操作的网页。该进程中可以运行渲染引擎,V8引擎程序,通过Blink对界面进行排版,通过V8执行javascript代码。对于谷歌浏览器而言,每当打开一个新的Tab标签,浏览器都会为其创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下;

  • 网络进程:负责页面的网络资源加载;

  • GPU进程:负责调用计算器硬件接口进行页面图形绘制,从而提供浏览器绘图性能。比如:在CSS中我们定义了一个动画,可以通过will-change开启GPU硬件加速,从而提升动画的性能;

  • 存储进程:负责页面的缓存处理,及cookie,indexedDB等浏览器数据存储;

  • 插件进程:负责浏览器插件的运行,因插件容易崩溃,因此需要通过插件进程来隔离,从而保证插件崩溃时不会对浏览器产生太大影响。

2.浏览器执行HTTP请求的流程是什么?

浏览器发送HTTP请求到接收数据大致会执行以下几个操作:

  1. 构建请求:浏览器根据URL地址构建请求报文,它包括:①请求行,它由请求方法,请求URI及HTTP的版本信息组成;②请求头,比如:Cache-Control,Cookie等请求头信息;③请求体,请求体的类型可以通过Content-Type请求头来设置;

  2. 查找缓存:浏览器查找本地缓存中是否有本次请求的资源。有,则拦截请求,并加载本地缓存。无,则继续发送请求;

  3. 域名解析:通过DNS将地址栏的域名地址解析成可访问的IP地址;

  4. 等待TCP队列:谷歌浏览器有个机制,同一域名最多只能建立6个TCP,如果在同一域名下同时有10个请求发生,那么其中四个请求会进入排队等待状态,直至进行中的请求完成;

  5. 建立TCP链接:三次握手建立连接:第一步,客户端发送SYN(seq=x)给服务端请求建立连接;第二步,服务端接收SYN(seq=x),并返回SYN(seq=y,ACK=x+1)来应答客户端请求;第三步,客户端发送ACK(ack=y+1)应答服务端确认连接;

  6. 发送HTTP请求:到这一步浏览器才真正的将HTTP请求的报文数据发送到服务端;

  7. 返回请求:服务器返回给浏览器的响应报文也包含三部分:①响应行,它由协议版本,状态码等要素组成;②响应头,如:Content-Type,Access-Control-Allow-Origin等响应头信息;,③响应体,响应体的类型可以通过Content-Type响应头来设置;

  8. 断开连接:通常情况下,一旦服务器向客户端返回了请求数据,它就会关闭TCP连接。如果要开启长连接模式,则需要在请求头中设置Connection:Keep-Alive,TCP断开连接需要经过四次挥手这几个过程才能将TCP连接断开。

3.浏览器导航流程是什么?

在浏览器地址栏输入一个地址并开始导航,浏览器大致会执行以下几个操作:

  1. 地址栏输入内容:浏览器会根据地址栏输入的内容判断是“搜索内容”还是“URL地址”,如果是搜索内容,浏览器会使用默认搜索引擎加上搜索内容合成URL地址。如果是域名,则会加上协议并合成完整的URL;

  2. 按下回车键:浏览器通过IPC(进程间通信)将URL传给网络进程;

  3. 执行HTTP请求:网络进程接收到URL之后,发送HTTP请求,并将响应头信息回传给浏览器进程;

  4. 提交响应到渲染进程:浏览器进程发送CommitNavigation消息到渲染进程,并携带响应头信息;

  5. 渲染进程确认提交:渲染进程接收到CommitNavigation消息之后,便开始与网络进程建立数据管道,最后渲染进程会像浏览器进程发起“确认提交”的消息,来告诉浏览器进程,可以开始接收和解析页面数据了;

  6. 浏览器进程更新状态:到这一步,浏览器开始更新如:①前进后退的状态,②站点安全状态,③地址栏URL,④web页面等浏览器信息。

4.浏览器渲染流程是什么?

  1.  渲染进程将HTML解析成DOMTree
  2. 渲染引擎将CSS样式表解析成浏览器可以理解的styleSheets,通过计算(Recalculate Style)生成元素节点的样式(ComputedStyle)

  3. 创建布局树(LayoutTree),并计算元素的布局信息。这一步进行的操作即是“重排或称为回流”(Reflow)

  4. 对布局进行分层,并生成分层树(LayerTree)

  5. 为每个图层绘制列表,并将其提交到合成线程

  6. 合成线程将图层分成图块(Tile),并在光栅化线程池中将图块转换成位图。这一步进行的操作即是“重绘”(Paint)

  7. 合成线程发送制图块命令DrawQuad给浏览器进程

  8. 浏览器进程根据DrawQuad消息生成(Composite Layers)页面,并显示到屏幕上

5.界面图层是什么?

浏览器图层更像是画布,可以堆叠。浏览器中的界面是由一个或者多个图层组成的,而每个图层都会包含一个或者多个DOM节点。浏览器一般在以下几种情况下会创建新的图层来满足需要

  • 元素的样式拥有3D变换的CSS属性,如:“transform: translate3d(20px, 20px, 20px);”;

  • html中使用了canvas、video标签;

  • CSS样式中使用了will-change属性来告知浏览器将会产生的变化,从而使得浏览器可以提前为将要产生的变化做好优化准备工作;

6.V8引擎执行Javascript代码的过程?

  1. 生成抽象语法树:这个阶段需要经过词法分析和语法分析。词法分析过程,JS编译器将每一行代码拆分成一个个token(指的是语法上不可再分的最小的单个字符或字符串)。语法分析,这个阶段是将词法分析生成的token数据,根据语法规则转换成AST(抽象语法树),如果源码不符合语法规则,这一步就会抛出“语法错误”。

  2. 生成字节码:字节码是介于AST和机器码之间的一种代码,但是与特定类型的机器码无关,字节码需要通过解释器将其转换为机器码之后才能执行,由于机器码占用的内存空间要远大于字节码,因此使用字节码可以减少系统的内存使用。

  3. 执行代码:解释器在解释执行字节码的期间,收集代码信息,并判断是否有代码会被重复执行多次。如果会,就被标记为热点代码,并将其转换为机器码,保存起来,下次执行时直接使用转换好的机器码,这一过程将代码标记为热代码,编译后保存可执行机器码的过程我们称为即时编译(JIT)。在V8执行的过程中,我们会发现基于JIT(即时编译),V8的执行效率往往和执行时间成正比。

7.界面重绘,重排是什么意思?

当一个元素的外观属性发生变化后,浏览器会根据元素的新属性重新绘制图层,这个过程中产生的浏览器行为我们称为重绘。

会产生重绘的CSS属性,如下:

  • 颜色相关:① color,  ② border-color,  ③ outline-color,  ④ backgound-color;

  • 其他:① visibility,  ② text-decoration,  ③ background,  ④ outline,⑤ box-shadow

当一个元素的“几何属性变化”或者“获取其几何属性值”的时候,浏览器会进行重排操作。

重绘优化方式:由于重绘是以图层为单位的,某个图层中的一个元素由于外观发生改变产生的重绘行为,会使得整个图层都重新绘制一遍。因此,我们应该把要发生外观变化的元素放在一个单独的图层中,从而实现优化效果。

重排优化方式:重排过程大部分情况会产生重绘操作,因此这个过程更耗时。重排也是以图层为单位的。因此,我们应该尽量减少重排的次数且为重排的元素提供一个单独的图层,从而实现优化效果。

针对重绘和重排,具体的优化方式如下所示:

  • 改变元素的位置时使用transform代替left和top的方式;

  • 在符合实际场景的情况下,使用visibility代替display控制元素的显示隐藏;

  • 将多次样式修改合并成一次;

  • 将DOM元素设置不可见后,集中进行样式操作,然后恢复显示;

  • JS动画使用requestAnimationFrame方法实现,使用cancelAnimationFrame来关闭动画。之所以该方法可以优化JS动画,主要是由于其回调函数每次都会在重绘之前执行。其次回调函数会由浏览器的帧率来决定其执行时机,而浏览器的帧率也会基于当前显示设备的帧率进行计算,已达到最佳显示效果。除此之外requestAnimationFrame实现的动画也会根据浏览器界面的激活状态来决定其是否暂停执行,这也降低了浏览器产生的额外开销,从而达到了优化效果。前面说的这些优点都是使用setInterval这样的周期函数很难实现的。

  • 通过documentFragment接口批量更新或者挂载元素,使用document.createDocumentFragment创建文档碎片,然后再通过appendChild方法将文档碎片绑定的目标DOM元素上;

8.浏览器缓存是什么?

缓存定义:缓存指的是通过某种存储方式将用户需要的数据存储起来,下次用户需要浏览数据可以直接从缓存中读取,而不用重新发送请求。

缓存分类有以下几种

  • 强缓存:浏览器根据响应头信息(Expires,Cache-Control)决定是否直接读取本地缓存数据。命中强缓存的请求,浏览器是不会向服务器发送真实请求的,而是从本地缓存中获取数据;
  • 协商缓存:浏览器根据上一次请求的响应头信息(Last-Modified,ETag),包装新的请求头信息(If-Modified-Since,If-None-Match)向服务器发送请求,服务器根据请求头信息判断是否命中协商缓存;

缓存优点:①减少了请求的次数,从而减少了服务器的压力,从而提升了网站性能;②提升了客户端加载网页的速度,从而给用户带来更好的体验。

参考资料:【浏览器】浏览器的缓存机制_南栀~zmt的博客-CSDN博客_浏览器缓存机制

9.如何进行跨页签通信?

  • 不跨域:可使用localStorage来实现通信,只需要主页面操作localStorage的值,同源下的界面可通过监听storage事件来获取存储的值,从而实现页签通信。

  • 跨域:可使用postMessage来实现通信,只需要主页面通过otherWindow.postMessage(这里的otherWindow是子窗口的引用)发送消息,在子窗口中通过注册message事件监听来获取发送过来的数据。如果不是子窗口,则需要使用iframe作为“桥”来实现跨域通信。

参考资料:第一篇《跨标签页通信》_鱼叔子的博客-CSDN博客_跨标签页通讯

10.在谷歌浏览器的开发者工具中的console面板中无法通过编写js代码触发某个元素的focus事件。记录一下,暂时不知道具体原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值