## 前言
相信有不止一个人给你推荐过web优化中药减少并简化请求,比如使用图片精灵,合并压缩文件,脚本文件写在dom末尾,那么今天我们从http这个角度去分析,去做一些有意义的探索。
## http瀑布图入门
如果说你想了解下http的请求情况或者想优化页面初始化的效率,那么http瀑布图是你不可缺少的一个分析工具。如下图所示:下面分别展示了一个页面打开的所有请求以及一个资源请求的详细情况。从下面的图中你既能看到不同请求的请求顺序,请求时间,也能看到资源是同步加载的,脚本会阻塞加载,另外渲染和js执行属于不同的引擎负责,等等。在后面的文章中,我会分别介绍如何去分析这些图,并根据这些图去优化对应的部分。
![](https://box.kancloud.cn/ba24ba04e2088903b82474358ebe7e19_1125x675.png)
## http协议的类型
科普内容:
![](https://box.kancloud.cn/564f9fe6070274d7457575b768ab4e08_690x515.png)
>物理层:以太网 · 调制解调器 · 电力线通信(PLC) · SONET/SDH · G.709 · 光导纤维 · 同轴电缆 · 双绞线等
数据链路层:Wi-Fi(IEEE 802.11) · WiMAX(IEEE 802.16) ·ATM · DTM · 令牌环 · 以太网 ·FDDI · 帧中继 · GPRS · EVDO ·HSPA · HDLC · PPP · L2TP ·PPTP · ISDN·STP 等
网络层协议:IP (IPv4 · IPv6) · ICMP· ICMPv6·IGMP ·IS-IS · IPsec · ARP · RARP等
传输层协议:TCP · UDP · TLS · DCCP · SCTP · RSVP · OSPF 等
应用层协议:DHCP ·DNS · FTP · Gopher · HTTP· IMAP4 · IRC · NNTP · XMPP ·POP3 · SIP · SMTP ·SNMP · SSH ·TELNET · RPC · RTCP · RTP ·RTSP· SDP · SOAP · GTP · STUN · NTP· SSDP · BGP · RIP 等
* http的通信流程:
![](https://box.kancloud.cn/505f7e66d76e9cca3a3fbaa3b0a554be_307x199.png)
* http的消息结构:
![](https://box.kancloud.cn/ff5d37e40e0dca70d7e3e6c0dcdca1d0_466x165.png)
* http连接注意事项
HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
* http版本
0.9 只接受get,过时;
1.0 大多数网站使用;
1.1 当前版本。持久连接被默认采用,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
2.0 符合spdy协议,二进制格式在协议的解析和优化扩展上带来了跟多的优势,对消息头采用Hpack进行压缩传输,能够节省消息头占用的网络流量,异步连接多路复用,Server Push,服务器端能够更快的把资源推送到客户端,保持了与HTTP 1.1语义的向后兼容性
* http种类:
**HTTP**:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
**HTTPS**:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL(ssl用户安全认证)。
**cdn请求**:为什么有的文件用cdn加速之后就没有写协议类型,因为当前协议类型有可能是http or https不确定的,写//会自动识别当前的页面请求类型。
**data:image/png;base64**:为什么没有协议类型,本身属于符合RFC2397的Data URI scheme,不需要加载文件,知识一部分内容直接用于输出,图片是2进制的,所以一般需要转换为64进制。除了这个之外,还有其他类型:比如:data:text/plain,<文本数据> ,data:text/css,<css代码> ,data:image/x-icon;base64,base64编码的icon图片数据等,详细文档请站内搜索“Data URI scheme”。
## http2 详解
### 多路复用
在HTTP/2中,有两个非常重要的概念:帧(frame)和流(stream)。
**1、帧(frame)**
HTTP/2中数据传输的最小单位,因此帧不仅要细分表达HTTP/1.x中的各个部份,也优化了HTTP/1.x表达得不好的地方,同时还增加了HTTP/1.x表达不了的方式。
每一帧都包含几个字段,有length、type、flags、stream identifier、frame playload等,其中type代表帧的类型,在HTTP/2的标准中定义了10种不同的类型,包括上面所说的HEADERS frame和 DATA frame。此外还有
> PRIORITY(设置流的优先级)
> RST_STREAM(终止流)
> SETTINGS(设置此连接的参数)
> PUSH_PROMISE(服务器推送)
> PING(测量RTT)
> GOAWAY(终止连接)
> WINDOW_UPDATE(流量控制)
> CONTINUATION(继续传输头部数据)
**2、流(stream)**
> “流”在HTTP/2中是一个逻辑上的概念,就是说在一个TCP连接上,我们可以向对方不断发送一个个的消息,这里每一个消息看成是一帧,而每一帧有个stream identifier的字段标明这一帧属于哪个“流”,然后在对方接收时,根据stream identifier拼接每个“流”的所有帧组成一整块数据。我们把HTTP/1.x每个请求都当作一个“流”,那么请求化成多个流,请求响应数据切成多个帧,不同流中的帧交错地发送给对方,这就是HTTP/2中的多路复用。
![](https://box.kancloud.cn/e8e6fd7fc875e287ba007a0d9acbe8ab_640x185.png)
从上图我们可以留意到:
不同的流在交错发送;
HEADERS 帧在 DATA 帧前面;
流的ID都是奇数,说明是由客户端发起的,这是标准规定的,那么服务端发起的就是偶数了。
多路复用让HTTP连接变得很廉价,只需要创建一个新流即可,这不需要多少时间,而在HTTP/1.x时代却要经历三次握手时间或者队首阻塞等问题。而且创建新流默认是无限制的,也就是可以无限制的并行请求下载。不过,HTTP/2还是提供了`SETTINGS_MAX_CONCURRENT_STREAMS` 字段在 SETTINGS 帧上设置,可以限制并发流数目,标准上建议不要低于100以保证性能。
优化Web性能有一个常用的技术,就是图片延迟加载,目的是除了节省流量外,还能避免图片资源与其他重要的脚本资源竞争下载。
HTTP/2提供了流的优先级与依赖性这种机制,可用 HEADERS 帧或 PRIORITY 帧设置,不过协议并没有提供如何处理优先级的具体算法,这可由服务器灵活应对。我用个例子来说明这个机制。
~~~
<!-- a.html -->
<html>
<body>
<script src="a.js"></script>
<img src="a.jpg">
<img src="b.jpg">
<link rel="stylesheet" type="text/css" href="style.css">
</body>
</html>
~~~
浏览器是边下载边解析的,文档解析器首先遇到a.js,它就会去下载并且阻塞页面,同时,资源探测器会继续向下扫描,发现a.jpg、b.jpg和style.css并服务器发起请求。在没有优先级机制时,a.jpg、b.jpg会跟重要的a.js、style.css竞争下载,但在HTTP/2中,浏览器可以给a.jpg、b.jpg设置较低的优先级,另外依赖关系为
![](https://box.kancloud.cn/6d30ee2f3392aa9ea6f86395459e930e_434x153.png)
这样服务器根据优先级信息,首先吐出a.js、style.css,再吐出图片,因此页面在没有图片的情况下提前进入可交互状态。例子所说的是在浏览器层面上harcode的一个优先级策略,再比如上文提到的prefetch就可以给一个更低的优先级。在代码层面上,也许之后会提供一些控制优先级的特性,类似于目前只有IE支持的lazyload attribute。
## http请求状态码
>HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。它由 RFC 2616 规范定义的,并得到RFC 2518、RFC 2817、RFC 2295、RFC 2774、RFC 4918等规范扩展。http常见的状态码以及代表含义作为前端要清楚,并且正确的运用。以下只提供了部分常见的,如果大家想了解更多可以参考以下在线文档:
[百度百科](http://baike.baidu.com/link?url=5Qa0aFGQ4ZFOS0Bzj4kXZ_p9xPMw8ZV55XUTbx0UhZxHz35wDHaTA2IEV4gXykzqLe5Iwo-m8_DDF_vQyG0PRQnniO06nQ2lySObfBWcbB891L-AIkoD8dvWM2_JvNm3) / [菜鸟教程](http://www.runoob.com/http/http-status-codes.html)
![](https://box.kancloud.cn/e1cbf9af1b069680db8ef452c2f52343_582x370.png)
### 1. 1xx 信息正在处理
### 2. 2xx 请求成功
|状态码 | 描述 |
| ------------- | ------------- |
|200|ok 请求被成功处理 |
|201|请求成功,并且服务器创建了新的资源 |
|202|服务器已经接受请求,但还没有处理 |
|203|服务器已经处理了请求,但是信息来自于另一个来源 |
|204|请求成功,但是服务器没有响应体 |
|205|处理了请求,但没有返回内容,要求请求者重置内容再次请求 |
|206|部分内容,该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求 |
###3. 3xx 重定向状态码
|状态码 | 描述 |
|------------- |------------- |
|301|永久性重定向 |
|302|临时性重定向 |
|304|未被修改,不会返回新内容 |
###4. 4xx 代表请求错误
|状态码 | 描述 |
|------------- |------------- |
|401|未被授权 |
|403|服务器拒绝请求 |
|404|页面或者文件找不到 |
|405|禁用请求中的指定方法 |
|408|请求超时 |
|414|请求uri过长 |
|417|请求参数不符合标准 |
###5. 5xx 服务器错误
| 状态码 | 描述 |
| --- | --- |
|500|服务器内部错误 |
|501|服务器不具备响应此需要的功能 |
|502|错误网关 |
|503|服务不可用,比如系统维护或者升级等 |
|504|网关超时 |
|505|http协议版本不支持 |
## http请求类型
共8种请求类型,常见的是get和post请求,所有的这些类型都参与js-restful的设计。
根据HTTP标准,HTTP请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
|状态码 | 描述 |
|------------- |------------- |
|GET|请求指定的页面信息,并返回实体主体 |
|HEAD|类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
|POST|向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资 源的建立和/或已有资源的修改 |
|DELETE|请求服务器删除指定的页面 |
|CONNECT|HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器 |
|OPTIONS|允许客户端查看服务器的性能 |
|TRACE|回显服务器收到的请求,主要用于测试或诊断 |
## get与post方式区别
首先要了解清楚的一点是:我们大多数的请求是get方式的,少数表单或者数据操作是post的,ajax异步多是post.选择上:如果你希望url可见,可被分享抓取,可手动修改参数访问,希望被缓存,参数较短,主要是受限于url长度,那么考虑用get。需要注意的一点是:需要上传文件的要用post.
>1.GET被浏览器强制支持(POST是可选的,不过一般都支持)
2.GET是幂等的,POST非幂等(幂等每次请求不会对系统造成影响,而post有可能会更新数据)
3.GET可以被浏览器缓存,POST不可以(比如访问的历史记录,请求的历史文件,比如样式文件等)
4.GET请求是『安全』的,POST不安全(这里的安全还是指的不会更新数据)
5.POST相对来说比GET要『安全』一些(操作安全,参数等不可见)
6.参数大小(理想和现实)
- 前端工程化
- 前端工程化技术栈
- 前端工程化说明
- 工程化实践
- npm教程
- npm入门
- cnpm入门
- cnpm搭建
- nodejs教程
- nodejs入门
- 快速入门
- 命令行工具
- 内存泄露
- 代码的组织与部署
- 文件操作
- 网络操作
- 进程管理
- 异步编程
- express教程
- orm模块
- nodejs实践
- 项目搭建
- 异步优化
- 创建web和tcp服务器
- 终端问答程序
- 爬虫系统
- mongleDb
- gulp教程
- gulp入门
- gulp常用插件(1)
- gulp常用插件(2)
- gulp创建目录
- webpack教程
- webpack入门
- vuejs教程
- vuejs入门系列
- vue-cli入门
- angularjs教程
- angularjs入门系列
- reactjs教程
- reactjs入门系列
- bower教程
- bower入门
- echarts教程
- swiper教程
- web
- web优化
- http优化1
- http优化2
- http优化3
- 其他