从输入URL到页面加载,总体分为以下几个过程:
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
具体解析:
DNS解析
IP地址不易用户记忆,所以出现了比如www.baidu.com这样的网址,DNS解析就是将网址转换为IP地址。DNS解析是一个递归查询的过程,查询依次:本地域名服务器、根域名服务器、com顶级域名服务器,直到最后本地域名服务器得到IP地址并缓存到本地,供下次查询使用。
DNS优化:多级缓存:浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存、主域名服务器缓存.
TCP连接
在通过上一步的DNS域名解析后,获取到了服务器的IP地址,在获取到IP地址后,便会开始 建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接。
第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;
第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
发送HTTP请求
完整的HTTP请求包含 请求行, 请求报头和请求正文。
请求方法:get、post、put、delete、options、trace……
get与post区别 (get、post区别)
服务器处理请求并返回HTTP报文
HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。
状态码
- 1XX :指示信息–表示请求已接收,继续处理
- 2XX :请求已被成功接收
- 3XX :重定向
- 4XX :客户端错误
- 5XX :服务器断错误
常见的状态码:200、301、302、304、400、401、403、404、500
HTTP缓存机制
浏览器解析渲染页面
- HTML解析出DOM Tree
- CSS解析出 style rules
- 二者关联生成 render Tree
- Layout(布局)根据 render Tree 计算节点信息
- Painting 根据计算好的信息绘制整个页面
回流(reflow)与重绘(repaint):
- reflow : 当render树的一部分或者全部因为大小边距等问题发生改变而需要重建的过程,叫做回流
- repaint : 当诸如颜色背景等不会引起页面布局变化,而只需要重新渲染的过程叫做重绘
- 回流必将引起重绘,重绘不一定会引起回流
reflow的成本比repaint高,毕竟repaint不会涉及到布局。DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父结点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。
那么,什么操作会引起回流呢?
- 页面渲染初始化
- DOM结构变化,比如:删除某个节点
- render 树变化,比如:删除padding
- 窗口resize事件触发
- 激活CSS伪类(例如::hover)
- 查询某些属性或调用某些方法:
补充:现代浏览器会对频繁的回流或重绘操作进行优化:
浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。但在访问以下属性和方法时,浏览器会立刻清空队列。
1. offsetTop, offsetLeft, offsetWidth, offsetHeight
2. scrollTop/Left/Width/Height
3. clientTop/Left/Width/Height
4. width,height
5. 调用了getComputedStyle(), 或者 IE的 currentStyle
那么,我们应该如何避免呢?从CSS和JS两个方面谈:
CSS:
- 避免table布局
- 尽可能在DOM树的最末端改变class
- 避免设置多层内联样式
- 将动画效果应用到position属性为absolute或fixed的元素上。
- 避免使用CSS表达式(例如:calc())。
JavaScript:
- 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
- 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
- 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
- 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
- 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
连接结束
参考:
前端经典面试题: 从输入URL到页面加载发生了什么?
浏览器渲染页面过程与页面优化
浏览器的回流与重绘 (Reflow & Repaint)–腰花