防抖:
防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
防抖就是将一段时间内连续的多次触发转化为一次触发。
- 应用
有个输入框,输入之后会调用接口,获取联想词。但是,因为频繁调用接口不太好,所以我们在代码中使用防抖功能,只有在用户输入完毕的一段时间后,才会调用接口,出现联想词。
节流
节流:指定时间间隔内只会执行一次任务。
- 应用:
- 懒加载要监听计算滚动条的位置,使用节流按一定时间的频率获取。
- 用户点击提交按钮,假设我们知道接口大致的返回时间的情况下,我们使用节流,只允许一定时间内点击一次。
防抖和节流的目的都是为了减少不必要的计算,不浪费资源,只在适合的时候再进行触发计算。
在某些特定的工作场景,我们就可以使用防抖与节流来减少不必要的损耗。
重绘
重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少。
- 常见的重绘操作有:
- 改变元素颜色
- 改变元素背景色
回流
又叫重排(layout)。当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
- 常见的回流操作有:
- 页面初次渲染
- 浏览器窗口大小改变
- 元素尺寸/位置/内容发生改变
- 元素字体大小变化
- 添加或者删除可见的 DOM 元素
- 激活 CSS 伪类(:hover……)
回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。
在工作中我们要如何避免大量使用重绘与回流呢?
避免频繁操作样式,可汇总后统一一次修改
尽量使用 class 进行样式修改,而不是直接操作样式
减少 DOM 的操作,可使用字符串一次性插入
浏览器解析 URL
- 用户输入 URL 地址。
- 对 URL 地址进行 DNS 域名解析。
- 建立 TCP 连接(三次握手)。
- 浏览器发起 HTTP 请求报文。
- 服务器返回 HTTP 响应报文。
- 关闭 TCP 连接(四次挥手)。
- 浏览器解析文档资源并渲染页面。
浏览器渲染页面的过程
浏览器通过 HTMLParser 根据深度遍历的原则把 HTML 解析成 DOM Tree。
浏览器通过 CSSParser 将 CSS 解析成 CSS Rule Tree(CSSOM Tree)。
浏览器将 JavaScript 通过 DOM API 或者 CSSOM API 将 JS 代码解析并应用到布局中,按要求呈现响应的结果。
根据 DOM 树和 CSSOM 树来构造 render Tree。
layout:重排(也可以叫回流),当 render tree 中任一节点的几何尺寸发生改变,render tree 就会重新布局,重新来计算所有节点在屏幕的位置。
repaint:重绘,当 render tree 中任一元素样式属性(几何尺寸没改变)发生改变时,render tree 都会重新画,比如字体颜色,背景等变化。
paint:遍历 render tree,并调动硬件图形 API 来绘制每个节点。
DNS 解析
DNS(Domain Name System)是 域名系统 的英文缩写,提供的服务是用于将主机名和域名转换为 IP 地址的工作:
所以,当用户在浏览器输入 http://jsliang.top 时,DNS 经历了以下步骤:
- 浏览器根据地址,在自身缓存中查找 DNS(域名服务器) 中的解析记录。如果存在,则直接返回 IP 地址;如果不存在,则查找操作系统中的 hosts 文件是否有该域名的 DNS 解析记录,如果有就返回。
- 在条件 1 中的浏览器缓存或者操作系统的 hosts 文件中都没有这个域名的 DNS 解析记录,或者已经过期,则向域名服务器发起请求解析这个域名。
- 先向本地域名服务器中请求,让它解析这个域名,如果解析不了,则向根域名服务器请求解析。
- 根服务器给本地域名服务器返回一个主域名服务器。
- 本地域名服务器向主域名服务器发起解析请求。
- 主域名服务器接收到解析请求后,查找并返回域名对应的域名服务器的地址。
- 域名服务器会查询存储的域名和 IP 的映射关系表,返回目标 IP 记录以及一个 TTL(Time To Live)值。
- 本地域名服务器接收到 IP 和 TTL 值,进行缓存,缓存的时间由 TTL 值控制。
- 将解析的结果返回给用户,用户根据 TTL 值缓存在本地系统缓存中,域名解析过程结束。
TCP 三次握手
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
三次握手:
第一次握手:起初两端都处于 CLOSED 关闭状态,Client 将标志位 SYN 置为 1,随机产生一个值 seq = x,并将该数据包发送给 Server,Client 进入 SYN-SENT 状态,等待 Server 确认。
第二次握手:Server 收到数据包后由标志位 SYN = 1 得知 Client 请求建立连接,Server 将标志位 SYN 和 ACK 都置为 1,ack = x + 1,随机产生一个值 seq = y,并将该数据包发送给Client以确认连接请求,Server 进入 SYN-RCVD 状态,此时操作系统为该 TCP 连接分配 TCP 缓存和变量。
第三次握手:Client 收到确认后,检查 ack 是否为 x + 1,ACK 是否为 1,如果正确则将标志位 ACK 置为 1,ack = y + 1,并且此时操作系统为该 TCP 连接分配 TCP 缓存和变量,并将该数据包发送给 Server,Server 检查 ack 是否为 y + 1,ACK 是否为 1,如果正确则连接建立成功,Client 和 Server 进入 established 状态,完成三次握手,随后 Client 和 Server 就可以开始传输数据。
四次挥手:
第一次挥手:Client 的应用进程先向其 TCP 发出连接释放报文段(FIN = 1,序号 seq = u),并停止再发送数据,主动关闭 TCP 连接,进入 FIN-WAIT-1(终止等待1)状态,等待 Server 的确认。
第二次挥手:Server 收到连接释放报文段后即发出确认报文段,(ACK = 1,确认号 ack = u + 1,序号 seq = v),Server 进入 CLOSE-WAIT(关闭等待)状态,此时的 TCP 处于半关闭状态,Client 到 Server 的连接释放。
注:Client 收到 Server 的确认后,进入 FIN-WAIT-2(终止等待2)状态,等待 Server 发出的连接释放报文段。
第三次挥手:Server 已经没有要向 Client 发出的数据了,Server 发出连接释放报文段(FIN = 1,ACK = 1,序号 seq = w,确认号 ack = u + 1),Server 进入 LAST-ACK(最后确认)状态,等待 Client 的确认。
第四次挥手:Client 收到 Server 的连接释放报文段后,对此发出确认报文段(ACK = 1,seq = u + 1,ack = w + 1),Client 进入 TIME-WAIT(时间等待)状态。此时 TCP 未释放掉,需要经过时间等待计时器设置的时间 2MSL 后,Client 才进入 CLOSED 状态。