Fork me on GitHub

从输入URL到页面加载发生了什么

大体过程

  1. 浏览器的地址栏输入URL并按下回车
  2. 浏览器检查当前URL是否存在缓存,并比较缓存是否过期
  3. DNS解析URL对应的IP
  4. 根据IP建立TCP连接(三次握手)
  5. HTTP发起请求
  6. 服务器处理请求,浏览器接收HTTP响应
  7. 渲染页面,构建DOM树
  8. 关闭TCP连接(4次挥手)
    image

具体过程的理解

浏览器缓存

大体上来说,可以分为强缓存和协商缓存

  • 强缓存

    • 强缓存主要通过http响应头中的==Cache-Control==和==Expires==两个字段来控制的

      1
      Expires: Wed, 21 Oct 2015 07:28:00 GMT
    • Expires是HTTP/1.0标准下的字段,上例表示该资源会在Wed, 21 Oct 2015 07:28:00 GMT之后过期,在这个时间点之前都是直接读取缓存不会发起请求的。这种方式有一个很大的问题就是服务器时间和本地时间可能不一致或者说是修改了本地时间也会造成缓存失败。

      1
      Cache-control: max-age=30
    • Cache-Control出现于HTTP/1.1,优先级高于Expires,上面这个表示该资源会在30秒之后过期,还有其他值可选,详情查看文档

  • 协商缓存
    • 如果缓存过期了,我们就要用协商缓存来解决问题,也就是说协商缓存是需要请求的,如果缓存有效会返回304。协商缓存通过HTTP的Last-modified,Etag字段进行判断
    • ==Last-Modified==是一个响应头字段,包含的是服务器认定的资源做出修改的日期及时间。下次请求时==If-Modified-Since==这个请求头字段会将Last-Modified发送给服务器,问服务器在该日期之后资源是否有更新,没有更新的话返回一个不带消息主体的304响应,有更新的话会返回新资源,并且响应头中会的Last-Modified会带有最新文件修改时间。
    • ==ETag==是一个响应头字段,类似于文件指纹,==If-None-Match==会将当前的ETag发送给服务器,服务器验证目前文件的ETag跟请求的ETag是否一致,如果一致,就返回不带任何内容的304未修改状态,如果不一致就返回最新资源。

DNS解析

DNS解析实际上就是将我们熟悉的域名解析成IP地址,也就是说当你在浏览器地址栏输入www.baidu.com时实际上访问的是这个域名对应的唯一IP地址,之所以当初要这样设计,是因为IP地址是由纯数字组成的,不便于记忆,而通过几级域名这种方式是便于我们人类记忆的。

DNS解析是一个递归查询的过程,从右到左解析的,有一个专门的DNS解析服务器,据说要经历8个步骤,具体过程我们了解不多,就不过多解释了。
image

建立TCP连接的三次握手

这一块InterviewMap讲的比较详细了
image

浏览器渲染页面的过程

  1. 处理HTML并构建DOM树
  2. 处理CSS构建CSSOM树
  3. 将DOM树和CSSOM树合并成一个渲染树
  4. 根据渲染树来布局,计算每个节点的位置(回流)
  5. 调用GPU绘制,合成图层,显示在屏幕上(重绘)
    image

总结

既然大体知道了浏览器从输入URL到页面加载的过程,那就可以针对这个过程一些可优化的点做优化,这也成了前端性能优化的一个重要部分,关于这部分,我会另写一篇文章来总结。

参考文章