Open yihan12 opened 10 months ago
注:这题胜在区分度高,知识点覆盖广,再不懂的人,也能答出几句, 而高手可以根据自己擅长的领域自由发挥,从URL规范、HTTP协议、DNS、CDN、数据库查询、 到浏览器流式解析、CSS规则构建、layout、paint、onload/domready、JS执行、JS API绑定等等;
1、浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
2、调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
3、通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
4、进行HTTP协议会话,客户端发送报头(请求报头);
5、进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
6、进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
7、处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
8、浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
9、文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
10、页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。
浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;
服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
载入解析到的资源文件,渲染页面,完成。
浏览器渲染机制
首先,浏览器的渲染机制中有几个基本概念名称:
(1)、DOM:浏览器将HTML解析成树形的数据结构
(2)、CSSOM:浏览器将CSS解析成树形的数据结构
(3)、Render Tree:DOM和CSSOM合并后生成Render Tree(渲染树)
(4)、Layout:计算出Render Tree每个节点的具***置
(5)、Painting:通过显卡,将Layout后的节点内容分别呈现到屏幕上
浏览器整个渲染流程如下:
(1)、用户输入一个URL后,浏览器就会向服务器发出一个请求,请求URL对应的资源
(2)、接到服务器的响应内容后,浏览器的HTML解析器,会将HTML文件解析成一颗DOM树,DOM树的构建是一个深度遍历的过程,当前节点的所有子节点都构建完成后,才会去构建当前节点的下一个兄弟节点
(3)、将CSS解析成CSSOM树
(4)、根据DOM树与CSSOM树,构建Render Tree
(5)、浏览器会根据Render Tree能知道网页中哪些有节点,各个节点的CSS,以及各个节点的从属关系
(6)、计算出每个节点在屏幕中的位置后,最后一步就是Painting,根据计算出的规则,把内容画到屏幕上
注意:
浏览器在获得HTML文件后,是自上而下的加载,并在加载过程中进行解析与渲染
加载过程中:
遇到外部CSS文件和图片等静态资源时,浏览器会另外发送一个异步请求
遇到js文件时,HTML文件会挂起渲染的进程,等待js文件加载完毕后,再继续进行渲染,因为js可能会修改DOM,导致后续HTML资源白白加载,这也是为什么建议将js文件写在底部body标签前
请问你了解什么是重绘?什么是回流?两者有何区别?
重绘:
更换某个元素颜色,这样的行为是不影响页面布局,DOM树不会变化,但颜色变了,使该元素所在的 Layer 重新渲染
常见情况:
(1)、回流必定引发重绘,但重绘也会单独触发
(2)、背景色、颜色、字体改变(字体大小改变,会触发回流)
回流:
增删DOM节点,或修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,需要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染
常见情况:
(1)、页面渲染初始化
(2)、DOM树变化(添加或者删除可见的DOM元素、元素位置改变)
(3)、Render树变化(元素尺寸改变:边距、填充、边框、宽度和高度)
(4)、浏览器窗口尺寸改变,resize事件发生
(5)、内容改变:文本改变或者图片大小改变而引起的计算值宽度和高度改变;
(6)、查询布局信息,包括offestLeft/Top/Width/Height、scrollLeft/Top/Width/Height、clientLeft/Top/Width/Height、浏览为了返回最新值,会触发回流
请问在浏览器中输入 URL后,浏览器会做哪些工作?
从输入URL到渲染出整个页面包括三个部分:
(1)、DNS解析URL
DNS解析就是寻找哪个服务器上有请求的资源,因为ip地址不易记忆,一般会使用URL域名(如www.baidu.com)作为网址,DNS解析就是将域名“翻译”成IP地址
具体过程:
a、浏览器缓存:浏览器会按照一定的频率,缓存DNS记录
b、操作系统缓存:如果浏览器缓存中找不到需要的DNS记录,就会取操作系统中找
c、路由缓存:路由器也有DNS缓存
d、ISP的DNS服务器:ISP有专门的DNS服务器应对DNS查询请求
e、根服务器:ISP的DNS服务器找不到,就要向根服务器发出请求,进行递归查询
(2)、浏览器发送请求与服务器交互
a、浏览器利用tcp协议通过三次握手与服务器建立连接
http请求包括header和body,header中包括请求的方式(get和post)、请求的协议 (http、https、ftp)、请求的地址ip、缓存cookie,body中有请求的内容
b、浏览器根据解析到的IP地址和端口号发起http的get请求
c、服务器接收到http请求之后,开始搜索html页面,并使用http返回响应报文
d、若状态码为200显示响应成功,浏览器接收到返回的HTML页面后,开始渲染页面
(3)、浏览器对接收到的HTML页面进行渲染
a、浏览器根据深度遍历的方式把HTML节点遍历成DOM树
b、将CSS解析成CSSOM树
c、将DOM树和CSSOM树构造成Render树
d、根据Render树计算所有节点在屏幕中的位置,进行布局(回流)
e、遍历Render树并调用硬件API绘制所有节点(重绘)
所以以下几个动作可能会导致性能问题:
渲染
当浏览器进程获取到 HTML 的第一个字节开始,会通知渲染进程开始解析HTML,将 HTML 转换成 DOM 树,并进入渲染流程。一般所有的浏览器都会经过五大步骤,分别是:
PARSE:解析 HTML,构建 DOM 树。
STYLE:为每个节点计算最终的有效样式(CSS-CSSOM)。
LAYOUT:为每个节点计算位置和大小等布局信息。
PAINT:绘制不同的盒子,为了避免不必要的重绘,将会分成多个层进行处理。
COMPOSITE & RENDER:将上述不同的层合成为一张位图,发送给 GPU,渲染到屏幕上。为了提高浏览器的渲染性能,通常的手段是保证渲染流程不被阻塞,避免不必要的绘制计算和重排重绘,利用 GPU 硬件加速等技术来提高渲染性能。
次级资源加载
一个网页通常会使用多个外部资源,如图片、JavaScript、CSS、字体等。主线程在解析 DOM 的过程中遇到这些资源后会一一请求。为了加速渲染流程,会有一个叫做预加载扫描器(preload scanner)线程并发运行。如果 HTML 中存在 img 或 link 之类的内容,则预加载扫描器会查看 HTML parser 生成的标记,并发送请求到浏览器进程的网络线程获取这些资源。
JavaScript 可能阻塞解析
当 HTML 解析器发现 script 标签时,会暂停 HTML 的解析,转而开始加载、解析和执行 JavaScript。因为 JS 可能会改变 DOM 的结构。如果不想因 JS 阻塞HTML 的解析,可以为 script 标签添加 defer 属性或将 script 放在 body 结束标签之前,浏览器会在最后执行 JS 代码,避免阻塞 DOM 构建。
CSSOM
CSSOM 和 DOM 是并行构建的,构建 CSSOM 不会阻塞 DOM 的构建。但CSSOM 会阻塞 JS 的执行,因为 JS 可能会操作样式信息。虽然 CSSOM 不会阻塞 DOM 的构建,但在进入下一阶段之前,必须等待 CSSOM 构建完成。这也是通常所说的 CSSOM 会阻塞渲染。
浏览器渲染性能的优化
上一节中是一轮典型的浏览器渲染流程,在流程完成之后,DOM、CSSOM、LayoutObject、PaintLayer 等各种树状数据结构都会保留下来,以便在用户操作、网络请求、JS 执行等事件发生时,重新触发渲染流程。
2.1 减少渲染中的重排重绘
2.2 优化影响渲染的资源在浏览器解析
HTML 的过程中,CSS 和 JS 都有可能对页面的渲染造成影响。
CSSOM
像
和它的子节点以及任何具有 display: none 样式的结点,例如 script { display: none; }(在 user agent stylesheets 可以看到这个样式)这些标签将不会显示,也就是它们不会出现在 Render 树上。具有 visibility: hidden 的节点会出现在 Render 树上,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理的默认值,因此上面代码示例中的 script 节点将不会包含在 Render 树中。每个可见节点都应用了其 CSSOM 规则。Render 树保存所有具有内容和计算样式的可见节点——将所有相关样式匹配到 DOM 树中的每个可见节点,并根据 CSS 级联确定每个节点的计算样式。
第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。
总结
综上所述,我们得出这样的结论:
浏览器工作流程:构建DOM -> 构建CSSOM -> 构建渲染树 -> 布局 -> 绘制。
CSSOM会阻塞渲染,只有当CSSOM构建完毕后才会进入下一个阶段构建渲染树。
通常情况下DOM和CSSOM是并行构建的,但是当浏览器遇到一个不带defer或async属性的script标签时,DOM构建将暂停,如果此时又恰巧浏览器尚未完成CSSOM的下载和构建,由于JavaScript可以修改CSSOM,所以需要等CSSOM构建完毕后再执行JS,最后才重新DOM构建。
()