浏览器输入网址到渲染出页面流程

浏览器输入网址到渲染出页面流程

详细阅读:github - 当你在浏览器中输入 google.com 并且按下回车之后发生了什么?

  1. 输入网址

  2. 浏览器进行地址解析,将解析出的域名进行 DNS 解析

    url解析:网络标准规定了URL只能是字母和数字,还有一些其它特殊符号(-_.~ ! * ‘ ( ) ; : @ & = + $ , / ? # [ ],但是有部分特殊字符需要进行编码否则会出现歧义。使用encodeURI(...)encodeURIComponent(...)进行编码。使用decodeURI(...)decodeURIComponent(...)进行解码。规则采用UTF-8

    请注意,encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 “&”, “+”, 和 “=” 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而encodeURIComponent这个方法会对这些字符编码。

    DNS解析: 先查看浏览器 DNS 缓存中是否有域名对应的 IP ,如果没有,则看操作系统 DNS 缓存中是否有对应的 IP (例如Windows的hosts文件),依旧没有就对本地区DNS 服务器发起请求,如果还是没有,就直接到 Root Server域名服务器请求解析。(非转发模式)

    一般使用 UDP 协议向 DNS 服务器进行寻址。

    DNS查询有两种模式,转发模式和非转发模式。转发模式,第一台DNS服务器查找不到,会转发到其他DNS服务器上查找,如果其他DNS服务器上也没有就会到根服务器查找。

    前端DNS优化:可以在html页面头部写入dns缓存地址

    <meta http-equiv="x-dns-prefetch-control" content="on" />
    <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
  3. 通过 IP 寻址和 ARP ,找到目标服务器地址。

    获取到 IP 后,直接通过 IP 寻址找到 IP 对应的服务器,然后通过 ARP 协议找到服务器的 MAC 地址。

  4. 进行 TCP 三次握手,建立 TCP 连接。

    • 第一次握手:主机A发送位码为SYN=1的TCP包给服务器,并且随机产生一个作为确认号(这是tcp包的一部分),主机B收到SYN码后直到A要求建立连接;
    • 第二次握手:主机B收到请求后,向A发送确认号(主机A的seq+1),syn=1,seq = 随机数 的TCP包;
    • 主机A收到后检查确认号是否正确,即第一次A发送的确认号是否+1了,以及位码ack是否为1,若正确,主机A会再发送确认号(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。

    三次握手

  5. 浏览器发送数据请求,等待服务器响应。

    根据数据请求判断是否使用浏览器缓存

    如果使用浏览器强缓存,则不会对服务器进行请求,直接响应数据请求,返回浏览器缓存数据。

    如果是协商缓存机制,会向服务器进行询问缓存使用结果,注意启发式缓存。

    如果不使用缓存,则会向服务器请求数据。

  6. 服务器处理请求,并对请求做出响应。

  7. 浏览器收到服务器响应,得到网页代码。

  8. 渲染页面

    HTML解析:HTML词法分析和语法分析

    外部样式、脚本加载(async / defer)

    • 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree);

      JS会阻塞DOM树的解析,但是CSS不会阻塞DOM树的解析。所以如果不得不将JS文件放在头部,可以将JS文件放在CSS文件引入之上。且JS文件中最好不要有修改样式的操作,不然会和预期结果不一致,同时也无法进行DOM操作。

    • 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树;

    • 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);

      渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。

      • 浏览器从DOM树的根节点开始遍历每个可见节点。
      • 对于每个可见节点,找到CSSOM树中对应的规则,并应用它们。
      • 根据每个可见节点以及其对应的样式组合生成渲染树。
    • 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置;

    • 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成;

    • 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件);

    • 回流(Reflow / 重排):当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

      回流操作:页面首次渲染、浏览器窗口大小发生改变、元素尺寸或位置发生改变、元素内容变化、元素字体大小变化、添加或删除可见的DOM元素等

      回流必将引起重绘,重绘不一定会引起回流。回流比重绘代价要更高

      获取 document.body.offsetHeight 等一些数据会引起浏览器重绘。

      参考资料:中文翻译:是什么导致重排英语原文

    • 重绘(Repaint):当页面中元素样式的改变并不影响它在文档流中的位置时(例如:colorbackground-colorvisibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

      更多资料:基础系列-重绘与回流

    HTML词法分析和语法分析,CSS解析, 合成图层、合成线程调用光栅化线程池,生成位图后浏览器进程间通信过程,显卡缓存与显示器的关系

html渲染流程

  1. 浏览器断开连接,四次挥手。

    一个http请求-响应,就会触发一次三次握手,四次挥手。

    http 1.1 有相关长连接(keep-alive)设置。一个长连接会保持一段时间,重复用于发送一系列请求,节省了新建 TCP 连接握手的时间,还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着:连接在空闲一段时间后会被关闭(服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间)。

    更多阅读:计算机网络-HTTP系列

四次挥手

参考链接

阿里面试官问“说一下从 url 输入到返回请求的过程”的难度就是不一样!

两张动图-彻底明白TCP的三次握手与四次挥手

从URL输入到页面展现到底发生什么

原来 CSS 与 JS 是这样阻塞 DOM 解析和渲染的

推荐:面试官,不要再问我三次握手和四次挥手

推荐:浏览器的回流与重绘 (Reflow & Repaint) – 掘金