最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 全面解析URL请求到页面显示完整过程加优化手段

    正文概述 掘金(烟花_渲染离别)   2021-03-14   399

    网页加载流程

    URL解析

    解析 URL 提取出协议、域名、端口号,对于一些特殊字符,在传递的时候需要进行编码解码。

    • encodeURIdecodeURI可以对中文、空格等编码解码,适用于 URL 本身
    • encodeURIComponentdecodeURIComponent范围更广,会编码解码一些特殊字符如 :/?=+@#$,适用于给参数编码解码

    缓存检查

    依次查找 Memory CacheDisk Cache中是否有缓存内容,有且没过期则使用,否则则发送网络请求。

    DNS 解析

    域名解析是一个递归查询 + 迭代查询的过程。

    1. 浏览器缓存,向浏览器的缓存中读取上一次的访问记录
    2. 操作系统的缓存,查找存储在系统运行内存中的缓存
    3. host 文件中查找
    4. 路由器缓存:有些路由器会把访问过的域名存在路由器上
    5. ISP互联网服务提供商缓存,比如 114.114.114.114
    6. 缓存中找不到,则本地 DNS 服务器进行迭代查询:.DNS 服务器 -> .com 顶级服务器 -> 主域名服务器 -> ...,直到服务器返回对应的 IP

    DNS 负载均衡:

    TCP 连接三次握手

    拿到 IP 后,(检查当前域名是否达到 TCP 连接上限),通过三次握手进行 TCP 连接

    全面解析URL请求到页面显示完整过程加优化手段

    三次握手:

    1. 第一次:客户端发送 SYN 包和初始序号 seq = x 给服务端,此时客户端状态为 SYN-SENT
    2. 第二次:服务端收到 SYN 包后,将标识位 SYNACK 置为1,确认序号 ack = x + 1, 初始序号 seq = y 发送给客户端,此时服务端状态为 SYN-RECEIVED
    3. 第三次:客户端收到后,将标识位 ACK 置为1, 确认序号 ack = y + 1, 自己的序号 seq = x + 1, 发送给服务端,服务端收到后也将状态切换为 ESTABLISHED

    三次握手抽象版:

    1. 客户端:你是客户端吗
    2. 服务端:是的,我是服务端,你是客户端吗
    3. 客户端:是的,我是客户端
    • seq序号,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记
    • ack确认序号,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1

    标识位:

    • ACK:确认标识,用于表示对数据包的成功接收。
    • SYN:同步标识,表示 TCP 连接已初始化,发起一个新连接。
    • FIN:完成标识,释放一个连接,用于拆除上一个 SYN 标识。一个完整的TCP连接过程一定会有 SYNFIN 包。

    为什么不能两次握手:两次握手,服务器不能确定客户端已经收到了确认请求,不能确认是否建立好了连接。服务器认为建立好了连接,发送数据包,结果发的包客户端没收到,那么攻击服务器就很容易了,只发包不收包。

    TCPUDP 的区别:

    • TCP 是一个面向连接的、可靠的、基于字节流的传输层协议,TCP 会精准记录哪些数据发送了,哪些数据被对方接收了,哪些没有被接收到,而且保证数据包按序到达,不允许半点差错。这是有状态, 当意识到丢包了或者网络环境不佳,TCP 会根据具体情况调整自己的行为,控制自己的发送速度或者重发。这是可控制
    • UDP 是一个面向无连接的传输层协议,无状态不可控

    HTTP请求

    TCP 连接建立之后,浏览器端会构建请求行、 请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,然后向服务器发送构建的请求信息。如果是 HTTPS,还需要进行 TSL 协商。

    服务器检查 HTTP 请求头是否包含缓存验证信息进行协商缓存

    Last-ModifiedIf-Modified-Since

    Last-Modified 弊端:

    1. 如果文件只是被打开,没有修改,也会造成 Last-Modified 修改,服务器不能命中缓存。
    2. 只能以秒计时,如果在毫秒级的时间内修改了文件,服务器 Last-Modified 的值并不会修改,会返回304,浏览器就会是自己的缓存 。

    ETagIf-No-Match

    启发式缓存:如果什么缓存都没设置,浏览器通常会响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。

    四次挥手

    全面解析URL请求到页面显示完整过程加优化手段

    数据传输完后,如果请求头或响应头里没有 connection: keep-alive,则需要四次挥手断开 TCP 连接,否则会保持连接通道,这样下一次在发送请求,就无需再次TCP三次握手了,节省了网络通信时间。

    四次挥手:

    • 第一次:客户端主动关闭放发送一个 FIN,用来关闭客户端到服务端的数据传输,告诉服务端我不会给你发送数据了
    • 第二次:服务端收到 FIN 包后,发送一个 ACK 给客户端,确认序号为收到序号 + 1
    • 第三次:服务端发送完数据后,服务端发送一个 FIN,用来关闭服务端到客户端的数据传输,告诉客户端我不会给你发数据了
    • 第四次:客户端收到 FIN 后,发送一个 ACK 给服务端,确认序号为收到序号 + 1,完成四次挥手

    四次挥手抽象版:

    1. 客户端:服务端,我要和你断开连接
    2. 服务端:好的,断吧
    3. 服务端:我也要和你断开连接
    4. 客户端:好的,断吧

    四次握手后,客户端还会等待 2MSL(MSL:最长报文段寿命,一般2min) 的时间,为了保证客户端发送的 ACK 报文能够到达服务器,因为这个报文可能会丢失,服务器收不到确认会超时重传 FIN + ACK 报文段,客户端能在 2MSL 时间内收到这个重传的报文段,然后客户端重新确认。

    为什么连接的时候是三次握手,关闭的时候却是四次挥手?

    • 服务端接收到客户端的 SYN 连接请求报文后,可以直接发送 SYN + ACK 报文
    • 但是关闭连接时,当服务端接收到 FIN 报文时,很可能并不会立即关闭连接,所以只能先回复一个 ACk 报文,告诉客户端你发的 FIN 报文我收到了,只有等服务端所有的报文发送完了,我才能发送 FIN 报文,因此不能一起发送,所以需要四次。

    客户端解析资源

    • 浏览器拿到资源会根据资源类型进行处理,比如是 gzip 压缩后的文件则进行解压缩,如果响应头 Content-typetext/html,则开始解析 HTML

    HTML ParserHTML 文件进行词法分析和语法分析,根据 HTML 标记关系构建 DOM 树。

    • 解析过程中遇到图片、linkscript会启动下载。
    1. script标签会阻塞 DOM 树的构建,所以一般将 script 放在底部,或者添加 asyncdefer 标识。
    2. css 下载时异步,不会阻塞浏览器构建 DOM 树,但是会阻塞渲染,在构建 render 时,会等待 css 下载解析完毕后才进行。
    • CSS Parser 解析层叠样式表构建 CSSOM 树。
    • 根据 DOM 树和 CSSOM 树构建 render 布局树,计算出最终样式,display: none不可见节点以及 head 这种不可见标签不会插入到渲染树里
    • 构建 DOM 树、构建 CSSOM 树、构建 render 树并不是严格的先后顺序,为了让用户能尽快看到网页内容,都是并行推进的
    • 根据最终样式进行图层分离,生成 layer 图层树,再生成绘制指令,交给合成线程进行绘制。

    优化

    • 尽早的把 CSS 下载到客户端,充分利用 HTTP 多请求并发机制,且 CSS 下载并不会阻塞渲染,style、link、@import 放到页面顶部
    • 避免 JS 加载阻塞渲染,添加 async、defer 标识,标签放到页面底部
    • 减少 DOM 的回流和重绘

    优化策略:

    • 减少回流范围:避免使用 table 布局,因为一个小改动可能会造成整个 table 的重新布局
    • 避免逐条改变样式,使用类名去合并样式
    • 使用 documentFragment 操作 dom,操作完成后再添加到文档中
    • 动画效果应用到 position 属性为 absolutefixed 元素上,脱离文档流,单独渲染区域
    • CSS3 硬件加速, transformopacity 等属性会触发 GPU 加速,不会引发回流和重绘,但是过多使用可能会占用大量内存,性能消耗严重
    • 现代浏览器会自己缓存一个 flush 队列,然后一次性清空。

    性能优化

    DNS 优化

    • DNS 预解析
    • 采用 CDN
    <meta http-equiv="x-dns-prefetch-control" content="on">
    <link rel="dns-prefetch" href="//g.alicdn.com" />  
    

    网络连接优化

    • 分服务器部署,区分 web 服务器、资源服务器、数据服务器,增加 HTTP 并发性
    • 减少 TCP 的三次握手和四次挥手:HTTP1.1默认开启的 Connection: keep-alive

    数据缓存

    • 对于静态资源文件实现强缓存和协商缓存
    • 对不经常更新的接口数据采用本地存储做数据缓存,比如地区数据

    数据传输

    • 减少数据传输的大小
    1. 利用工具如 webpack 对传输内容进行压缩
    2. 服务端开发 GZIP 压缩,一般能压缩 60% 左右
    3. 大批量数据分批次请求,下拉刷新,分页
    • 减少 HTTP 请求的次数
    1. 资源文件合并处理
    2. 小图片转成 base64,但是可能会造成图片大小增加 1/3

    采用 HTTP2.0

    HTTP1.1 虽然在串行请求可以通过 Connection: keep-alive 复用同一个 TCP 连接,如果是并行发送多个请求,会建立多个连接,但是浏览器一般限制会限制同一域名下最多同时可以建立6个连接。

    • 请求阻塞:在并发请求达最大限制时,请求必须等到上一个请求完成后,才可以复用这个 TCP 发出下一个请求,所以会受到前面请求的阻塞。
    • 线头阻塞:请求响应的顺序必须和请求发送的顺序一致,如果后发送的请求响应完成了,也要等前面的阻塞的请求返回。

    多路复用:允许同时通过单一的 HTTP2.0 连接发起的多重请求 - 响应消息,连接通道是共享的

    HTTP2.0 的传输是基于二进制帧的,每个 TCP 连接中,都有多个双向流通的流,每个流都有独一无二的标识和优先级,而流就是由二进制帧组成的。二进制帧会标识自己是属于哪个流的,所以这些流可以交错传输,在接收端根据帧头组装成完整的信息,解决线头堵塞的问题。

    头部压缩:HTTP1.xheader 中带有大量的信息,每次都要重复发送,HTTP2.0 使用 HPACK 算法对 header 数据进行压缩,减少需要传输的 header 大小,通讯双方各自缓存一个头部字典表,可以差异化更新头部,减少需要传输数据的大小

    参考文章

    • 阿里面试官的”说一下从url输入到返回请求的过程“问的难度就是不一样!
    • 从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!
    • (建议收藏)TCP协议灵魂之问,巩固你的网路底层基础

    起源地下载网 » 全面解析URL请求到页面显示完整过程加优化手段

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元