从输入URL到页面展示完成浏览器做了些什么

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:为什么输入URL就可以显示想要的页面?输入URL后浏览器做了些什么?前端可以针对这些做哪些优化?

为什么输入URL就可以显示想要的页面?

输入URL后浏览器做了些什么?

前端可以针对这些做哪些优化?

浏览器的 主要功能 是将用户选择的web资源呈现出来,它需要从服务器请求资源,并将其显示在浏览器窗口中,资源的格式通常是HTML,也包括PDF、image及其他格式。

那么从输入URL到浏览器显示完成,大致是分为2个阶段。首先解析url,完成后通过http获取页面资源,最后将获得的资源渲染展示出来。

从输入URL到页面展示完成浏览器做了些什么

HTML页面加载和解析流程

1.用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件;

2.浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;

3.浏览器又发出CSS文件的请求,服务器返回这个CSS文件;

4.浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;

5.浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;

6.服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头重新渲染这部分代码;

7.浏览器发现了一个包含一行Javascript代码的<script>标签,赶快运行它;

8.Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。突然少了这么一个元素,浏览器不得不重新渲染这部分代码;

9.终于等到了</html>的到来,浏览器泪流满面……

10.等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;

11.浏览器召集了在座的各位<div><span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面

1. 解析url、获取页面资源

  • DNS解析获取ip地址
  • TCP请求(3次握手)
  • http请求获得返回数据html

2. 解析、渲染页面

  • html解析/dom树构建
  • 同获取html方式获取css/js/图片的资源
  • 解析构建css规则树
  • 构建渲染树
  • 布局layout
  • 渲染页面

DNS域名解析

浏览器在发起http请求前,会先解析这个域名,找到ip地址。这个过程就是dns解析。解析过程如下:

1)浏览器先查询hosts文件是否有与这个域名对应的ip地址,如果有则直接向这个ip地址发起http请求。查询不到就进行下一步。

2)浏览器向本地DNS服务器发出解析域名的DNS解析报文,本地DNS服务器收到请求后,先查询缓存,判断是否有对应的记录,如果有就返回这条记录,查询不到就进行下一步。

3)本地DNS服务器没有在缓存中查询到对应的记录,本地DNS服务器于是就向DNS根服务器发起查询请求。DNS根服务器收到请求通过查询得到顶级域名对应的顶级域服务器的ip地址,然后向本地DNS服务器发送一条应答报文。

4)本地DNS服务器收到应答报文后,得到顶级域服务器的地址,然后向该地址发送请求解析域名的DNS请求报文。

5)顶级域名服务器在收到请求后先查询缓存是否有对应的记录,如果有就返回对应的记录,如果没有找到就查询域名对应的二级域服务器地址,然后将域名对应的二级域服务器地址返回给本地DNS服务器。

6)本地DNS服务器收到应答报文后,得到二级域服务器的地址,然后向该地址发送请求解析域名的DNS请求报文。

7)二级域服务器在收到请求后先查询缓存是否有对应的记录,如果有就返回对应的记录,如果没有找到就查询域名对应的三级域服务器地址,然后将域名对应的三级域服务器地址返回给本地DNS服务器。

8)本地DNS服务器收到应答报文后,得到三级域服务器的地址,然后向该地址发送请求解析域名的DNS请求报文。

9)三级域服务器在收到请求后在DNS区域数据库中查询对应的记录,返回对应的记录

10)本地名称服务器在收到三级域服务器后,向用户返回一条DNS应答报文,并将这条记录保存在缓存中

11)浏览器就得到了域名对应的ip地址,然后就可以发起http请求了

3次握手4次挥手

ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

SYN(SYNchronization):在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1.

因此, SYN置1就表示这是一个连接请求或连接接受报文。

FIN (finis):完,终结的意思, 用来释放一个连接。当 FIN = 1

时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

1)第一次握手:建立连接。客户端发送 SYN 包到服务器,Sequence Number 为 x,进入 SYN_SENT 状态,等待服务器确认。

2)第二次握手:服务器收到 SYN 包,对这个报文进行确认,设置 Acknowledgment Number 为 Sequence Number + 1;同时自己也要发送 SYN 包,Sequence Number 为 y;服务器将这些所有信息放入 SYN + ACK 包中发送给客户发,服务器进入 SYN_RCVD 状态。

3)第三次握手:客户端收到 SYN + ACK 包。将 Acknowledgment Number 设为 y + 1,即服务器发来的 Sequence Number + 1,并向服务器发送 ACK 包,发送完成后客户端和服务器都进入 ESTABLISHED 状态。

从输入URL到页面展示完成浏览器做了些什么

http相关

通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。

在浏览器查看一个http请求的请求头部如下:

从输入URL到页面展示完成浏览器做了些什么

http响应头部

从上图可以看到,头部信息包括三部分:

1、通用头部

1)通用头域包含请求和响应消息都支持的头域。
 2)Request URL:请求的URL地址
 3)Request Method: 请求方法,get/post/put/……
 4)Status Code:状态码,200 为请求成功
 5)Remote Address:路由地址

2、请求头部

1) Accept:  告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型;
 2)Accept-Charset:  浏览器申明自己接收的字符集
 Accept-Encoding:浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法  (gzip,deflate)
 3)Accept-Language:  浏览器申明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。
 4)Authorization:  当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,该头部来回应自己的身份验证信息给WEB服务器。
 5)Connection:表示是否需要持久连接。close(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,
 不要等待本次连接的后续请求了)。keep-alive(告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。
 6)Referer:发送请求页面URL。浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。
 7)User-Agent: 浏览器表明自己的身份(是哪种浏览器)。
 8)Host: 发送请求页面所在域。
 9)Cache-Control:浏览器应遵循的缓存机制。
        no-cache(不要缓存的实体,要求现在从WEB服务器去取)
        max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象) 
        max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)  
        min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象)
 10)Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。
 11)Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。
 12)Form:一种请求头标,给定控制用户代理的人工用户的电子邮件地址。
 13)Cookie:这是最重要的请求头信息之一

3、响应头部

1)Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
  2)Accept-Ranges:WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
  3) Cache-Control:服务器应遵循的缓存机制。
          public(可以用 Cached 内容回应任何用户)
          private(只能用缓存内容回应先前请求该内容的那个用户)
          no-cache(可以缓存,但是只有在跟WEB服务器验证了其有效后,才能返回给客户端) 
          max-age:(本响应包含的对象的过期时间)  
          ALL:  no-store(不允许缓存)  
  4) Connection: 是否需要持久连接
          close(连接已经关闭)。
          keepalive(连接保持着,在等待本次连接的后续请求)。
          Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒)。例如:Keep-Alive:300
  5)Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。 例如:Content-Encoding:gzip 
  6)Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
  7)Content-Length:WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length: 26012
  8)Content-Range:WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。例如:Content-Range: bytes 21010-47021/47022
  9)Content-Type:WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml
 10)Expired:WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。
 11) Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。
 12) Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部指定的位置去取。
 13)Proxy-Authenticate: 代理服务器响应浏览器,要求其提供代理身份验证信息。
 14)Server: WEB 服务器表明自己是什么软件及版本等信息。
 15)Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计。

从输入URL到页面展示完成浏览器做了些什么

从输入URL到页面展示完成浏览器做了些什么

从输入URL到页面展示完成浏览器做了些什么

从输入URL到页面展示完成浏览器做了些什么

html解析/dom树构建

从输入URL到页面展示完成浏览器做了些什么

从输入URL到页面展示完成浏览器做了些什么

同获取html方式获取css/js/图片的资源

dom树构建过程中,遇到link标签、script标签会停止dom树构建,以获取html的方式获取相关资源。

解析构建css规则树

CSS解析的过程类似于HTML解析,也是浏览器使用自带的解析器进行解析,一般解析过程是由上而下,会将CSS文件解析成为StyleSheet对象,且每个对象都包含CSS规则。CSS规则对象包含了选择和声明对象,以及其他与CSS语法对应的对象。CSS解析完成后会大致生成如下结构的CSS Rule Tree。

从输入URL到页面展示完成浏览器做了些什么

构建渲染树

渲染的主要过程分为——Render Tree(渲染树)生成——Layout(布局)——Paint(绘制)。

DOM树和CSS树结合生成Render Tree(渲染树)——这是由可视化元素按照其显示顺序组成的树形结构,是文档可视化的表示,它的作用是让浏览器能够按照正确的顺序渲染页面元素。Firefox中称之为“框架”,Webkit中的术语则是呈现器或者呈现对象。

渲染树是和DOM元素相对应的,但是并非全部一一对应,例如:1,非可视化元素是不会出现在渲染树中,如“head”元素,2,如果元素的display属性值为“none”,也不会出现在渲染树中(但是visibility属性值为“hidden”的元素会出现在渲染树中)

布局layout

渲染树中并不包含位置和大小的信息,计算这些值的过程就是布局或者重排。

布局的过程是一个递归的过程,从根元素开始,递归遍历部分或者所有的渲染树结构,并为每一个需要显示元素计算几何信息。一般根元素位置坐标(0,0),大小为浏览器窗口的可见区域。

这里涉及到两个重要的概念reflow和repaint:

repaint(重绘):元素的某一部分属性发生改变,如字体颜色,背景颜色等改变,尺寸并未改变,这时发生的改变过程就是repaint。

reflow(回流): 因为浏览器渲染是一个由上而下的过程,当发现某部分的变化影响了布局时,就需要倒回去重新渲染,这个过程就称之为reflow。reflow几乎是没法避免的,现在一些常用的效果,比如树状目录的折叠、展开(实质上是元素的显示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染。基本上能引起reflow的主要有几个原因:

1,网页初始化。

2,JS操作DOM树的时候,增加删除元素等。

3,某些元素的尺寸改变。

4,CSS属性的改变,

但是浏览器很聪明,为了避免细小的改变就进行repaint或者reflow,浏览器采用一种"dirty"系统,会将这些改变操作积攒一批,然后做一次reflow,这又叫异步reflow或增量异步reflow。但是有些特殊情况不会这么做,比如:resize窗口,改变了页面默认的字体,等,对于这些操作,浏览器会马上进行reflow。

但是有的时候,我们自己编写的脚本会阻止浏览器的这种操作,比如我们请求下面的值的时候:offsetTop, offsetLeft, offsetWidth, offsetHeight,scrollTop/Left/Width/Height,clientTop/Left/Width/Height,IE中的 getComputedStyle(), 或 currentStyle等,如果我们的程序运行的时候需要这些值,那么浏览器需要给我们返回最新的值,而这样就会将当前积攒的操作执行,从而引起频繁的reflow或者repaint。

通常reflow比repaint会耗费更多的时间,从而也就会影响性能,所以编写代码的时候要尽可能避免过多的reflow或者repaint。减少reflow/repaint的方法:

1,修改样式不要逐条修改,建议定义CSS样式的class,然后直接修改元素的className。

2,不要将DOM节点的属性值放在循环中当成循环的变量。

3,为动画的 HTML 元素使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。

4,把DOM离线后修改。如设置DOM的display:none,然后进行你需要的多次修改,然后再显示出来,或者clone一个节点到内存中,然后随意修改,修改完成后再与在线的交换。

5,千万不要使用table布局,一个微小的改变就可能引起整个table的重新布局。

渲染页面

在绘制阶段,系统会遍历渲染树,并且调用呈现器将的“paint”方法,将内容显示在屏幕上。同样,类似于布局过程,也分为全局和增量两种

性能优化

1,提升HTML加载速度

-    页面精简,删除不必要的注释,空格,将内嵌的JS和CSS移至外部文件,使用压缩 工具 等。

-    减少文件数量,减少页面上引入的文件数量可以减少请求的次数,可以合并的JS和CSS文件尽量合并。

-    减少域名查询,DNS查询和解析域名需要消耗时间,减少对外部JavaScript、CSS、图片等资源的引用,不同域名的使用越少越好。

-    使用缓存,重用数据。

-    优化页面元素的加载顺序。

-    使用现在CSS和合法的标签。

-    指定图片的大小,如果浏览可以立即确定图片大小就不需要重新进行布局操作。

-   根据浏览器类型选择合适的策略。

-    使用压缩工具等。

-    页面精简,删除不必要的注释,空格,将内嵌的JS和CSS移至外部文件,使用压缩工具等。

2,编写合理的CSS

首先说明CSS选择符的匹配顺序,从右到左!从右到左!从右到左!(重要的事情说三遍),所以,类似于“#nav li” 我们以为很简单的规则,应该马上就可以匹配成功,但是,需要从右往左匹配,所以,先会去查找所有的li,然后再去确定它的父元素是不是#nav。因此,编写合理的CSS也可以提高我们的页面行能:

-    DOM的深度尽量浅,不要嵌套过深。

-    减少inline javascript  css的数量。

-    使用合法的CSS属性。

-    不要为ID选择器指定类名或者标签名。

-    避免后代选择器,尽量使用子选择器。

-    避免使用通配符。

3,关于javascript标签

对于javascript标签首先得了解其加载和执行的特点:1,载入后立即执行,2,执行时会阻塞页面后续的内容,针对这些特点,我们使用javascript标签时应该注意:

-    将所有的javascript标签放在页面底部,也就是body标签闭合之前,这样可以保证脚本执行前已完成DOM渲染。

-    尽可能合并脚本,页面中引入的脚本越少,加载响应速度也就越快。

-    减少inline javascript的使用。

-    所有的javascript标签会按照其引入顺序依次执行,只有前面的内容解析完成才会解析下一个,所以注意多个javascript标签的引入顺序。

-    使用defer属性,该属性可以使脚本在文档完全呈现以后再执行。

-    使用async属性,可以使当前脚本不必等待其他脚本的执行,也不必阻塞文档的呈现。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java技术手册(第6版)

Java技术手册(第6版)

Benjamin J Evans、David Flanagan / 安道 / 人民邮电出版社 / 2015-12-1 / 79.00

《Java技术手册 第6版》为《Java 技术手册》的升级版,涵盖全新的Java 7 和Java 8。第1部分介绍Java 编程语言和Java 平台,主要内容有Java 环境、Java 基本句法、Java 面向对象编程、Java 类型系统、Java的面向对象设计、Java 实现内存管理和并发编程的方式。第2部分通过大量示例来阐述如何在Java 环境中完成实际的编程任务,主要内容有编程和文档约定,使......一起来看看 《Java技术手册(第6版)》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具