当前位置: 首页 > Web前端 > HTML5

当我们在浏览器中输入URL时会发生什么?

时间:2023-04-05 19:54:59 HTML5

写在开头:这篇文章被我归为博客性能优化的范畴,因为我认为如果要优化网站性能,提升用户体验,首要目标是了解用户请求的过程并在本地加载您的网页,最后发生了什么,在此基础上我们可以更好地优化网页。原文发表于我的个人博客:kmknkk.xin图片来源:知乎-张秋仪浏览器解析查询缓存DNS查询DNS查询顺序如下,如果其中一个步骤成功,直接跳到链接建立部分:浏览器自带的DNS操作系统DNS本地的hosts文件向域名服务器发送请求建立连接。TCP三向握手(three-wayhandshaking)sender:SYN(synchronize)receiver:SYN/ACK(acknowledgement),确认信息已传达sender:ACK——确认receiver在线,可以接收结束的优点AcceptTCP的三次握手就是发送方可以确认接收方还在线,不会白白发送浪费资源。发送HTTP请求消息头(GET/index.htmlHTTP/1.1)方法URLHTTP版本空行(CR+LF)消息体注意:1、HTTP是无连接无状态的,即HTTP会Disconnected(HTTP1.1之前),并且不会记录访客的状态。从HTTP/1.1开始,默认支持持久连接,即一次通信后连接不会中断。HTTP/1.0需要手动设置:keep-alive。通常情况下,HTTP请求和响应方式是一个请求一个响应:请求1->响应1->请求2->响应2->请求3->响应3如果使用长连接请求管道方式:请求1->Request2->Request3->Response1->Response2->Response3使用pipelined的条件:服务端需要支持pipelined,只有GET和HEAD可以pipeline,POST请求有限制。Pipelined不会2.关于CR(CarriageReturn,回车)和LF(LineFeed,LineFeed)Dos和Windows用CR/LF表示下一行,UNIX/Linux用LF表示下一行,MACOS系统用CR表示下一行一行服务器发送响应消息头(HTTP/1.1200OK)HTTP版本响应状态码状态码信息空行(CR+LF)消息体客户端收到页面,浏览器渲染页面,执行以下过程:根据DOCTYPE解析HTML判断文档类型(最常见的是HTML5,注意如果是HTML4,有严格模式和松散模式)构建DOM树(基于构建类似于二叉树的树onHTML)下载资源CSS-构建CSSOM树js-等待下载并分析执行后的浏览器渲染。在谈浏览器渲染之前,先明确一个概念:其实我们看到的页面并不是我们直观看到的一层图页面,而是很多DOM元素渲染出来的一层(Layers)。组成,如下图所示。页面的渲染过程那么一个页面的渲染过程包括以下几个步骤:构建渲染树(RenderTree):根据DOM和CSSOM树进行渲染,不可见的元素不会被渲染布局(layout):CPU根据渲染树布局计算元素的具体位置和大小,转换为绝对像素,并根据样式分成多个独立的渲染层(Layers),每层对应位图绘制(Paint):GPU根据每个渲染层(Layers)位图绘制每个点,即填充像素,并缓存所有渲染层。如果下一页发生变化但渲染层没有发生变化,则不会触发重绘。Compositing:顾名思义就是处理多个渲染层之间的关系,将它们合成一个完整的页面。重绘和重绘重绘(repaint):元素的视觉性能属性发生改变而触发重绘,比如改变可见性、颜色等,不会影响dom结构。元素布局事件会触发回流。同时会触发repaint。这种开销是非常昂贵的,不可避免地会导致性能下降。页面元素越多,效果越明显。回流的常见情况:增加、删除、修改DOM节点,移动DOM或动画显示的位置(所以动画尽量使用canvas),修改宽度和显示等CSS样式,调整窗口大小或修改默认字体网页滚动时(不推荐)display:none会触发reflow和repaint,而visibility:hidden只会产生repaint。显然,要提高页面性能,首要目标是减少重绘和重排。具体方法包括但不限于以下几种:压缩DOM深度,防止内部元素变化导致多个外层发生变化。对于无用的元素,尽量设置display:none来降低绘制压力。当操作DOM上的大量元素时,我们可以使用DocumentFragment对象来操作,最后一次加载到DOM结构中。指定img的大小:由于img是一个内联元素,加载后它的宽高会发生变化,严重的会导致整个页面重新排列,所以最好在渲染前设置好它的宽高,或者放出来的文档流。DOM渲染层(Layers)与GPU硬件加速了解了浏览器页面的渲染合成过程后,我们不难得出一个结论:如果我们抽取会进行大量重绘重排的元素,触发一个渲染层(Layer),不会一起重绘其他元素,这样会大大提高页面性能。那么如何触发渲染层,让GPU加速绘制呢?最简单的方法有以下三种:will-change:transform;will-change:不透明度;转换:translateZ(0);PS:使用Layers触发GPU加速(硬件加速)也会带来负面影响,比如掉电太快,占用内存和GPU等。所以在使用过程中注意不要滥用,只用在经常触发的元素上重新绘制和重新排列。