让前端飞Web前端之路js基础

说一说从 URL 输入到页面呈现到底发生了什么?

2020-04-27  本文已影响0人  旭哥_

前言

这是面试过程中一道高频考题。

从面试官的角度思考:

基本回答:

如果应聘者只回答了上述步骤,很多关键步骤(前端应该了解的知识点)没有提及,很有可能达不到面试官想要的回答效果。

笔者针对一些关键步骤,具体展开说明。让这道题成为我们面试考卷中的加分项

网络请求

构建请求

浏览器会构建请求行:

// 请求方法是 GET,路径为根路径,HTTP 协议版本为 1.1
GET / HTTP/1.1

然后根据 Cache-control 和 Expires 字段,检查强缓存,如果命中直接使用,否则进入下一步。关于强缓存,如果不清楚可以参考下图:

DNS 解析

由于我们输入的是域名,而数据包是通过IP地址传给对方的。因此我们需要得到域名对应的IP地址。这个过程需要依赖一个服务系统,这个系统将域名和 IP 一一映射,我们将这个系统就叫做DNS(域名系统)。

DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。得到具体 IP 的过程就是DNS解析。

DNS 是一个网络服务器,我们的域名解析简单来说就是在 DNS 上记录一条信息记录。

例如 baidu.com 220.114.23.56(服务器外网IP地址)80(服务器端口号)

浏览器通过域名去查询 URL 对应的 IP :

建立 TCP 连接

TCP 三次握手的过程如下:

谢希仁著《计算机网络》中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。

发送 HTTP 请求

现在 TCP 连接建立完毕,浏览器可以和服务器开始通信,即开始发送 HTTP 请求。浏览器发 HTTP 请求要携带三样东西:请求行请求头请求体

[图片上传失败...(image-f9c53-1587981019451)]

1.请求行包含请求方法、URL、协议版本

POST /user.html HTTP/1.1

2.请求头包含请求的附加信息,由关键字/值对组成,如下

// 服务器可以接受的文件格式
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng;q=0.8,application/signed-exchange;v=b3
// 指定浏览器可以支持的 Web 服务器返回的内容压缩编码类型
Accept-Encoding: gzip, deflate, br
// 浏览器支持的语言
Accept-Language: zh-CN,zh;q=0.9
// 缓存机制
Cache-Control: no-cache
// 是否需要持久连接
Connection: keep-alive
// 发送该请求域名下所有 Cookie 值到服务器
Cookie: /* 省略cookie信息 */
// 指定请求的服务器的域名和端口号
Host: www.baidu.com
Pragma: no-cache
Upgrade-Insecure-Requests: 1
// 用户代理 UA,包含发出请求的用户信息
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1

3.请求体,可以承载多个请求参数的数据,包含回车符、换行符和请求数据,一般在 POST 方法下存在。

网络响应

跟请求部分类似,网络响应具有三个部分:响应行响应头响应体

1.响应行包含:协议版本,状态码,状态码描述

HTTP/1.1 200 OK

状态码规则如下:

2.响应头部包含响应报文的附加信息,由 名/值 对组成,如下:

// 缓存机制
Cache-Control: no-cache
Connection: keep-alive
Content-Encoding: gzip
// 表示具体请求中的媒体类型信息,决定浏览器将以什么形式、什么编码读取这个文件
Content-Type: text/html;charset=utf-8
// 原始服务器消息发出的时间
Date: Wed, 04 Dec 2019 12:29:13 GMT
// Web 服务器软件名称
Server: apache
// 由服务器端向客户端发送 cookie
Set-Cookie: rsv_i=f9a0SIItKqzv7kqgAAgphbGyRts3RwTg%2FLyU3Y5Eh5LwyfOOrAsvdezbay0QqkDqFZ0DfQXby4wXKT8Au8O7ZT9UuMsBq2k; path=/; domain=.baidu.com

这里注意下 Set-Cookie 中关于网络安全方面的两个值:HttpOnly、SameSite

设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS)。

SameSite=Lax 允许服务器设定一则 cookie 不随着跨域请求一起发送,这样可以在一定程度上防范跨站请求伪造攻击(CSRF)。

响应完成之后要判断 Connection 字段,如果请求头或响应头中包含 Connection: Keep-Alive ,表示建立了持久连接,这样 TCP 连接会一直保持,之后请求统一站点的资源会复用这个连接。
否则断开 TCP 连接, 请求-响应流程结束。

3.响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据

总结浏览器端的网络请求过程:

image

浏览器解析渲染页面

image

浏览器解析渲染页面分为以下五个步骤:

回流时,以上流程会重新走一遍。重绘时,会重新计算样式,跳过中间步骤直接生成绘制列表。可见,重绘不一定导致回流,但回流一定发生了重绘。

image

构建 DOM 树

样式计算

CSS 样式来源一般为三种:

格式化样式表

浏览器无法直接识别 CSS 样式文本,这里渲染引擎接收到 CSS 文本之后将其转化为一个结构话的对象,即 styleSheets 。

可以在浏览器控制台输入 document.styleSheets 来查看这个最终结构(包含上述三种 CSS 来源)。

标准化样式属性

有一些渲染引擎不容易直接理解的 CSS 样式数值,需要在计算样式之前将它们标准化。如:em -> pxred -> #ff0000bold -> 700 等等。

计算每个节点的具体样式

计算具体样式主要遵循两个规则:继承层叠

计算完样式之后,所有样式值会被挂载到 window.getComputedStyle 中,也就是可以通过 JS 获取计算后的样式。

生成布局树

布局树生成主要分两部:

布局树只包含可见元素,对于 head 标签和设置了 display: none 的元素将不会被放入其中。

如果想了解布局的细节,可以读一读人人 FED 团队的文章从Chrome源码看浏览器如何layout布局

构建图层树

这里分两种情况,一种是显式合成,一种是隐式合成

显式合成

一、拥有层叠上下文的节点

层叠上下文也基本上是有一些特定的 CSS 属性创建的,一般有以下情况:

  1. HTML 根元素本身就具有层叠上下文

  2. 普通元素设置 position 不为 static 并且设置了 z-index 属性,会产生层叠上下文

  3. 元素的 opacity 值不是 1

  4. 元素的 transform 值不是 none

  5. 元素的 filter 值不是 none

  6. 元素的 isolation 值是 isolate

  7. will-change 指定的属性值为上面任意一个

二、需要剪裁的地方

比如一个 div,你只给他设置 100 * 100 像素的大小,而你在里面放了非常多的文字,那么超出的文字部分就需要被剪裁。当然如果出现了滚动条,那么滚动条会被单独提升为一个图层。

隐式合成

简单说就是层叠等级低的节点被提升为单独的图层之后,那么所有层叠等级比它高的节点都会成为一个单独的图层。

这个隐式合成其实隐藏着巨大风险,如果在一个大型应用中,当一个 z-index 比较低的元素被提升为单独图层之后,层叠在它上面的元素统统会被提升为单独的图层,可能会增加上千个图层,大大增加内存压力,甚至直接让页面崩溃。这就是层爆炸的原理

当需要 repaint 时,只需要 repaint 本身,而不会影响到其他层。

生成绘制列表

渲染引擎会将图层的绘制拆分成一个个绘制指令,比如先画背景、再描绘边框......然后将这些指令按顺序组合成一个待绘制列表。

大家可以 F12 打开 Chrome 开发者工具,在设置栏展开 more tools ,然后选择 Layers 面板,就能看到绘制列表了。

后面就是渲染进程的主线程把绘制列表提交给合成线程。然后合成线程选择视口附近的图块,把它交给栅格化线程池生成位图。

栅格化操作完成后,合成线程会生成一个绘制指令 DrawQuad,并发送给浏览器进程。浏览器进程中的 viz 组件 接收到命令,把页面内容绘制到内存,也就是生成了页面。

断开连接

当数据传送完毕,需要断开 TCP 连接,此时发起四次挥手。

image

参考文章

感谢

如果本文对你有帮助,就点个赞支持下吧!感谢阅读。

上一篇下一篇

猜你喜欢

热点阅读