Web Streams 的隐性开销与JavaScript 流处理新方案

Web Streams 的隐性开销与JavaScript 流处理新方案

处理视频流时突然卡顿?处理大文件时内存爆表?这些看似奇怪的问题,可能源于 JavaScript 中一个被广泛采用但设计复杂的标准 API——Web Streams。当你的 Node.js 应用突然因为未消费的 body 耗尽连接池,或者处理大文件时内存爆表,你可能已经踩过 Web Streams 的坑了。

问题:Web Streams 的设计缺陷

Web Streams 是 JavaScript 中处理数据流的标准 API,2014-2016 年设计,旨在统一浏览器和服务器的数据流处理。它被用于 fetch()、Node.js、Cloudflare Workers 等场景,成为现代 Web 应用的数据传输基础。WHATWG Streams Standard 文档 定义了这套机制,初衷是让开发者能以统一方式处理实时数据、大文件、网络请求等流式场景。然而,经过多年的实际使用,开发者们发现这个标准 API 存在诸多问题。

例如,读取流数据需要繁琐的锁管理:const reader = stream.getReader();reader.releaseLock();,一旦忘记释放锁,整个流就永久锁死。更严重的是,response.clone() 这样的 API 会隐式创建分支流,如果不消费所有分支,会导致连接池耗尽。Matteo Collina(Node.js 技术委员会主席)在讨论中指出:「Cloning streams in Node.js’s fetch() implementation is harder than it looks… the coordination required between two readers sharing one source makes it easy to accidentally break the original request or exhaust connection pools.」(在 Node.js 的 fetch() 实现中克隆流比看起来困难得多……共享单个源的两个读取器之间需要协调,这很容易意外破坏原始请求或耗尽连接池。)

BYOB(自带缓冲区)机制本为优化内存,但实际使用复杂:需要单独的 ReadableStreamBYOBReader,处理缓冲区转移,且几乎不被使用。背压机制也形同虚设——desiredSize 只是建议值,生产者可以无视地持续写入,导致内存无限增长。Vercel 的 研究 显示,Node.js 中 Web Streams 管道性能比优化后方案低 12 倍,主要问题在于「Promise 和对象分配开销」。

新方案:原生异步迭代流

一位 Cloudflare 工程师提出新方案:将流设计为原生 async iterable,直接通过 for await...of 消费,无需锁管理。数据仅在消费时处理(pull-through),批量处理 Uint8Array[] 减少 Promise 开销,同步/异步分离路径避免无谓开销。例如,创建和消费流的代码从:

const{ readable, writable }=newTransformStream();const enc =newTextEncoder();const writer = writable.getWriter();await writer.write(enc.encode("Hello, World!"));await writer.close(); writer.releaseLock();const dec =newTextDecoder();let text ='';forawait(const chunk of readable){ text += dec.decode(chunk,{stream:true});} text += dec.decode();

简化为:

import{ Stream }from'new-streams';const{ writer, readable }= Stream.push();await writer.write("Hello, World!");await writer.end();const text =await Stream.text(readable);

性能测试显示,新方案比 Web Streams 快 2-120 倍。例如,链式 3 次转换场景提升 80-90 倍,async iteration 快 40-100 倍。这是因为避免了中间缓冲区、减少了 Promise 创建,且同步场景可以完全跳过异步开销。一位 Node.js 核心贡献者评价:「We’ve done a lot to improve performance and consistency in Node streams, but there’s something uniquely powerful about starting from scratch. New streams’ approach embraces modern runtime realities without legacy baggage…」(我们在改进 Node 流的性能和一致性方面做了很多工作,但从零开始设计的流方案有种独特的力量,它拥抱现代运行时特性而没有历史包袱……)

开发者社区的争议与思考

Hacker News 上,开发者们对新方案有不同看法。有人质疑「每字节创建对象」的方案会导致 GC 压力,但支持者认为 JS 引擎可优化短生命周期对象。关于同步/异步分离,有人认为「应该统一 API 避免代码重复」,但也有开发者分享实际案例:Lit-SSR 通过「同步迭代器+thunk」实现 12-18 倍 SSR 性能提升。一位开发者指出:「The tension between ‘streams as lazy sequences’ vs ‘streams as async event channels’ isn’t unique to JavaScript. Every major runtime has hit this wall… .NET actually handled this better with IAsyncEnumerable in C# 8 — a single abstraction that’s pull-based but async-aware.」(「流作为惰性序列」和「流作为异步事件通道」之间的张力并非 JavaScript 独有,所有主流运行时都遇到过这个难题…….NET 通过 C# 8 的 IAsyncEnumerable 单一抽象(基于拉取且支持异步)实际上处理得更好。)

这不仅是技术改进,更是对开发体验的重视。当 API 设计回归简单、显式、高性能的原生迭代模式,开发者才能真正专注于业务逻辑,而不是与复杂 API「战斗」。正如一位开发者所说:「We deserve a better stream API. So let’s talk about what that could look like.」(我们值得拥有更好的流 API。那我们就来探讨下它可能的模样吧。)

在这里插入图片描述

Read more

Java Web 公交线路查询系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

Java Web 公交线路查询系统系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着城市化进程的加速,公共交通系统的复杂性和规模不断扩大,传统的公交线路查询方式已难以满足用户高效、精准的出行需求。公交线路查询系统的开发旨在解决这一问题,通过信息化手段提升公交出行的便捷性和智能化水平。该系统整合了公交线路、站点、换乘等关键信息,为用户提供实时查询、最优路径推荐等功能,同时优化公交资源管理效率。关键词:公交线路查询、智能化出行、信息化管理、SpringBoot、Vue3。 本系统采用前后端分离架构,后端基于SpringBoot2框架,结合MyBatis-Plus实现高效数据持久化操作,MySQL8.0作为数据库存储公交线路、站点及用户信息。前端使用Vue3构建响应式用户界面,提供线路查询、换乘推荐、站点导航等功能。系统支持多条件筛选和动态路径规划,确保用户能够快速获取最优出行方案。关键词:SpringBoot2、Vue3、MyBatis-Plus、MySQL8.0、路径规划。 数据表 公交线路数据表 公交线路数据表用于存储公交线路的基本信息,包括线路名称、运营方向、首末班时间等属性。线路编号是该表的主键,用于唯一标识每条线路。结构表如表3-1所示。

By Ne0inhk
音乐播放器实现:前端HTML,CSS,JavaScript综合大项目

音乐播放器实现:前端HTML,CSS,JavaScript综合大项目

音乐播放器实现:前端HTML,CSS,JavaScript综合大项目 * 项目概述 * 项目视图效果 * 一、侧边栏相关代码 * (一)HTML代码 * (二)css代码 * 二、登录页面 * (一)HTML代码 * (二)css代码 * (三)js代码 * 三、剩余代码以及所有源代码Gitee地址 项目概述 在当今数字化时代,音乐已然成为人们生活中不可或缺的一部分。本次带来的音乐播放器 HTML 项目,旨在打造一个具备基础且实用功能的音乐播放平台。通过 HTML、CSS 和 JavaScript 等前端技术的巧妙融合,实现一个界面美观、操作便捷的音乐播放器,满足用户在本地浏览音乐库、播放音乐等多样化需求。 提示!!!! 由于项目代码太多,代码全部内容放置在我的Gitee码云中,需要的小伙伴们自取 我的码云链接https://gitee.com/srte-7719/project-experience/tree/master/

By Ne0inhk
【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题 在开发 Web 应用时,尤其是集成了 Unity WebGL 内容的页面,遇到一个问题:当 Unity WebGL 渲染内容嵌入到一个 Tab 中时,切换 Tab 后画面会变黑,直到用户点击黑屏区域,才会恢复显示。 这个问题通常是因为 Unity 渲染在 Tab 切换时被暂停或未能获得焦点所致。 在本文中,我们将介绍如何在使用 Layui 框架时,通过监听 Tab 切换事件并强制 Unity WebGL 渲染恢复,来解决这一问题。 1. 问题描述 当 Unity WebGL 内容嵌入到页面中的多个

By Ne0inhk
Spring Boot携手Leaflet,点亮省级旅游口号WebGIS可视化之路

Spring Boot携手Leaflet,点亮省级旅游口号WebGIS可视化之路

目录 前言 一、旅游口号信息管理 1、写在前面的 2、空间属性关联 二、SpringBoot后台实现 1、系统调用时序图 2、Mapper数据查询实现 3、控制层接口实现 三、Leaflet集成实现WebGIS 1、省级数据展示及可视化 2、东北三省旅游口号 3、长三角城市群口号 4、珠三角旅游口号 5、西北地区旅游口号 四、总结 前言         在当今数字化浪潮汹涌澎湃的时代,地理信息系统(GIS)技术正以前所未有的速度改变着我们对世界的认知与探索方式。它不仅为科学研究提供了强大的工具,更在旅游、城市规划、环境保护等诸多领域展现出巨大的应用潜力。而当我们将目光聚焦于旅游行业,一个充满活力与创新的领域,GIS技术的应用更是如鱼得水,为旅游体验的提升和旅        游管理的优化带来了全新的机遇。         省级旅游口号作为各地旅游宣传的重要名片,承载着地域文化的精髓与旅游资源的亮点,是吸引游客、塑造旅游品牌形象的关键要素。然而,传统的旅游口号宣传方式往往局限于文字、

By Ne0inhk