一个url加载的全过程
最近在进行前端面试方面的一些准备,遇到了一个经典前端问题,一个url从输入到页面加载中间到底发生了什么,以前也认真想过这个问题,但是当时回答的都不全面,现在来好好总结一下:
总体来说分为以下六个步骤:
1、DNS解析
2、TCP连接
3、发送HTTP请求
4、服务器处理请求并返回HTTP报文
5、浏览器解析渲染页面
6、连接结束
具体过程:
1、DNS解析
DNS解析的过程就是寻找哪台服务器上有我请求资源的过程,当你在浏览器中输入一个地址时,例如:www.baidu.com,其实并不是百度网站真正意义上的地址,互联网上每一台计算机的唯一标识是他的IP地址,但是IP地址并不方便记忆,所以互联网设计者需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到ip地址的转换,这个过程就是DNS解析,就是域名到ip地址的转换
DNS解析是一个递归查询的过程
例如你在浏览器中输入一个www.google.com的IP地址,首先在本地域名服务器中查询IP地址,如果没有找到,本地域名服务器会向根域名服务器发送一个请求,如果根域名服务器也不存储该域名,本地域名会向com顶级域名服务器发送一个请求,依次类推下去,直到最后本地域名服务器得到google的IP地址并把它缓存到本地,供下次查询使用(自己计算机上的hosts文件就是域名到ip的一个映射,他可以不用去寻找网络上的DNS解析),,从上述过程中,可以看出网址的解析是一个从右到左的过程:com->google.com->www.google.com,但是你是否发现少了点什么,根域名服务器的解析过程呢?实际上,真正的网址是www.google.com,并不是我多打开一个.,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,即然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上去,所有的网址真正解析的过程为.->.com->google.com->www.google.com
DNS优化
为了了解DNS的过程,可以为我们带来什么?上文中请求道google的ip地址,经历了8个步骤,这个步骤中存在多个请求(同时存在UDP和TCP请求),为什么有两种请求方式呢)如果每次都经过这么多步骤,是否太耗时间,如何减少该过程的步骤呢,那就是DNS缓存
DNS缓存
DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种:浏览器缓存,系统缓存,路由缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存
在你的chrome浏览器中输入:chrome://dns/,你就可以看到chrome浏览器的DNS缓存
系统缓存主要存在hosts文件中
DNS负载均衡
不知道大家有没有思考过一个问题,DNS返回的IP地址石佛偶每次都一样呢?如果每次都一样是否说明你请求的资源都位于同一台机器上面,那么这台服务器需要多高的性能和存储才能满足亿万请求呢?其实真是的互联网世界背后存在成千上百的服务器,大型的网站甚至更多,在用户眼里,它需要的只是处理它的请求,哪台服务器处理并不重要。DNS可以返回一个合适的机器的IP给用户,例如可以根据每台服务器的负载量,该机器离用户地理位置的距离等,这种过程就是DNS负载均衡,又可以叫做DNS重定向,大家耳熟能详的CDN就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。
2、TCP连接
HTTP协议是使用TCP作为其传输层协议的,当TCP出现瓶颈时,HTTP也会受到影响
3、HTTP协议
HTTP报文是包裹在TCP报文中发送的,服务器端收到TCP报文时会解包提取出HTTP报文,但是这个过程存在一定风险,HTTP报文时明文,如果中间被截取的话存在一些信息泄露的风险,那么在进入TCP报文之前对HTTP做一次加密就可以解决这个问题了,HTTPS协议的本质就是HTTP+SSL(or TLS)。在HTTP报文进入到TCP报文之前,先使用SSL对HTTP报文进行加密,从网络层结构看他位于HTTP协议与TCP协议之间。
HTTPS过程
HTTPS在传输数据之前需要客户端与服务器进行一个握手(TLS/SSL握手),在握手过程中将确立双方加密传输数据的密码信息,TLS/SSL使用了非对称加密,对称加密及hash等,HTTPS相比HTTP,虽然提供了安全保证,但是也势必会带来一些时间上的损耗,如握手和加密过程等,是否使用HTTPS需要根据具体情况在安全和性能方面做权衡。
HTTP请求
发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议是80/8080,HTTPS端口是443).HTTP请求报文由三部分组成:请求行,请求报头,请求正文。
请求行
格式如下:
Method Request-URL HTTP-Version CRLF
eg:GET index.html HTTP/1.1
常用的方法有:GET,POST,PUT,DELETE,OPTIONS,HEAD
请求抱头
请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。客户端并不一定特指浏览器,有时候也可以使用测试工具等
常见的请求报头有:Accept,Accept-Charset,Accept-Endding,Accept-Language,Content-Type,Authorization,Cookie,User-Agent等。
Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。
请求正文
当使用POST、put等方法时,通常需要客户端向服务器传递数据,这些数据就存储在请求正文中,在请求包文中有一些与请求正文相关的信息,请求的数据格式一般为json,这时就需要设置Content-Type:application/json.
4、服务器处理请求并返回HTTP报文
这些就是后端工程师眼中的HTTP,后端从固定的端口接收到TCP报文开始,这一部分对应编程语言中的socket。它对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用,这一部分工作一般是由WEB服务器去进行,我们使用过的W恶霸服务器又Tomcat等
http响应报文也是由散步分组成的状态码、响应报头、响应报文
状态码:
状态码是由三个数字组成的,第一个数字定义了响应的类别,且有5种可能取值:
1xx:指示信息-表示请求已接收,继续处理
2xx:成功-表示请求已被成功接收
3xx:重定向-要完成请求必须进行更进一步的操作
4xx:客户端错误-请求的语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求。
响应报文:
服务器返回给浏览器的文本信息,通常HTML、css、js、图片等文件就放在这一部分
5、浏览器解析渲染页面
浏览器收到HTML\CSS\JS文件后,它是如何把页面呈现到屏幕上的?
浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上,这个过程比较复杂,设计到两个概念:reflow回流和repain重绘。DOM节点中的各个元素都是以盒模型的形式存在的,这些都需要浏览器去计算其位置和大小等,这个过程称为relow,当盒模型的位置大小和其他属性,颜色,字体确定下来之后,浏览器便开始绘制内容了,这个过程称为repain,页面在首次加载时必然会经历reflow和repain。这个过程是非常消耗性能的,尤其是在移动设备上,他会破坏用户体验,有时会造成页面卡顿,所以我们尽可能减少reflow和repain。
js解析是由浏览器中的js解析引擎完成的,js是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才开始,但是又存在某些任务比较耗时,如IO读写,所以需要一种机制可以先执行排在后面的任务,这就是:同步任何和异步任务,js的执行机制可以看作是一个主线程加上一个任务队列,同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈,异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫事件循环。
浏览器在解析过程中,如果遇到请求外部资源的时候,如图像、js文件\css文件deng ,浏览器将下载该资源,请求过程是异步的,并不会影响html文档进行加载,但是当文档加载过程中遇到js文件时,html文档会挂起渲染过程,不仅要等到文档中js文件加载完毕还要等待解析执行完毕,才会继续html的渲染过程,原因是因为js有可能会修改dom结构,这意味着js执行完成前,后续所有资源下载是没有必要的,这就是js阻塞后续资源下载的根本原因,css文件的加载不影响js文件的加载,但是却影响js文件的执行,js代码执行前浏览器必须保证css文件已经下载并加载完毕,这也是在head中为什么先用link引用css文件,再去加载js文件的原因.
web优化
了解上面过程的目的就是为了Web优化,在谈到Web优化之前,我们回到一个更原始的问题,Web前端的本质是什么?我的理解是:将信息快速并友好的展示给用户并能够与用户进行交互,快速的意思就是在尽可能短的时间内完成页面的加载,试想一下如果你在淘宝购买东西的时候,淘宝页面加载十几秒才显示出物品,这个时候你还有心情去购物吗?怎么快速完成页面的加载呢?最简单的答案就是参照雅虎34条军规,这34条军规实际上就是围绕请求过程进行的一些优化方式。
如何尽快地加载资源呢?答案就是不能从网路中加载的资源就不从网路中加载,当我们合理使用缓存,将资源放在浏览器端,这是最快的方式,如果资源必须从网络中获取,则要考虑缩短连接时间,即DNS优化部分,减少响应内容大小,即对内容进行压缩。另一方面,如果加载的资源数比较少的话,额可以快速的响应用户,当资源到达浏览器之后,浏览器开始尽心那个解析渲染,浏览器中最耗时间的就是reflow,所以围绕这一部分可以澳旅如何减少reflow的次数。
一个url加载的全过程的更多相关文章
- 从一个URL加载一个Document
存在问题 你需要从一个网站获取和解析一个HTML文档,并查找其中的相关数据.你可以使用下面解决方法: 解决方法 使用 Jsoup.connect(String url)方法: Document doc ...
- 浏览器输入URL加载的全过程都发生了什么事情,你知道?
什么是URL: 统一资源定位符(URL,英文 Uniform / Universal Reaource Locator 的缩写) 标准的URL由服务类型(协议).存放资源的主机域名(可以是域名或者ip ...
- 从输入URL到页面加载的全过程
前面的话 本文将详细介绍从输入URL到页面加载的全过程 概述 从输入URL到页面加载的主干流程如下: 1.浏览器构建HTTP Request请求 2.网络传输 3.服务器构建HTTP Response ...
- URL加载系统----iOS工程师必须熟练掌握
URL加载系统----iOS工程师必须熟练掌握 iOS根本离不开网络——不论是从服务端读写数据.向系统分发计算任务,还是从云端加载图片.音频.视频等. 当应用程序面临处理问题的抉择时,通常 ...
- coreml之通过URL加载模型
在xcode中使用mlmodel模型,之前说的最简单的方法是将模型拖进工程中即可,xcode会自动生成有关模型的前向预测接口,这种方式非常简单,但是更新模型就很不方便. 今天说下另外一种通过URL加载 ...
- 《动手实现一个网页加载进度loading》
loading随处可见,比如一个app经常会有下拉刷新,上拉加载的功能,在刷新和加载的过程中为了让用户感知到 load 的过程,我们会使用一些过渡动画来表达.最常见的比如"转圈圈" ...
- 用C3中的animation和transform写的一个模仿加载的时动画效果
用用C3中的animation和transform写的一个模仿加载的时动画效果! 不多说直接上代码; html标签部分 <div class="wrap"> <h ...
- 初识canvas,使用canvas做一个百分比加载进度的动画
canvas作为H5中重要的新增特性,使开发者可以用它来创作各种令人惊叹的作品.先来看一下浏览器对canvas的支持情况. <canvas> 标签定义图形,比如图表和其他图像,我们使用脚本 ...
- WPF 多线程 UI:设计一个异步加载 UI 的容器
对于 WPF 程序,如果你有某一个 UI 控件非常复杂,很有可能会卡住主 UI,给用户软件很卡的感受.但如果此时能有一个加载动画,那么就不会感受到那么卡顿了.UI 的卡住不同于 IO 操作或者密集的 ...
随机推荐
- pageResponse - 让H5适配移动设备全家
http://www.cnblogs.com/PeunZhang/p/4517864.html
- 爬虫用到的库Beautiful Soup
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- java项目规范
一.命名规范 1. 项目名全部小写 2. 包名全部小写 3. 类名首字母大写,如果类名由多个单词组成,每个单词的首字母都要大写. 如:public class MyFirstClass{} 4. 变量 ...
- mysqldump备份成压缩包
可以直接应用mysqldump直接将mysql数据库中的表或者整个数据库备份成压缩格式的包 废话不多说了直接上代码吧 mysqldump -h localhost -uroot -pHb118114 ...
- 【Python之路】Python目录
Python基础1 -- Python由来.Python种类.编码方式, Python基础2 -- Python运算符.数据类型.enumerate.range.for循环 python基础3 -- ...
- sql server下划线查询
select * from tablea A where A.b like '%[_]%'
- Azkaban简介及使用
一.Azkaban概述 Azkaban是一个分布式工作流管理器,在LinkedIn上实现,以解决Hadoop作业依赖性问题. 我们有需要按顺序运行的工作,从ETL工作到数据分析产品. 特点: 1)给用 ...
- HDFS基本命令行操作及上传文件的简单API
一.HDFS基本命令行操作: 1.HDFS集群修改SecondaryNameNode位置到hd09-2 (1)修改hdfs-site.xml <configuration> //配置元数据 ...
- MySQL索引优化案例浅析
MySQL是关系型数据库的一种,查询功能强,数据一致性高,数据安全性高,支持二级索引.但是性能比起非关系型数据库稍弱,特别是百万级以上的数据,很容易出现查询慢的现象.这时候要分析慢的原因,一般情况下是 ...