谈谈HTTP/2对前端的影响【转载】

原文:http://www.peep-squirrel.com/itcontent-2500617.htmljavascript

 

 

随着 HTTP/2 规范的确认,以及主流浏览器(Chrome、Firefox、IE11)对其的全面支持,是时候采用新协议了。看了不少博文跟官方说明,在此作个总结,css

为何要有 HTTP/2 ?

一句话评价:预先加载,合并请求,缩小数据,提高性能html

HTTP 1.1时代,每一个TCP链接一次只能下载一个资源,好比浏览器发送一个请求获取index.html的数据,服务端收到后只会返回index.html,随后浏览器会解析index.html,若是里面含有<link rel="stylesheet" href="xxx.css"><script src="app.js"></script>,则会再次向服务器发送请求,获取xxx.cssapp.js的数据。 这一过程会产生 三个性能问题前端

  1. 若是index.html里含有多个js和css文件,请求数则随之增长,从而致使在TCP往返链接所耗费的时间增多。
  2. 每次发送的请求,HTTP头部信息基本是同样的,从而致使必定的头部信息冗余,耗费了没必要要的流量。
  3. index.html与内部的资源文件之间会产生了一个延时,而非同步获取。

因为上述问题,也就催生出了 HTTP/2。在HTTP/2中,多个请求是能够合并为一个的,以下图,多个数据请求容许在同一路中传输(Multiplexed),这样也就能够解决了 问题1。java

而由于是同一个请求,所以 HTTP头信息 只须要有一个就足够,下图可看出,HTTP/2中一个请求头中容许有多个方法,既能够GET,也能够PUT,在切换到下一个方法时,只须要获取数据便可,而不用再次获取头信息。node

并且,HTTP/2将头信息进行了压缩(参见HPACK),进一步的减小了头信息的大小,所以 问题2 获得了解决。git

同时,HTTP/2 新加入了 PUSH 方法,该方法的主要做用就是让服务器试探性的去推送信息给客户端,如 问题3 中所述状况,当请求index.html时,服务器在返回index.html的同时,会主动把xxx.cssapp.js一同发送给浏览器。这样当浏览器解析DOM,准备发送请求获取xxx.cssapp.js的时候,也许两个资源已经下载完了,只须要从缓存中获取便可。这样就大大减小了网络请求的时间。github

HTTP/2给前端带来哪些影响?

虽然HTTP/2是在协议方面的改进,且但其机制也对目前前端的部分优化方案产生必定影响。web

减小HTTP请求不必定提高性能

如上所述, HTTP/2 针对多个请求进行了优化,所以以前咱们在前端中所作的 关于减小HTTP请求的最佳实践都再也不适用,如合并JS、CSS文件(Concatenation),多个图片或图标合并(Spriting),将较小的JS或CSS文件内嵌到HTML中(Inlining),合并HTML文件(Vulcanize),根据 此网站 的测试结果显示,在使用HTTP/2后,合并为一个大文件的加载时间反而会比不合并更长。chrome

如上图所示,其中TTFB时间明显减小,所谓TTFB(Time To First Byte),即从浏览器发送请求开始,到接受到来自服务器的返回的第一字节信息(HTTP头信息)结束,之间所耗费的时间。这里就会包含 TCP链接往返(round trip)+服务器处理时间(如SQL执行)。 由于浏览器在第一次发送请求后,服务器已经预先把其余资源文件一同推送给了浏览器,所以后续的资源请求中,TTFB的时间获得了缩小。

压缩仍然须要

有些可能会问,那是否是用了 HTTP/2 后,资源文件也不须要压缩了呢? 答案是No,压缩文件仍是有必要的,毕竟获取一个小文件的时间比大文件更短,HTTP/2并不会帮你自动压缩文件。

能够看出,HTTP/2 目的之一,就在于想把开发环境与生产环境的部署尽可能保持一致,减小由于打包合并而产生一些没必要要的麻烦。

如何使用 HTTP/2 ?

目前一部分主流网站已经采用了 HTTP/2,而不少语言也已经有实施方案,详细的可见该 列表, 本文只介绍下如何用 NodeJS 搭建 HTTP/2 站点。

建立证书

虽然目前规范中并无达成一致意见来决定 HTTP/2 是否须要加密( Encryption ),但目前主流的实施方案都是须要加密的(如SSL/TLS),所以,如同 HTTPS,HTTP/2 一样须要建立公私密钥,来搭建站点。

建立Key:

openssl req -new -newkey rsa:2048 -nodes -keyout localhost.key -out localhost.csr

在输入完身份信息后,输出证书:

openssl x509 -req -days 365 -in localhost.csr -signkey localhost.key -out localhost.crt

搭建服务

若是是初次使用npm安装,则初始化npm依赖管理:

npm init

此时则会在当前目录中,生成一个package.json文件。

安装http2包:

npm install http2 –save

新建app.js文件:

var https = require('http2'); var fs = require('fs'); var options = { key: fs.readFileSync('localhost.key'), cert: fs.readFileSync('localhost.crt') }; https.createServer(options, function(request, response) { fs.readFile(__dirname + request.url, function (err,data) { if (err) { response.writeHead(404); response.end(JSON.stringify(err)); return; } response.writeHead(200); response.end(data); }); }).listen(8080);

验证

这样就搭建完毕,运行便可看到结果

node app.js

若是想确认是否真的采用了 HTTP/2, 只须要在Chrome Dev Tools > Network中,新增 Protocol,便可看到结果:

2015-12-25 更新:

另外注意一点,若是你是从http转向https,须要在服务端/客户端作个重定向,保证用户访问的站点是https而不是http。

// Redirect from http port 80 to https var http = require('http'); http.createServer(function (req, res) { res.writeHead(301, { "Location": "https://" + req.headers['host'] + req.url }); res.end(); }).listen(80);

或者在页面端:

var host = "YOURDOMAIN.github.io"; if ((host == window.location.host) && (window.location.protocol != "https:")) window.location.protocol = "https";

并且一旦搭建了https,页面内部全部的外部资源都必须实施https,不然会浏览器阻拦:

Mixed Content: The page at 'https://localhost:8080/index.html' was loaded over HTTPS, but requested an insecure script 'http://hectorguo.com/Universities-in-US/app.min.js'. This request has been blocked; the content must be served over HTTPS.

如何使用 PUSH ?

PUSH 是 HTTP/2 的新方法,虽然可让服务端预先推送资源给客户端,但并非说只要使用该方法性能就会提高,有时反而会降低。目前官方还未公布最佳实践方法,所以并不建议在生产环境中运用,但能够在开发环境下体验。

Google提供了一个 SimpleHttp2Server 来简单搭建 HTTP/2 并使用 PUSH 方法,NPM中也提供了一个 http2-push-manifest 包,能够自动检测 html文件中的请求资源,方便服务端识别须要PUSH的文件。

HTTP/2 部署现状

客户端

目前各大浏览器对 HTTP/2 的支持度以下:

能够看出基本能够不用担忧浏览器的支持度问题,并且因为与HTTP 1.1的API一致,只要 服务端部署完成,便可无缝体验。

服务端

Chrome有个 插件,能够简单的监测站点是否采用了 HTTP/2, 通过一些主流网站的观察,发现国外站点的部署效率的确要高不少。

Google、Twitter、YouTube目前都采用 HTTP/2 (蓝色⚡️表明H2)

而国内看了下,百度,必应都木有采用,而淘宝采用了SPDY 3.1(能够看做H2的前一代,绿色⚡️)

参考

  1. https://http2.github.io/faq/
  2. https://http2-push.appspot.com/
  3. http://blog.httpwatch.com/2015/01/16/a-simple-performance-comparison-of-https-spdy-and-http2/
  4. https://github.com/molnarg/node-http2
  5. https://bjartes.wordpress.com/2015/02/19/creating-a-http2-server-with-node-js/
  6. https://www.futurehosting.com/blog/what-does-http2-mean-for-web-designers/
  7. https://github.com/GoogleChrome/simplehttp2server
  8. https://www.youtube.com/watch?v=r5oT_2ndjms
相关文章
相关标签/搜索