Server Push是什么
当服务器接收到一个请求时,使用Server Push可以将多个资源文件一起发送给客户端。
乍一看,立即就想到好像可以用这个技术点优化前端资源请求。目前很多公司网站请求资源的顺序是:
- 请求html文件
- 服务端返回html文件
- 解析html文件
- 请求css、js等文件
- 服务端或cdn返回文件
如果用Server Push,请求应该是这样:
- 请求html文件
- 服务端返回css、js、html文件
- 解析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,详细内容见这里。