# 从输入网址后发生了什么

用户输入 URL，浏览器会根据用户输入的信息判断是搜索还是网址，如果是搜索内容，就将搜索内容+默认搜索引擎成新的 URL；如果用户输入的内容符合 URL 规则，浏览器就会根据 URL 协议，在这段内容上加上协议成合法的 URL

## 一整套过程

1. DNS 域名解析
2. 建立 tcp 连接
3. 发送 http 请求
4. 服务器处理请求
5. 返回响应结果
6. 关闭 tcp 连接
7. 浏览器解析 html
8. 浏览器布局渲染

把他们扩展一下就是 dns: 从客户端到本地服务器属于递归查询， 而 dns 服务器之间的交互属于迭代查询。

建立 tcp 连接：三次握手原理 客户端发送 syn 标志的数据包给服务端，服务端收到后，回传一个带有 syn/ack 标志的数据包已示传达确认信息，最后客户端在回传一个带有 ack 标志的数据包，代表握手结束，连接成功。

发送 http 请求：与服务器建立连接后， 就向服务器发起请求了

服务器处理请求： 服务器收到请求后由 web 服务器处理请求，web 服务器解析用户请求，知道了需要调度哪些资源文件，在通过相应的这些资源文件处理用户请求和参数，并调用数据库信息，最后将结果通过 web 服务器返回给浏览器客户端。

关闭 TCP 连接： 与创建 tcp 连接的三次握手类似，关闭 tcp 连接，需要 4 次握手。

客户端： 我这边没有数据要给你了，关闭连接吧

服务端： 好的，我看我这边还有数据要传给吗

服务端： 我这边也没有数据要传给你了，咱们可以关闭连接了

客户端： 好的。

浏览器解析 html： 渲染树与 dom 树不同，渲染树中并没有 head、display 为 none 等不必显示的节点。

浏览器布局渲染： 根据 css 样式，即每个节点在页面中的大小和位置等。html 默认是流式布局，css 和 js 会打破这种布局。改变 dom 的外观样式以及大小和位置。

## 第一步 DNS 涉及到的东西

通过 dns 解析域名的实际 ip 地址

dns 解析首先会从你的浏览器的缓存中去寻找是否有这个网址对应的 ip 地址，如果没有就向 os 系统的 dns 缓存中寻找，如果没有就是路由器的 dns 缓存，如果没有就是 isp 的 dns 缓存中寻找。 浏览器-> 系统-> 路由器-> isp

## 期间涉及到的缓存有哪些

### dns 缓存

查询浏览器以及操作系统中的 DNS 缓存，再查询本地 host 文件，如果还未找到的话，就向自己的 DNS 服务器查询。 浏览器缓存->系统缓存->路由器缓存->IPS 服务器缓存->根域名服务器缓存->顶级域名服务器缓存->主域名服务器缓存。

1. 浏览器搜索自身的 dns 缓存，
2. 搜索操作系统自身的 dns 缓存
3. 读取本地的 hosts 文件，查询有无域名对应解析
4. 浏览器发起的 dns

### 浏览器缓存机制

1. 查询浏览器中是否有对应网页的强缓存（Expires 或 Cache-Control 未过期），如果命中缓存则直接取本地磁盘的 html（状态码为 200， 内存或者磁盘）
2. 如果没有命中强缓存，则会向浏览器发起请求（先进行下一步的 TCP 连接），服务器通过 Etag 和 last-Modify 来与服务器确认返回的响应是否被更改（协商缓存），若无更改返回状态码（304 Not Modified）,浏览器取本地缓存；
3. 若强缓存和协商缓存都没有命中则返回请求结果

本地存储

四个和缓存有关的

* cache-control 相对时间 优先级高于 expires
* expires 绝对时间
* last-modified 文件最后修改的时间
* ETag 生成 hash 值， 优先级高于 last-modified

[浏览器缓存策略详解.md](liu-lan-qi-huan-cun-ce-le-xiang-jie)

### cdn 缓存与回源

DNS 可以返回一个合适的机器的 IP 给用户，例如可以根据每台机器的负载量，该机器离用户地理位置的距离等等，这种过程就是 DNS 负载均衡，又叫做 DNS 重定向。大家耳熟能详的 CDN (Content Delivery Network)就是利用 DNS 的重定向技术，DNS 服务器会返回一个跟用户最接近的点的 IP 地址给用户，CDN 节点的服务器负责响应用户的请求，提供所需的内容。

cdn 往往用来存放静态资源

* 『缓存』就是说我们把资源 copy 一份到 cdn 服务器上这个过程。
* 『回源』就是说 cdn 发现自己没有这个资源（一般是缓存的数据过期了），转头向根服务器（或者它的上层服务器）去要这个资源的过程。

## 浏览器的绘制

[浏览器的渲染进程](liu-lan-qi-de-xuan-ran-jin-cheng)

## DNS 预解析

dns Prefetch, 即 dns 预获取, 是前端优化的一部分, 一般来说, 在优化中与 dns 有关的有两点: 一是减少 dns 的请求次数, 另一个就是进行 dns 预获取.

减少 dns 解析时间和次数是个很好的优化方式。DNS Prefetching 是让具有此属性的域名不需要用户点击链接就在后台解析，而域名解析和内容载入是串行的网络操作，所以这个方式能 减少用户的等待时间，提升用户体验 。

默认情况下浏览器会对页面中和当前域名（正在浏览网页的域名）不在同一个域的域名进行预获取，并且缓存结果，这就是隐式的 DNS Prefetch。如果想对页面中没有出现的域进行预获取，那么就要使用显示的 DNS Prefetch 了。

dns prefetch 应该经量的放在网页的前面, 推荐放在 \<meta charset="UTF-8">

```js
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//www.img.com">
<link rel="dns-prefetch" href="//www.api.com">
<link rel="dns-prefetch" href="//www.test.com">
```

如果要禁止隐式的 dns prefetch, 可以使用以下的标签

```js
<meta http-equiv="x-dns-prefetch-control" content="off">
```
