HTTP2之Server Push从入门到放弃

771 阅读3分钟

Server Push是什么

当服务器接收到一个请求时,使用Server Push可以将多个资源文件一起发送给客户端。

乍一看,立即就想到好像可以用这个技术点优化前端资源请求。目前很多公司网站请求资源的顺序是:

  1. 请求html文件
  2. 服务端返回html文件
  3. 解析html文件
  4. 请求css、js等文件
  5. 服务端或cdn返回文件

如果用Server Push,请求应该是这样:

  1. 请求html文件
  2. 服务端返回css、js、html文件
  3. 解析html文件

简单对比之下,Server Push明显可以加快页面加载速度。既然如此,看看用node.js怎么实现Server Push。

node.js实践

原以为Server Push只是一个小功能点,实践起来应该不难。没想到还是遇到了问题,让我一度放弃,所以用好google还是很重要的。

首先我去node.js官网上找相关文档,没有找到适合新手入门的。这不重要,网上教程很多。我找了几个教程,失败了几次,这就跟配置开发环境一样,总是会遇到问题。

所幸最后还是成功启动服务了。教程网址忘记了,先贴上代码

index.js文件

const http2 = require("spdy");const logger = require("morgan");const express = require("express");const app = express();const fs = require("fs");let path = require("path");app.use(logger("dev"));app.get("/", function (req, res) {  res.send(`hello, http2! go to /pushy`);});app.get("/pushy", (req, res) => {  let stream = res.push("/main.js", {    status: 200, // optional    method: "GET", // optional    request: {      accept: "*/*",    },    response: {      "content-type": "application/javascript",    },  });  stream.on("error", function () {});  stream.end('alert("hello from push stream!");');  res.end('<html><body>123<script src="/main.js"></script></body></html>');});let options = {  key: fs.readFileSync(path.resolve("../local-cert-generator/server.key")),  cert: fs.readFileSync(path.resolve("../local-cert-generator/server.crt")),};http2.createServer(options, app).listen(8088, () => {  console.log(`Server is listening on https://localhost:8088.    You can open the URL in the browser.`);});

以上代码启动了端口号为8088的本地服务,有两个路由,其中/pushy是返回一个请求/main.js的html文件。

因为http2是基于https的,所以创建服务需要提供https证书和私钥,可以用OpenSSL生成。

执行node ./index.js,然后在chrome浏览器访问https://localhost/8088 ,遇到了第一个问题

问题:您的连接不是私密连接

连“继续前往”按钮都没有。问题肯定出自https证书和私钥,google了很久,终于在这篇教程里找到了解决方法:在Mac钥匙串中添加并信任OpenSSL生成的证书。

重新访问https://localhost/8088 ,遇到第二个问题

问题:Invalid typed array length: -4095

array长度怎么会是负数呢?又google了很久,终于在这里找到解决方法:把node版本改成v10.*.*

重新启动服务,终于看到正常的页面

在Network面板可以看到请求列表。main.js是从Push /pushy获取的,请求时长2ms

放弃

很多网站服务已经使用了http2协议,但是很少听说使用Server Push。因此,Server Push必定存在一些缺点。

  • 需要额外的服务端开发成本,开发者要根据请求匹配到push的资源。
  • 当浏览器已经缓存了被push的资源时,使用Server Push反而会增加资源加载时长。
  • google chrome提出Server Push只有在满足一定条件时才能改善加载性能,即:传输的内容size < 单位时间内带宽能传输的数据size,详细内容见这里

相关链接

如何快速在本地开发环境启动 HTTPS

RangeError: Invalid typed array length: -4095

HTTP/2之服务器推送(Server Push)最佳实践

Rules of Thumb for HTTP/2 Push