本文整理在,我的github 上。欢迎Star。

各版本的http

发展

在HTTP建立之初,主要是为了传输超文本标记语言(HTML)文档。随着时代的发展,也进行了若干次演进。下图是各个版本发布的时间轴。

目前为止,使用最为广泛的是http1.1http1.0应该比较少了,最新的是http2
这篇博文也主要,围绕着1.0、1.1、2.0三个版本进行介绍。

http/1.0

http1.0不会复用tcp链接,每次请求都会打开、断开一条链接。
如果您看过我前阵子整理的关于TCP的博文,您就会知道,TCP是有延迟响应机制的,每次请求并不会马上返回。这算是http1.0性能不好的一个原因吧。

http/1.1

http/1.1当前普及程度最高的http版本。
到了http/1.1版本,tcp链接可以持久保持了(也就说,一段时间内,一个tcp链接会等到同一个域名下的所有资源加载完后再断开。)

在保持tcp链接的基础上,引入了http管道的机制,差点实现了多路复用

http/1.1 without pipelining(不使用管道)

通过一条tcp链接请求资源,只有在上一个请求完成后,才能发出下一个请求。也就是上图描述的情形。

http/1.1 with pipelining(使用管道)

客户端不会等待响应,直接并发N个请求。但是,http/1.x有严格的串行返回响应机制。通俗的讲就是:请求时,不用等上一个完成;但响应时,必须严格按照顺序返回
通过开发者工具,你就可以观察到这一点。

基于以上描述,使用“ HTTP 管道”技术时,万一第一个响应时间很长,那么后面的响应处理完了也无法发送,只能被缓存起来,占用服务器内存,这就是传说中的“队首阻塞(head of line blocking)”。
这也是http/1.x下,多数网络体验不好的原因。

http/2.0

在介绍http/2.0之前,我们来先看一份Akamai公司提供的一个官方演示

这里用了361(19*19)张图片,分别使用http/1.1,http/2.0两种版本的协议进行对比。可以直观的感受到,http/2.0比http/1.0快出5倍左右的速度。

考虑到您可能需要分别用开发者工具仔细查看下两个版本,我已经帮你找好了两个版本对应的链接。(不客气)


那http/2.0究竟引入了哪些机制、特性才达到目前的加速效果呢?简答的说可以概括成。

  • 二进制分帧层
  • 多路复用
  • 首部压缩
  • 服务器推送(server Push)

    二进制分帧层与多路复用

    引入了二进制分帧层,就不再是文本传输了,而是数据帧(二进制)。
    注意:HTTP原本的语义,方法、动词、首部都不受影响。仅仅是传输期间的数据格式变化了。

http/2规定了10种不同的帧。
如上图,分针层会把 开始行首部行分割到HEADERS帧正文实体分割到DATA帧。


TCP 连接在客户端和服务器间建立了一条运输的通道,可以双向通行,当一端要向另一端发送消息时,会先把这个消息拆分成几部分(帧),然后通过发起一个流对这些帧进行发送,最后在另一端将同一个流的帧重新组合。

这里涉及了以下概念。

流:已建立的连接上的双向字节流
消息:与逻辑消息对应的完整的一系列数据帧
帧:HTTP/2 通信的最小单位,每个帧包含帧首部

其中帧对数据进行顺序标识,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据,这就是流所做的事情。

HTTP/2对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。同样Apache的最大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了6倍!

首部压缩

在服务器和客户端各维护一个“首部表”,表中用索引代表首部名,或者首部键 - 值对,上一次发送两端都会记住已发送过哪些首部,下一次发送只需要传输差异的数据,相同的数据直接用索引表示即可。

首部压缩,可以解决http头臃肿的问题。

服务器推送(server Push)

服务器可以对一个客户端请求发送多个响应。也就是说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源。

这里就涉及到了另一个帧类型:PUSH_PROMISE帧。
举个栗子,当客户端请求index.html时,服务器会同时推送style.css,index.js对应的PUSH_PROMISE帧。客户端可以直接缓存起来。

基于http/2对前端性能优化的思考

个人觉得前端的性能优化,应该主要从两个方面。加载速度流畅运行
原引,在网上看到的一段话:

网页不仅应该被快速加载,同时还应该流畅运行,比如快速响应的交互,如丝般顺滑的动画等。


http/1.x的优化方案

当然,今天的主题是讨论网路协议,那我们只谈加载速度。
基于http1.x的相关特性,可爱的前端们提出了很多颇具成效的优化方案。(精灵图,多域名加载等等)其中,比较著名的雅虎军规,很多人应道都知道,这里有一张整理好的图。

http/2的变革

在http/2的基础上,很多http/1.x要优化的问题,都不存在了。问题都不存在了,问题的优化方案也就不存在了。
这里插一句,我始终坚信的一个观点是:没有任何优化手段是不需要付出代价的。是药三分毒,无非是取舍罢了。

1.合并css、js与精灵图

在http/1.x时代,http并没有最大程度上利用好tcp链接。虽然http/1.1里有了http管道,但其也带来了队首阻塞等问题,同时也要受队列大小的限制。所以我们要通过合并文件的方式减少http链接数量。
不错,减少http请求数量的确能起到优化的作用,但与此同时,也有很多弊端:

  1. 所有文件合成一个大文件,那不管哪个模块发生变更,都要整体更新,用户都要重新下载,无法继续使用缓存。
  2. 带来了额外的维护成本。印象比较深的是维护精灵图,稍微改一点,就得重新弄。

以上,就是”合并css方案"、“合并js方案”、“精灵图方案”的优势与弊端。

  • 在http/1.x基础上,明显优势>弊端,所以我们使用这些方案。
  • 但http/2,它对tcp链接的利用程度已经有了飞跃性的提升。此时这些方案是否优势>弊端,就值得商榷了。笔者觉得应该正好反过来。优势<弊端

2.分域名

在http/1.x基础上,分域名有两个好处。

  • 为了绕过浏览器对同一域名的最大管道限制。可以同时请求更多内容。
  • 同一域名下的请求报文,会匹配的站点的全部cookie,增大请求报文长度。而很多资源,比如图片、css是不需要cookie的。

在http/2上,对于这些问题

  • 原本就支持多路复用,没必要分
  • 首部压缩机制,首部行大点,也就传一个。

3.接口合并

如果页面需要多种数据,我们会尽量将数据汇总到一个接口,以减少http请求数量。
这种做法,几乎违背了各种程序设计规范,比如“单一职责原则”等等,接口很难复用,维护成本高。
这种方案在http/2下,明显弊端>优势了。

参考文献

前端与HTTP的更多相关文章

  1. 构建一个基本的前端自动化开发环境 —— 基于 Gulp 的前端集成解决方案(四)

    通过前面几节的准备工作,对于 npm / node / gulp 应该已经有了基本的认识,本节主要介绍如何构建一个基本的前端自动化开发环境. 下面将逐步构建一个可以自动编译 sass 文件.压缩 ja ...

  2. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  3. 前端极易被误导的css选择器权重计算及css内联样式的妙用技巧

    记得大学时候,专业课的网页设计书籍里面讲过css选择器权重的计算:id是100,class是10,html标签是5等等,然后全部加起来的和进行比较... 我只想说:真是误人子弟,害人不浅! 最近,在前 ...

  4. 总结:Mac前端开发环境的搭建(配置)

    新年新气象,在2016年的第一天,我入手了人生中第一台自己的电脑(大一时好友赠送的电脑在一次无意中烧坏了主板,此后便不断借用别人的或者网站的).macbook air,身上已无分文...接下来半年的房 ...

  5. Fis3的前端工程化之路[三大特性篇之声明依赖]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  6. Fis3的前端工程化之路[三大特性篇之内容嵌入]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  7. Fis3的前端模块化之路[基础篇]

    Fis3版本:v3.4.22 fis3是一个构建工具 解决前端开发中自动化工具.性能优化.模块化框架.开发规范.代码部署.开发流程等问题. 安装 npm install -g fis3 运行 fis3 ...

  8. 细说前端自动化打包工具--webpack

    背景 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过链接组织在一起.用过Dreamweaver的都知道,做网页就像用word编辑文档 ...

  9. 通过AngularJS实现前端与后台的数据对接(二)——服务(service,$http)篇

    什么是服务? 服务提供了一种能在应用的整个生命周期内保持数据的方法,它能够在控制器之间进行通信,并且能保证数据的一致性. 服务是一个单例对象,在每个应用中只会被实例化一次(被$injector实例化) ...

  10. 前端框架 EasyUI (0) 重新温习(序言)

    几年前,参与过一个项目.那算是一个小型的信息管理系统,BS 结构的,前端用的是基于 jQuery 的 EasyUI 框架. 我进 Team 的时候,项目已经进入开发阶段半个多月了.听说整个项目的框架是 ...

随机推荐

  1. bzoj2865 字符串识别

    Description XX在进行字符串研究的时候,遇到了一个十分棘手的问题. 在这个问题中,给定一个字符串S,与一个整数K,定义S的子串T=S(i, j)是关于第K位的识别子串,满足以下两个条件: ...

  2. WebFrom基础

    ASP.NET WebForm C/S B/S客人 - 用户 要土豆丝 - 给IIS发送请求 ,IIS就相当于是服务员 通知厨房 - IIS把用户要想看到的ASPX告知.NET框架 厨房炒菜 - .n ...

  3. app遍历——appCrawler的使用

    1.appCrawler环境配置 1.1 apkinfo获取安装包的报名和mainActivity https://github.com/codeskyblue/apkinfo/releases 使用 ...

  4. 自动手动随便你 Win7驱动程序安装自己设

    Win7系统是非常智能方便的操作系统,可以自动安装硬件驱动程序,为用户提供了很多方便.但是并不是所有的驱动程序和硬件都能完美兼容,如果不合适就需要卸载了重新安装:还有一些朋友就习惯自己安装驱动,那么, ...

  5. new 运算符干了什么

    为了追本溯源, 我顺便研究了new运算符具体干了什么?发现其实很简单,就干了三件事情. var obj = {}; obj.__proto__ = F.prototype; F.call(obj); ...

  6. springboot 2.0 自动装配原理 以redis为例

    当面试管问你springboot 和 普通spring 有什么区别? 您还在回答: 简化了配置 ,内置tomcat 等等 吗 ? 那只是皮毛, 最重要的还是自动化配置.一起来了解一下 第一步: 第二步 ...

  7. 利用Nginx rewrite规则实现域名显性转发

    体验更优排版请移步原文:http://blog.kwin.wang/website/nginx-rewrite-realize-domain-forward.html 自己的blog域名最开始用的vb ...

  8. Spring Boot SSO单点登入

    https://github.com/ITDragonBlog/daydayup/tree/master/SpringBoot-SSO 流程图: 1: Redis 保存用户信息 到Redis(KEY- ...

  9. OpenLayers 3 扩展插件收集

    OpenLayers 3 扩展插件 Awesome-OpenLayers OL3扩展 ol3-ext 很酷的一组 OpenLayers 3 (ol3) 扩展: 编辑-选择控件.CSS popup(弹出 ...

  10. Linux命令之sed批量替换字符串操作

    使用sed命令可以进行字符串的批量替换操作,以节省大量的时间及人力: 使用的格式如下: sed -i "s/oldstring/newstring/g" `grep oldstri ...