如何在nodejs中体验http/2详解
作者:空山与新雨 发布时间:2024-05-05 09:21:48
前言
2015年,HTTP/2 发布,直到2021年公司的项目才开始在实践中应用;自己对http2诸多特点的理解只存在于字面上,于是尝试在nodejs中实践一下,加深自己的理解。
多路复用
同域名下所有通信都在单个连接上完成,消除了因多个 TCP 连接而带来的延时和内存消耗,这在大量请求同时发出的情况下能够减少加载时间。
使用如下代码查看http2环境下,资源下载的情况(浏览器开启限流和disable cache):
const http2 = require('http2');
const fs = require('fs');
const { HTTP2_HEADER_PATH } = http2.constants;
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
// stream is a Duplex
const path = headers[':path'];
if(path === '/img.png' || path === '/favicon.ico'){
const fd = fs.openSync('img.png', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'image/png'
};
stream.respondWithFD(fd, headers);
} else if(path === '/') {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200
});
stream.end(`
<h1>Hello World</h1>
<script>
for(var i=0;i<50;i++){
fetch('/img.png')
}
</script>
`);
}
});
server.listen(8443);
可以看到当资源开始同时请求,所有的请求形成一个队列,请求之间开始时间相差大概1ms, 因为下载的是同一个图片,50张图片同时下载,最后几乎在同时完成下载。
下面是http1.1的例子,通过对比发现浏览器按照自己的最大并发量同时发出请求,只有当请求返回后才发出新的请求(浏览器开启限流和disable cache):
const http = require('http');
const fs = require('fs');
const server = http.createServer(function(req,res){
const path = req.url;
if(path === '/img.png' || path === '/favicon.ico'){
res.writeHead(200,{'Content-type':'image/png'})
var stream = fs.createReadStream('img.png')
stream.pipe(res)
} else {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`
<h1>Hello World</h1>
<script>
for(var i=0;i<50;i++){
fetch('/img.png')
}
</script>
`);
}
});
server.listen(8444);
服务端推送
按照如下代码测试
const http2 = require('http2');
const fs = require('fs');
const { HTTP2_HEADER_PATH } = http2.constants;
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem')
});
server.on('error', (err) => console.error(err));
server.on('stream', (stream, headers) => {
const path = headers[':path'];
if(path === '/') {
stream.respond({
'content-type': 'text/html; charset=utf-8',
':status': 200
});
stream.pushStream({ [HTTP2_HEADER_PATH]: '/style.css' }, (err, pushStream, headers) => {
if (err) throw err;
const fd = fs.openSync('style.css', 'r');
const stat = fs.fstatSync(fd);
const header = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/css'
};
pushStream.respondWithFD(fd, header)
});
stream.end(`
<h1>Hello World</h1>
<script>
setTimeout(()=>{
fetch('/style.css')
},2000)
</script>
`);
} else if(path === '/style.css'){
const fd = fs.openSync('style.css', 'r');
const stat = fs.fstatSync(fd);
const headers = {
'content-length': stat.size,
'last-modified': stat.mtime.toUTCString(),
'content-type': 'text/css'
};
stream.respondWithFD(fd, headers);
}
});
server.listen(8442);
资源加载情况如下,style.css的Initiator是Push,大小是66 B, 同时首页加载的大小是207 B,
注释掉stream.pushStream
部分后,不使用推送,资源加载如下,style.css大小是89B, 同时首页加载的大小是182B,
综上所看,服务端推送可以提前加载资源,优化非首页加载有益。
令人高兴的是,因为使用率低,chrome在105版本后不再支持http2的服务端推送,导致这个特点在前端开发中可以忽略了。并且如果要测试改特点需要使用低版本的chrome,比如本例子使用的是chrome 96 mac版本。
本文所用代码:https://github.com/blank-x/pg/tree/master/http2,nodejs版本是v16.19.0.
来源:https://www.cnblogs.com/walkermag/p/16995319.html


猜你喜欢
- 前言:把一个功能模块使用组件化的思想充分封装,如导航栏,这无论对我们的开发思想还是效率都有许多好处,在开发中,我们要尽量多得运用组件化的开发
- 一.一维数组的转置描述一维数组的重塑就是将一行或一列的数组转换为多行多列的数组重塑之后的数组应于原有数组形状兼容(数组元素应该相等)用法和参
- 本文实例讲述了Python计算回文数的方法。分享给大家供大家参考。具体如下:这里检查数字是不是回文数,用196算法生成一个数字的回文数num
- 爬取TOP500的音乐信息,包括排名情况、歌曲名、歌曲时间。网页版酷狗不能手动翻页进行下一步的浏览,仔细观察第一页的URL:http://w
- 太长不看的简洁版本1.x = np.arange(start, end, steps)Values are generated within
- 前言大家好,今天给大家带来绘制“手绘风格”可视化作品的小技巧,主要涉及Python编码绘制。主要内容
- 一、为什么要搭建爬虫代理池在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制,即在某一时间段内,当某个ip的访问次数达到一定的阀值时
- 概述从今天开始, 小白我将带领大家一起来补充一下 数据库的知识.MySQL 安装下载地址:https://dev.mysql.com/dow
- Kettle简介Kettle最早是一个开源的ETL(Extract-Transform-Load的缩写)工具,全称为KDE Extracti
- 最近在网上看到了一些测试,感觉不是很准确,今天亲自测试了一番。得出了结论,测试过程在个人计算机上,可能不够全面,仅供参考。测试过程:准备一张
- 本文实例为大家分享了Pyqt实现简易计算器的具体代码,供大家参考,具体内容如下环境:pycharm、python3.7首先用qtDesign
- 本文记录了python安装及环境配置方法,具体内容如下Python安装 Windowns操作系统中安装Python步骤一 下载安装包从Pyt
- 原文网址:gradio.app/sharing-you…1.分享演示share=True通过在方法中设置,可以轻松公开
- 前言mitmproxy 是 man-in-the-middle proxy 的简称,译为中间人代理工具,可以用来拦截、修改、保存 HTTP/
- 在前面的文章 Python 计算机视觉(十五)—— 图像特效处理 中我已经介绍了大部分的图像的特效处理,但还是忽略了油画特效的处理,在本篇文
- 如果您刚刚开始接触网页设计,是不是经常发生这样的问题呢?做好的网页在自己机器上可以正常浏览,而把页面传到服务器上就总是出现看不到图片,css
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:create or replace procedure PROC_test is --D
- 学习目的 接触验证控件 昨天介绍了SQL SERVER插入数据,但是我们省略了验证输入这一步。以前的做法是用语句逐个判断输入的正确性,如是否
- 本文实例为大家分享了python实现二叉树的遍历具体代码,供大家参考,具体内容如下代码:# -*- coding: gb2312 -*- c
- 本文实例讲述了python获取本机外网ip的方法。分享给大家供大家参考。具体如下:python从显示ip地址的网站获取本机外网ip,这段py