HTTP/2 Server Push 详细解释(下)

HTTP2 Server Push的研究

2017/01/05 · 基础技术 ·
HTTP/2

原文出处:
AlloyTeam   

问题:加载一个页面所需的资源,需要多次请求。例如加载index需要请求三次:index.html、index.js、index.css。

HTTP/2 Server Push 详解(下)

2017/04/23 · 基础技术 ·
HTTP

原文出处: Jeremy
Wagner   译文出处:AlloyTeam   

接上篇 HTTP/2 Server Push 详解(上)

译者注:上文介绍了 HTTP/2 Server Push
的基本概念和用法,下面继续深入实际使用的性能和考量。

收录待用,修改转载已取得腾讯云授权

1,HTTP2的新特性。

关于HTTP2的新特性,读着可以参看我之前的文章,这里就不在多说了,本篇文章主要讲一下server
push这个特性。

HTTP,HTTP2.0,SPDY,HTTPS你应该知道的一些事

 

解决思路:Server在接收到加载index请求时,同时返回index.html、index.js、index.css。

如何分辨 Server Push 是否生效

目前,我们已经通过 Link
首部来告诉服务器推送一些资源。剩下的问题是,我们怎么知道是否生效了呢?

这还要看不同浏览器的情况。最新版本Chrome将在开发者工具的网络发起栏中展示推送的资源。

图片 1

Chrome显示服务器推送的资源(大图)

更进一步,如果把鼠标悬停在网络请求瀑布图中的资源上,将获得关于该推送资源的详细耗时信息:

图片 2

Chrome显示推送资源的详细耗时信息(大图)

Firefox对推送资源则标识地没那么明显。如果一个资源是被推送的,则浏览器开发者工具的网络信息里,会将其状态显示为一个灰色圆点。

图片 3

Firefox对推送资源的展示(大图)

如果你在寻找一个确保能分辨资源是否为推送的方法,可以使用 nghttp
命令行客户端来检查是否来自 HTTP/2
服务器,像这样:

nghttp -ans

1
nghttp -ans https://jeremywagner.me

这个命令会显示出会话中所有资源的汇总结果。推送的资源将在输出中显示一个星号(*),像这样:

id responseEnd requestStart process code size request path 13 +50.28ms
+1.07ms 49.21ms 200 3K / 2 +50.47ms * +42.10ms 8.37ms 200 2K
/css/global.css 4 +50.56ms * +42.15ms 8.41ms 200 157
/css/fonts-loaded.css 6 +50.59ms * +42.16ms 8.43ms 200 279 /js/ga.js 8
+50.62ms * +42.17ms 8.44ms 200 243 /js/load-fonts.js 10 +74.29ms *
+42.18ms 32.11ms 200 5K /img/global/jeremy.png 17 +87.17ms +50.65ms
36.51ms 200 668 /js/lazyload.js 15 +87.21ms +50.65ms 36.56ms 200 2K
/img/global/book-1x.png 19 +87.23ms +50.65ms 36.58ms 200 138
/js/debounce.js 21 +87.25ms +50.65ms 36.60ms 200 240 /js/nav.js 23
+87.27ms +50.65ms 36.62ms 200 302 /js/attach-nav.js

1
2
3
4
5
6
7
8
9
10
11
12
id  responseEnd requestStart  process code size request path
13     +50.28ms      +1.07ms  49.21ms  200   3K /
  2     +50.47ms *   +42.10ms   8.37ms  200   2K /css/global.css
  4     +50.56ms *   +42.15ms   8.41ms  200  157 /css/fonts-loaded.css
  6     +50.59ms *   +42.16ms   8.43ms  200  279 /js/ga.js
  8     +50.62ms *   +42.17ms   8.44ms  200  243 /js/load-fonts.js
10     +74.29ms *   +42.18ms  32.11ms  200   5K /img/global/jeremy.png
17     +87.17ms     +50.65ms  36.51ms  200  668 /js/lazyload.js
15     +87.21ms     +50.65ms  36.56ms  200   2K /img/global/book-1x.png
19     +87.23ms     +50.65ms  36.58ms  200  138 /js/debounce.js
21     +87.25ms     +50.65ms  36.60ms  200  240 /js/nav.js
23     +87.27ms     +50.65ms  36.62ms  200  302 /js/attach-nav.js

这里,我在自己的站点上使用了
nghttp,有五个推送的资源(至少在写这篇文章时)。推送的资源在 requestStart
栏左侧以星号标记了出来。

现在我们知道了如何识别推送的资源,接下里具体看看对真实站点的性能有什么实际影响。


2,Server Push是什么。

简单来讲就是当用户的浏览器和服务器在建立链接后,服务器主动将一些资源推送给浏览器并缓存起来,这样当浏览器接下来请求这些资源时就直接从缓存中读取,不会在从服务器上拉了,提升了速率。举一个例子就是:

假如一个页面有3个资源文件index.html,index.css,index.js,当浏览器请求index.html的时候,服务器不仅返回index.html的内容,同时将index.css和index.js的内容push给浏览器,当浏览器下次请求这2两个文件时就可以直接从缓存中读取了。

Client:

测量 Server Push 性能

测量任何性能提升的效果都需要很好的测试工具。Sitespeed.io 是一个可从
npm
获取的优秀工具,它可以自动地测试页面,收集有价值的性能数据。有了得力的工具,我们来快速过一下测试方法吧。

译者:TAT.Johnny

3,Server Push原理是什么。

要想了解server
push原理,首先要理解一些概念。我们知道HTTP2传输的格式并不像HTTP1使用文本来传输,而是启用了二进制帧(Frames)格式来传输,和server
push相关的帧主要分成这几种类型:

  1. HEADERS
    frame(请求返回头帧):这种帧主要携带的http请求头信息,和HTTP1的header类似。
  2. DATA frames(数据帧) :这种帧存放真正的数据content,用来传输。
  3. PUSH_PROMISE
    frame(推送帧):这种帧是由server端发送给client的帧,用来表示server
    push的帧,这种帧是实现server push的主要帧类型。
  4. RST_STREAM(取消推送帧):这种帧表示请求关闭帧,简单讲就是当client不想接受某些资源或者接受timeout时会向发送方发送此帧,和PUSH_PROMISE
    frame一起使用时表示拒绝或者关闭server push。

Note:HTTP2.0相关的帧其实包括10种帧,正是因为底层数据格式的改变,才为HTTP2.0带来许多的特性,帧的引入不仅有利于压缩数据,也有利于数据的安全性和可靠传输性。

了解了相关的帧类型,下面就是具体server push的实现过程了:

  1. 由多路复用我们可以知道HTTP2中对于同一个域名的请求会使用一条tcp链接而用不同的stream
    ID来区分各自的请求。
  2. 当client使用stream
    1请求index.html时,server正常处理index.html的请求,并可以得知index.html页面还将要会请求index.css和index.js。
  3. server使用stream 1发送PUSH_PROMISE
    frame给client告诉client我这边可以使用stream 2来推送index.js和stream
    3来推送index.css资源。
  4. server使用stream 1正常的发送HEADERS frame和DATA
    frames将index.html的内容返回给client。
  5. client接收到PUSH_PROMISE frame得知stream 2和stream
    3来接收推送资源。
  6. server拿到index.css和index.js便会发送HEADERS frame和DATA
    frames将资源发送给client。
  7. client拿到push的资源后会缓存起来当请求这个资源时会从直接从从缓存中读取。

下图表示了整个流程:

图片 4

Link: </css/styles.css>; rel=preload; as=style, </js/scripts.js>; rel=preload; as=script, </img/logo.png>; rel=preload; as=image

测试方法

我想通过一个有意义的方法,来测量 Server Push
对网站性能的影响。为了让结果是有意义的,我需要建立6种独立的场景来交叉对比。这些场景以两个方面进行分隔:使用
HTTP/2 或 HTTP/1。在 HTTP/2 服务器上,我们想测量 Server Push
在多个指标的效果。在 HTTP/1
服务器上,我们想看看内联资源的方法,在相同指标中对性能有什么影响,因为内联应该能达到和
Server Push 差不多的效果。具体场景如下:

  • 未使用 Server Push 的HTTP/2

网站使用了 HTTP/2 协议,但没有资源是被推送的。

  • 仅推送 CSS 的 HTTP/2

使用了 Server Push,但仅用在了 CSS 资源。该网站的 CSS
体积比较小,经过 Brotli
压缩后仅有2KB多一点。

  • 推送所有资源

网站的所有资源都是推送的。包括了上面的 CSS,以及6个JS(合计
1.4KB)、5个SVG图片(合计5.9KB)。这些资源同样经过了压缩处理。

  • 未内联资源的HTTP/1

网站只运行在 HTTP/1 上,没有内联任何资源,来减少请求数和加快渲染速度。

  • 只内联 CSS

只有网站的 CSS 被内联了。

  • 内联所有资源

页面上的所有资源都进行了内联。CSS 和脚本是普通内联,而 SVG 图片是经过
Base64 编码方式直接放入 HTML 标签中。值得一提的是 Base64
编码后体积比原先大了1.37倍。

在每个场景中,都使用下面的命令开始测试:

sitespeed.io -d 1 -m 1 -n 25 -c cable -b chrome -v

1
sitespeed.io -d 1 -m 1 -n 25 -c cable -b chrome -v https://jeremywagner.me

如果想知道这个命令的输入、输出,可以参看文档。简而言之,这个命令测试了我的网站
的主页,使用了下面的条件:

  • 页面中的链接无法抓取。只测试指定的页面。
  • 页面测试25次
  • 使用了“有线宽带”级的网络配置。回路时间(译者注:RTT)为28ms,下行带宽是5000kbps,上行带宽为1000kbps。
  • 测试使用 Google Chrome

每项测试中收集和展示3项指标:

  • 首屏渲染时间

页面在浏览器首次展现的时间点。当我们努力让一个页面“感觉上”加载很快,那么这个指标是我们要尽量降低的。

  • DOMContentLoaded 时间

这个是 HTML 完成加载与解析的时间。同步的 JavaScript
代码会阻塞解析,并导致这个时间增加。在// <![CDATA[
标签上使用 async 属性可以避免对解析的阻塞。

  • 页面加载时间

这个是整个页面完成所有资源加载的耗时。

测试的所有因素都确定后,让我们看看结果!

原文:

4,Server Push怎么用。

既然server
push这么神奇,那么我们如何使用呢?怎么设置服务器push哪些文件呢?

首先并不是所有的服务器都支持server
push,nginx目前还不支持这个特性,可以在nginx的官方博客上得到证实,但是Apache和nodejs都已经支持了server
push这一个特性,需要说明一点的是server
push这个特性是基于浏览器和服务器的,所以浏览器并没有提供相应的js
api来让用户直接操作和控制push的内容,所以只能是通过header信息和server的配置来实现具体的push内容,本文主要以nodejs来说明具体如何使用server
push这一特性。

准备工作:下载nodejs
http2支持,本地启动nodejs服务。

1. 首先我们使用nodejs搭建基本的server:

JavaScript

var http2 = require(‘http2’);   var url=require(‘url’); var
fs=require(‘fs’); var mine=require(‘./mine’).types; var
path=require(‘path’);   var server = http2.createServer({   key:
fs.readFileSync(‘./zs/localhost.key’),   cert:
fs.readFileSync(‘./zs/localhost.crt’) }, function(request, response) {
    var pathname = url.parse(request.url).pathname;     var realPath =
path.join(“my”, pathname);    //这里设置自己的文件名称;       var
pushArray = [];     var ext = path.extname(realPath);     ext = ext ?
ext.slice(1) : ‘unknown’;     var contentType = mine[ext] ||
“text/plain”;       if (fs.existsSync(realPath)) {  
        response.writeHead(200, {             ‘Content-Type’:
contentType         });  
        response.write(fs.readFileSync(realPath,’binary’));       } else
{       response.writeHead(404, {           ‘Content-Type’: ‘text/plain’
      });         response.write(“This request URL ” + pathname + ” was
not found on this server.”);       response.end();     }   });  
server.listen(443, function() {   console.log(‘listen on 443’); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var http2 = require(‘http2’);
 
var url=require(‘url’);
var fs=require(‘fs’);
var mine=require(‘./mine’).types;
var path=require(‘path’);
 
var server = http2.createServer({
  key: fs.readFileSync(‘./zs/localhost.key’),
  cert: fs.readFileSync(‘./zs/localhost.crt’)
}, function(request, response) {
    var pathname = url.parse(request.url).pathname;
    var realPath = path.join("my", pathname);    //这里设置自己的文件名称;
 
    var pushArray = [];
    var ext = path.extname(realPath);
    ext = ext ? ext.slice(1) : ‘unknown’;
    var contentType = mine[ext] || "text/plain";
 
    if (fs.existsSync(realPath)) {
 
        response.writeHead(200, {
            ‘Content-Type’: contentType
        });
 
        response.write(fs.readFileSync(realPath,’binary’));
 
    } else {
      response.writeHead(404, {
          ‘Content-Type’: ‘text/plain’
      });
 
      response.write("This request URL " + pathname + " was not found on this server.");
      response.end();
    }
 
});
 
server.listen(443, function() {
  console.log(‘listen on 443’);
});

这几行代码就是简单搭建一个nodejs
http2服务,打开chrome,我们可以看到所有请求都走了http2,同时也可以验证多路复用的特性。

图片 5

这里需要注意几点:

  1. 创建http2的nodejs服务必须时基于https的,因为现在主流的浏览器都要支持SSL/TLS的http2,证书和私钥可以自己通过OPENSSL生成。
  2. node http2的相关api和正常的node httpserver相同,可以直接使用。

  3. 设置我们的server push:

JavaScript

var pushItem = response.push(‘/css/bootstrap.min.css’, {        request:
{             accept: ‘*/\*’        },       response: {
            ‘content-type’: ‘text/css’      } });
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

1
2
3
4
5
6
7
8
9
var pushItem = response.push(‘/css/bootstrap.min.css’, {
       request: {
            accept: ‘*/\*’
       },
      response: {
            ‘content-type’: ‘text/css’
     }
});
pushItem.end(fs.readFileSync(‘/css/bootstrap.min.css’,’binary’));

我们设置了bootstrap.min.css来通过server
push到我们的浏览器,我们可以在浏览器中查看:

图片 6

可以看到,启动server push的资源timelime非常快,大大加速了css的获取时间。

这里需要注意下面几点:

  1. 我们调用response.push(),就是相当于server发起了PUSH_PROMISE
    frame来告知浏览器bootstrap.min.css将会由server push来获取。
  2. response.push()返回的对象时一个正常的ServerResponse,end(),writeHeader()等方法都可以正常调用。
  3. 这里一旦针对某个资源调用response.push()即发起PUSH_PROMISE
    frame后,要做好容错机制,因为浏览器在下次请求这个资源时会且只会等待这个server
    push回来的资源,这里要做好超时和容错即下面的代码:
  4. JavaScript

    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {        response.writeHead(404, {           
    ‘Content-Type’: ‘text/plain’        });        response.end(‘request
    error’); }   pushItem.stream.on(‘error’, function(err){
        response.end(err.message); });   pushItem.stream.on(‘finish’,
    function(err){    console.log(‘finish’); });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    try {
        pushItem.end(fs.readFileSync(‘my/css/bootstrap.min.css’,’binary’));
        } catch(e) {
           response.writeHead(404, {
               ‘Content-Type’: ‘text/plain’
           });
           response.end(‘request error’);
    }
     
    pushItem.stream.on(‘error’, function(err){
        response.end(err.message);
    });
     
    pushItem.stream.on(‘finish’, function(err){
       console.log(‘finish’);
    });

    上面的代码你可能会发现许多和正常nodejs的httpserver不一样的东西,那就是stream,其实整个http2都是以stream为单位,这里的stream其实可以理解成一个请求,更多的api可以参考:node-http2。

  5. 最后给大家推荐一个老外写的专门服务http2的node
    server有兴趣的可以尝试一下。

Server
Apache: FilesMatch、H2PushResource
Nginx:不支持

测试结果

经过对上述6种场景的测试,我们将结果以图表形式做了展示。先看看各个场景的首屏渲染时间情况:

图片 7

首屏渲染时间(大图)

让我们先讲讲图表是如何设计的。图中蓝色部分代表了首屏渲染的平均时间,橙色部分是90%的情况,灰色部分代表了首屏渲染的最长耗时。

接下来我们讨论结果。最慢的情形是未使用任何优化的 HTTP/2 和
HTTP/1。可以看到,对 CSS 使用 Server Push
使页面渲染平均速度提升了8%,而内联 CSS 也比简单的 HTTP/1 提升了5%速度。

当我们尽可能地推送了所有资源,图片却显示出了一些异样,首屏渲染时间有所轻微增加。在
HTTP/1
中我们尽可能内联所有资源,性能表现和推送所有资源差不多,仅仅少了一点时间。

结论很明确:使用 Server Push,我们能获得比 HTTP/1
中使用内联更优的性能。但随着推送或内联的资源增多,提升的效果逐渐减少。

使用 Server Push
或内联虽好,但对于首次访问的用户并没有太大价值(译者注:实际上对于首次访问用户有很大的性能提升,猜测作者这里写错了)。另外,这些测试实验是运行在较少资源的站点上,所以未必能反映出你的网站的使用情况。

我们再看看各项测试对 DOMContentLoaded 时间的影响:

图片 8

DOMContentLoaded
时间(大图)

数据趋势跟刚才看到的图表没太大差别,除了一个需要注意的区别:在 HTTP/1
中尽可能地内联资源,相对 DOMContentLoaded
时间非常低。可能的原因是内联减少了需要下载的资源数,从而保证解析器(parser)可以不被打断地工作。

最后再看看页面加载时间的情况:

图片 9

页面加载时间(大图)

各项测量数据依然保持了先前的趋势。仅推送 CSS
时加载时间最短。推送所有资源会偶尔导致服务迟缓,但毕竟还是比什么都不做表现更优。与内联相比,Server
Push 的各项情况都是优于内联的。

在做最后总结前,还要讲讲使用 Server Push 时可能遇到的“坑”。

作者:Jeremy
Wagner

5,Server Push相关问题。

  1. 我们知道现在我们web的资源一般都是放在CDN上的,那么CDN的优势和server
    push的优势有何区别呢,到底是哪个比较快呢?这个问题笔者也一直在研究,本文的相关demo都只能算做一个演示,具体的线上实践还在进行中。
  2. 由于HTTP2的一些新特性例如多路复用,server
    push等等都是基于同一个域名的,所以这可能会对我们之前对于HTTP1的一些优化措施例如(资源拆分域名,合并等等)不一定适用。
  3. server
    push不仅可以用作拉取静态资源,我们的cgi请求即ajax请求同样可以使用server
    push来发送数据。
  4. 最完美的结果是CDN域名支持HTTP2,web server域名也同时支持HTTP2。

 

参考资料:

  1. HTTP2官方标准:
  2. 维基百科:
  3. 1 赞 1 收藏
    评论

图片 10

使用 Server Push 的一些建议

Server Push 并不是性能优化的万金油,它也有一些需要注意的地方。

译者按:网络优化一直是译者长期研究的方向,HTTP/2
的理论学习也已做了不少,随着这项标准的推进,越来越多特性被大家开始使用。作为
HTTP/2 最激动人心的特性,Server Push
在性能提升的效果被寄予了很高期望,却因其对传统 B/S
架构的开发模式影响较大未能广泛实践。如何更好地使用这项能力,让我们跟着作者深入探索。

推送过多资源

前面的一项测试中,我推送了很多资源,但它们加起来也只占传输数据的一小部分。一次推送很多大资源的话,会造成页面渲染及可交互时间的延迟,因为浏览器不但要加载
HTML
文档,还要同时下载推送的资源。最好的做法是有选择性地推送,样式表文件是个不错的开始(目前它们并不是很大),接着再评估还有什么其他资源适合推送。

在过去的一年时间,HTTP/2
的出现为关注性能的开发者带来了显著的变化。HTTP/2
已经不再是我们期待中的特性,而是伴着 Server
Push(服务端推送)能力已然到来。

推送页面以外的资源

如果你有访客统计分析,那么这种做法也未必不好。一个好的例子是,在多页注册账户表单场景,可以推送下一页的注册步骤资源。但要澄清的是,如果你不确定用户是否会访问后续的页面,千万不要尝试推送它的资源。有些用户的流量是十分珍贵的,这么做可能会导致其不必的损失。

除了解决常见的 HTTP/1 性能问题(比如,首部阻塞和未压缩的报头),HTTP/2
还提供了 Server Push
能力!服务端推送允许我们向用户发送一些还没有被访问的资源。这是一种获得
HTTP/1
优化实践(例如内联)所带来性能提升的优雅方式,同时也避免了原先实践的一些缺点。

正确地配置 HTTP/2 服务

有些服务器会给出很多 Server Push 的配置选项。Apache 的 mod_http2
模块有一些关于如何推送资源的配置选项。H2PushPriority设置就比较有意思,虽然在我的服务器上使用了默认设置。有一些实验性的配置可以获得额外的性能提升。每一种
Web服务器都有其整套不同的实验性配置,所以查看你的服务器手册,看看有哪些配置可以用起来吧!

本文中,你将了解什么是 Server
Push,它的工作原理与解决了哪些问题。同时你也将学习如何使用它,判断它是否正常运作,以及它对性能的影响。让我们开始吧!

推送资源可能不被缓存

Server Push
也有一些有损性能的的情况,对于访问网站的回头客们,一些资源可能会被非必要地进行推送。有些服务器会尽可能地减轻这种影响。Apache
的 mod_http2 模块使用了H2PushDiarySize
设置对这一点进行了一些优化。H2O
服务器有一种 Server Push
缓存感知特性,使用了
Cookie 机制来记录推送行为。

如果你不是使用 H2O服务器,也可以使用服务端代码实现同样的效果,即只推送
Cookie 记录外的资源。如果有兴趣了解具体做法,可以查看我在 CSS Tricks
上的文章。值得一提的是,浏览器可以向服务器发送一个 RST_STREAM
帧来通知不需推送的资源。随着时间推移,这个问题的解决将会愈加优雅。

最后来总结一下以上学到的内容。

Server Push 为何物

访问网站始终遵循着请求——响应模式。用户将请求发送到远程服务器,在一些延迟后,服务器会响应被请求的内容。

对网络服务器的初始请求通常是一个 HTML
文档。在这种情况下,服务器会用所请求的 HTML
资源进行响应。接着浏览器开始对 HTML
进行解析,过程中识别其他资源的引用,例如样式表、脚本和图片。紧接着,浏览器对这些资源分别发起独立的请求,等待服务器返回。

图片 11

典型的服务器通信(大图)

这一机制的问题在于,它迫使用户等待这样一个过程:直到一个 HTML
文档下载完毕后,浏览器才能发现和获取页面的关键资源。从而延缓了页面渲染,拉长了页面加载时间。

有了 Server Push,就有了解决上述问题的方案。Server Push
能让服务器在用户没有明确询问下,抢先地“推送”一些网站资源给客户端。只要正确地使用,我们可以根据用户正在访问的页面,给用户发送一些即将被使用的资源。

比如说你有一个网站,所有的页面都会在一个名为 styles.css
的外部样式表中,定义各种样式。当用户向务器请求 index.html
时,我们可以向用户推送 styles.css,同时我们发送 index.html。

图片 12

使用HTTP/2 Server
Push的Web服务器通信(大图)

相比等待服务器发送 index.html,然后等待浏览器请求并接收
styles.css,用户只需等待服务器的响应,就可在初次请求同时使用 index.html
和 styles.css。

可以想象,这可以降低一个页面的渲染时间。它还解决了一些其他问题,特别是在前端开发工作流方面。

最后的思考

如果你已经将自己的网站迁移到
HTTP/2,你没有什么理由使用服务器推送。如果你的网站因有过多的资源而显得复杂,可以从体积较小的资源开始尝试。一个好的经验法则是,考虑推送那些你曾经用到内联的资源。推送
CSS
是个不错的开始。如果感觉更有冒险精神之后,就考虑推送其他资源。要牢记在改动后测试对性能的影响。下了一定功夫后,你一定能从中有所受益。

如果你没有用像 H2O 这样使用缓存感知推送机制的服务器,可以考虑用 cookie
追踪你的用户,只在没有相关 cookie
的情况下给他们推送资源。这样可以为未知用户提升着性能的同时,最小化向已知用户的资源推送量。这不仅利于性能优化,也向用户展示了数据用量的尊重。

剩下的就需要你自己在服务器上折腾 Server Push
了,看看有哪些特性可以对你或用户有用吧。如果你想了解更多关于 Server
Push,看看这些资源吧:

  • “Server Push,”
    “Hypertext Transfer Protocol Version 2 (HTTP/2),” Internet
    Engineering Task Force
  • “Modernizing Our Progressive Enhancement
    Delivery,”
    Scott Jehl, Filament Group
  • “Innovating with HTTP 2.0 Server
    Push,”
    Ilya Grigorik

    1 赞 收藏
    评论

图片 10

Server Push 解决了什么问题?

Server Push
解决了减少关键内容网络回路的耗时问题,但这并不是唯一作用。Server Push
更像是 HTTP/1 特定优化反模式的替代方案,例如将 CSS 和 JavaScript 内联在
HTML,以及使用data
URI方案将二进制数据嵌入到
CSS 和 HTML 中。

这些技术在 HTTP/1
优化工作流中非常受用,是因为这样减少了我们所说的页面“感知渲染时间”,也就是说在页面整体加载时间可能不会减少的同时,对用户而言网页的加载速度却显得更快。这确实是说得通的,如果你将
CSS 内嵌到 HTML 的

发表评论

电子邮件地址不会被公开。 必填项已用*标注