从输入URL到页面呈现知识点详解

状态码

本文对一次完整的请求和渲染过程作了一个详细的总结,小伙伴若是以为本文对你稍微有所帮助的话,能够给笔者点个赞,有疑问的地方欢迎私聊。css

概述

  • DNS解析域名获取IP地址
  • 发起http请求(TCP三次握手)
  • 服务器处理请求,并返回请求资源
  • 浏览器解析html文件渲染页面
  • 关闭请求(TCP四次挥手)

DNS 解析

说到这里就不得不提一下DNS这哥们的解析顺序了html

  • 浏览器缓存
    • 若是有解析这个域名的记录,而且没有清除浏览器缓存就存在该域名的IP映射,未找到则进行下一步查找。
  • 系统缓存
    • 从本机host文件中查找是否存在该域名对应的IP映射。
  • 路由器缓存
    • 从路由器缓存记录中查找是否存在该域名的解析记录,有则返回对应的IP映射。
  • ISP(互联网服务提供商) DNS缓存
    • 以上三种方式属于本地查询,若是仍是未找到则进入ISP DNS缓存中查找。就好比你用的网络是联通的,那就进入联通的DNS缓存服务器中查找。
  • 根域名服务器
    • 全球仅存在13台根域名服务器,1台主根域名服务器,12台辅根域名服务器。以上方式都未成功,则进入根域名服务器,根域名服务器收到请求后会查询区域文件记录,若不存在则将其管辖范围下的主域名服务器(如.com)的IP地址发送给客户端。
  • 主域名服务器
    • 本地DNS服务器向根域名服务器返回的主域名服务器发起请求,主域名服务器收到请求后,查询本身缓存,若没有则返回本身下一级域名服务器IP地址,若仍是未找到,就重复该步骤直到找到该域名对应的IP地中。
  • 保存当前结果到缓存,并返回给客户端
    • 客户端拿到IP地址请求对应资源。

缓存

强缓存经过返回头的cache-controlexpires判断前端

对比缓存经过首部的ETaglast-modified判断web

强缓存

  • Expires是一个绝对时间,即服务器时间。浏览器检查当前时间,若是还没到失效时间就直接使用缓存文件。可是该方法存在一个问题:服务器时间与客户端时间可能不一致。所以该字段已经不多使用。浏览器

  • cache-control中的max-age保存一个相对时间。例如Cache-Control: max-age = 484200,表示浏览器收到文件后,缓存在484200s内均有效。 若是同时存在cache-control和Expires,浏览器老是优先使用cache-control。缓存

指令 参数 说明
private 代表响应只能被单个用户缓存,不能做为共享缓存(即代理服务器不能缓存它)
public 可省略 代表响应能够被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存
no-cache 可省略 缓存前必需确认其有效性
no-store 不缓存请求或响应的任何内容
max-age=(s) 必须 响应的最大值
  • Pragma

PragmaHTTP/1.1以前版本遗留的通用首部字段,仅做为于HTTP/1.0的向后兼容而使用。虽然它是一个通用首部,可是它在响应报文中时的行为没有规范,依赖于浏览器的实现。RFC中该字段只有no-cache一个可选值,会通知浏览器不直接使用缓存,要求向服务器发请求校验新鲜度。由于它优先级最高,当存在时必定不会命中强缓存。服务器

若是响应报文首部的expires的时间大于请求的时间或者max-age不为0而且cache-control设置的值不为no-cache或者no-store,同时请求报文首部不存在Pragma字段的时候才会命中强缓存。网络

对比缓存

  • last-modified是第一次请求资源时,服务器返回的字段,表示最后一次更新的时间。下一次浏览器请求资源时就发送if-modified-since字段。服务器用本地Last-modified时间与if-modified-since时间比较,若是不一致则认为缓存已过时并返回新资源给浏览器;若是时间一致则发送304状态码,让浏览器继续使用缓存。
  • Etag:资源的实体标识(哈希字符串),当资源内容更新时,Etag会改变。服务器会判断Etag是否发生变化,若是变化则返回新资源,不然返回304。

图解缓存

TCP三次握手

TCP三次握手图解

由上图咱们能够清晰的看到TCP三次握手的详细过程。dom

  • 首先是由客户端发送一个创建链接的请求,SYN置为1(表示要创建链接),生成一个随机数seq=x,进入SYN_SEND状态
  • 服务端接收到请求,首选确认ack=x+1,将SYN置为1,ACK置为1,也生成一个随机数seq=y,进入SYN_RECV
  • 客户端收到请求后,发送确认包ACK=y+1,服务器接收到确认包,链接创建成功,客户端和服务器进入ESTABLISHED状态。

服务器接收到客户端的http请求后会将该http请求封装成一个Request对象,并经过不一样的web服务器处理,处理完结果以Response对象返回给客户端,主要内容为状态码请求头响应报文三个部分。async

常见状态码

状态码 类别 缘由短语
1xx Informational(信息性状态码) 接受的请求正在处理
2xx Success(成功状态码) 请求正常处理完毕
3xx Redirection(重定向状态码) 须要进行附加操做以完成请求
4xx Client Error(客户端错误状态码) 服务器没法处理请求
5xx Server Error(服务器错误状态码 服务器处理请求出错

页面渲染

domTree

cssTree

基本流程

  • 解析HTML文件,生成DOM
  • 解析CSS文件,生成CSS
  • 合并DOM树和CSS树,生成渲染树
  • 布局和绘制页面(回流,重绘)

浏览器解析HTML文件自上而下解析遇到CSS文件会阻塞页面渲染和JS文件的执行,CSS文件不会阻塞js文件加载,他们是能够并行的,若是js文件具备defer(IE)或者async属性时,该js文件加载完就当即执行,不会受到css加载的影响。

一旦页面DOM树生成接解析完毕就会触发DOMContentLoadedPS:IE用onreadystatechange),就能够经过document.addEventListener('DOMContentLoaded',callback,false)来进行绑定监听事件。

回流和重绘

概念

  • 回流

Reflow,又叫layout,通常意味着DOM元素内容、结构、位置或尺寸发生变化,须要从新计算样式和渲染树,这个过程叫作回流。

  • 重绘

Repaint,通常是由于元素一些外观上的改变(例如:背景色,边框颜色,字体颜色等),此时只要应用新样式绘制到元素上就好了,这个过程叫重绘。

因此回流比重绘的代价高的多得多,每一个节点都有reflow方法,一个节点产生回流,可能会致使子元素产生回流,甚至会致使父节点或者兄弟节点产生回流。

触发回流的一些操做

  • 删除、新增DOM节点会触发RepaintReflow
  • 操做节点位置改变或给节点添加一个动画
  • 改变CSS一些样式(如:改变节点尺寸等)
  • 窗口大小改变
  • 修改网页默认字体
  • 网页初始化的时候
  • js获取精确CSS样式的时候(如:getComputedStylescroll家族,offset家族,client家族等,使用这些方法将强制刷新队列)

会产生上面的问题的根源仍是现代浏览器都比较聪明,他们经过队列化修改并批量执行来优化重排的过程,浏览器会将修改操做都放入一个队列当中,等到过了一段时间或者达到一个阈值才会清空队列。

那么咱们为了减小回流优化页面性能又该采起什么样的措施呢?

  • 在须要对一个节点采用数次操做时能够先将该元素display:none,修改完以后再让他显示,这样只会触发两次重排
  • 须要使用js操做多个节点时能够借用DocumentFragment来进行批量操做后再插回页面
  • 让须要被操做的节点先脱离标准文档流
    • position:absolute(fixed)
    • 浮动
  • 使用cssText。将须要操做的样式一次性合并而后做用到元素上。

咱们说了这么多的减小重绘、重排,好像还忘了一个神奇的东西。bingo,就是咱们的CSS3 GPU加速啦!

CSS3 GPU加速

能触发GPU硬件加速的有以下几个属性:

  • transform
  • filter
  • opacity
  • Wall-change

他们的优势在于,在使用transform filter opacity属性实现动画时,不会触发重排和重绘;固然,在享受GPU硬件加速带来的好处的同时呢,咱们也得考虑一个问题就是若是太多元素使用这个特性,将会出现内存内存占用过大,影响性能。

TCP四次挥手

TCP四次挥手

FIN表明断开链接标志位,ACK确认标志位,seq随机数,这里笔者就很少说了,相似于前面所述的三次握手

  • 首先客户端向服务器端发送一个FIN=1+seq=u标志位
  • 服务端收到请求发送一个确认号ACK=1,其中ack=u+1,seq=v
  • 以后服务器再次向客户端发送一个FIN=1+seq=w+ACK=1+ack=u+1
  • 客户端收到后,向服务端发送一个ACK=1,ack=w+1,seq=w+1

到这里一次完整的TCP四次挥手就完结了,你们看完这个可能会有疑问,为何是四次挥手而不是三次,为何FINACK并非一块儿发送的,那么这里笔者就得说道说道了。

由于刚开始是客户端主动请求断开链接,这仅仅表示客户端没有数据传给服务端了,并不表明服务端的数据也传输完了,发送一个ACK确认标志位只是告诉客户端我知道了。

等到服务端数据也传输完了,才会出现第三次握手,也就是服务端主动发送一个FIN+ACK给客户端,告诉客户端个人数据也发送完了,咱们分手吧,而后客户端收到了,再告诉服务端我知道了。至此,分手完毕。

笔者一次性巴拉巴拉这么多,可能你们会有点很差消化,但是笔者的初衷仍是但愿可以遇到一个知识点就解决它并延申一些相关知识点,这样比零散的查找会好得多。

参考文章

浏览器HTTP缓存机制

从输入url到页面加载完成发生了什么?——前端角度

你真的了解回流和重绘吗?

相关文章
相关标签/搜索