Valuable insights
1.关注“首次数据时间”的性能指标: 衡量从打开网页到实际看到所需数据所需的时间至关重要,这是衡量用户体验和工具效率的关键指标,远超传统的前端渲染指标。
2.拥抱简洁性,目标是“烧毁后端”: 传统的复杂后端架构带来维护和协调难题;目标是尽可能删除组件,仅保留必要的CDN以应对物理延迟限制,实现架构的极致简化。
3.浏览器在数据处理中的潜力被低估: 现代浏览器API、WebAssembly (WASM) 和异步特性使得JavaScript能够处理复杂的计算任务,提供了构建高性能、无需服务器的应用的可能性。
4.云原生文件格式实现浏览器端查询: 利用GeoTIFF和Apache Parquet等格式的索引特性,通过HTTP Range Get请求,可以直接在浏览器中高效查询大型数据集,无需预先下载整个文件。
5.JavaScript在数据工程中应被重视: 前端不应是数据架构的 afterthought;从一开始就将界面视为核心,可以带来更快的用户体验和更优的开发效率,实现全栈功能一次实现。
引言与动机
演讲者Kenny Daniel来自西雅图一家早期初创公司,其背景通常在人工智能领域。本次演讲的核心主题是关于数据处理的性能和架构选择。最初的动机源于尝试训练一个世界级的JavaScript生成式AI模型,这要求必须对数据进行深入的探索和分析,从而引出了对现有数据工具性能的深刻反思和改进需求。
当前数据工具的问题
在数据科学的传统流程中,首要步骤是查找和检查数据,例如在Hugging Face上查看数据集。然而,随着数据集规模的爆炸式增长(如网络抓取或代码转储),嵌入式查看器往往表现不佳。当尝试深入查看数据时,用户经常会遇到一个分页表格的加载指示器(spinner),这表明现有工具在数据可视化方面存在严重的性能瓶颈。
首次数据时间:速度的重要性
本次演讲的核心关注点是“首次数据时间”,即从打开网页到实际看到所需数据的速度。演讲者认为Python在构建数据交互界面方面是效率最低的选择,因为它在UI构建方面能力有限,并且是异步处理能力较弱的语言之一。对于需要引人注目的界面的应用而言,必须在浏览器中实现,因此JavaScript是必然选择。
传统后端架构及其弊端
传统的系统架构通常包含前端、后端、关系数据库、指标和日志记录等多个复杂层级。这种结构导致了前后端团队之间的协调难题,后端团队构建API后“扔过墙”给前端,维护成本高昂,尤其是在需要部署到客户私有网络(VPC)时,安全检查和Kubernetes等基础设施的复杂性令人头疼。
工程师们都明白简洁性更好,那么在这个架构图中,我们可以删除哪些部分呢?
烧毁后端:拥抱简洁性
简洁性的目标是删除尽可能多的组件,包括后端、日志、基础设施和数据库。然而,为了追求速度和性能(即首次数据时间),CDN(如CloudFront)被保留下来,因为内容分发网络能够物理性地缩短用户与端点之间的往返时间,从而提升整体速度。
OpenAI与Anthropic:不同的数据处理方法
OpenAI的Code Interpreter模式涉及模型生成Python代码,将其发送到Docker容器或VM中运行以生成图表(通常是PNG格式),这种方式缺乏交互性且速度较慢。相比之下,Anthropic选择拥抱JavaScript,让Claude生成的代码直接在浏览器中运行,提供了更强的交互性,并将基础设施成本和沙箱责任转移给了用户。
构建无后端的前端优先应用
在不使用后端的情况下,可以通过多种方式处理状态存储和计算密集型任务。浏览器提供了Local Storage和IndexDB等存储API,以及Web Workers来处理耗时任务而不阻塞UI。此外,将S3对象存储作为基础层,结合HTTP Range Get请求和云原生数据格式,可以在浏览器中实现强大的功能。
本地优先应用:超越隐私和同步
“本地优先应用”这一术语容易产生歧义。它不一定指代像Gmail那样带有同步引擎的系统,后者实际上构建起来更复杂。它也不完全是出于隐私考虑,尽管保护数据不发送到云端很有价值。演讲者关注的重点是,利用本地能力可以使应用变得更快、更具交互性。
JSCAD:完全基于浏览器的 3D CAD
JSCAD项目是一个完全在浏览器中运行的开源代码CAD工具,用于生成3D设计,整个应用甚至可以托管在GitHub页面上,无需服务器基础设施成本。用户可以直接将本地文件拖入编辑器进行编辑和渲染,并且可以通过Ctrl+S将更改保存回本地磁盘,这得益于现代浏览器提供的文件访问API。
在从事这个项目之前,其实并不知道浏览器可以做到这一点,以为那会是安全噩梦。
云原生文件格式:GeoTIFF与Parquet
云原生文件格式是数据工程领域的一个新趋势。例如,云原生GeoTIFF文件用于存储卫星图像,其索引允许浏览器仅使用HTTP Range Get请求获取渲染地图所需的特定图块,避免了下载数GB的完整文件。Apache Parquet文件可以被视为带有压缩和内置索引的CSV文件,它也支持这种远程查询能力。
直接在浏览器中查询 Parquet 文件
为了实现在浏览器中直接查询Parquet文件的目标,演讲者发现现有的相关项目大多已处于废弃状态。因此,决定从零开始构建一个全新的项目,该项目完全使用纯JavaScript编写,不含任何依赖项,并实现了完整的Parquet规范,最终编译后的代码体积仅为10KB min+gzip。
Parquet加载方法的基准测试
对四种主要的Parquet文件加载方法进行了基准测试,包括ParquetJS和基于WASM的解决方案(如Parquet WASM或DuckDB WASM)。WASM方法的主要性能障碍在于需要先下载一个体积庞大的WASM模块(例如DuckDB WASM包超过20MB),这在开始数据获取之前就消耗了大量时间。
让 JavaScript 快速处理数据工程
优化JavaScript性能的关键在于避免网络往返,因为额外的网络延迟非常痛苦。其次,应尽量减少内存分配,因为内存分配和随后的垃圾回收都会消耗时间,理想情况是直接索引到原始的ArrayBuffer中。此外,利用Typed Arrays和Web Workers可以显著提升速度。
WASM优化解压缩
性能分析显示,加载Parquet文件时约三分之二的时间花费在Snappy解压缩上。为了解决这个问题,作者转向了WASM。一个关键的发现是,浏览器允许同步加载小于4KB的WASM Blob,将其作为Base64字符串内联。为了满足这个极小的体积限制,作者甚至重写了自定义的memcpy和C标准库函数。
Chrome DevTools是地球上每台计算机上都安装的世界上最好的调试工具之一,这太棒了。
通过将解压缩逻辑内联到JavaScript包中,可以完全避免为WASM模块进行额外的网络请求。这种方法带来了巨大的速度提升,数据越大,加速效果越明显,尽管增加了实现上的复杂性,但对于实现极速的首次数据时间是值得的。
构建高性能数据查看器
仅仅能够解析Parquet文件是不够的,还需要一个高效的查看器。尽管市面上有许多JavaScript网格实现,但为了获得完全的控制权,作者构建了自己的无依赖的虚拟化滚动React表格。这种设计允许根据Parquet的列式存储特性,异步加载需要的单元格,而不是等待整行数据加载完毕。
现场演示:Hyperparam 数据查看器
Hyperparam网站展示了这一成果,用户无需登录或付费即可立即使用。通过拖放一个远程URL指向的Parquet文件,数据几乎瞬间加载完成。这是一个虚拟化滚动表格,允许用户快速跳转到文件的任何部分,因为它仅读取索引并按需获取所需数据,而不是加载完整的400MB文件。
- 近乎即时的远程数据加载速度。
- 支持快速滚动和任意位置跳转。
- 通过高效的数据获取机制,使查看大型非结构化文本数据变得可行。
后续工作:浏览器中的Apache Iceberg
接下来的目标是将Apache Iceberg支持引入浏览器。Iceberg是一种基于Parquet文件栈的系统,用于在S3上构建可演进的数据库,可与Snowflake等服务竞争。由于已经实现了Parquet解析器,作者花费数周时间构建了一个可以读取和进行基本写入操作的Iceberg解析器,以支持数据集的迭代和清理工作。
论证更好的 JavaScript 数据工具
JavaScript社区需要更优秀的数据工程工具,并且前端设计必须从架构的初始阶段就成为核心要素。传统上,前端被视为次要公民,这必然导致用户体验性能低下和功能受限。用户真正关心的是界面体验,而不是后端如何实现,因此应优先考虑用户界面。
重新思考对后端的需要
如果能够规避架构上的妥协,那么构建无后端应用更为简单,基础设施成本更低,且无需处理前后端之间的协调问题。在无后端模型中,只需在一个地方实现功能(例如浏览表格或上传CSV),这使得开发速度更快,并能为用户构建更好的体验。
云原生数据格式的未来
云原生格式被认为是架构系统的绝佳方式。演讲者希望看到比Parquet和GeoTIFF更多的此类格式出现,因为它们代表了一种高效、面向未来的数据架构范式。
加入项目与最终想法
演讲者最后宣布其公司Hyperparam正在招聘从事此类重型JavaScript性能工作的人员。同时,他呼吁社区关注并为高Parquet(high-parquet)GitHub库点赞,目标是使其成为浏览器中最受欢迎的Parquet解析器,以推动JavaScript在数据性能领域的进步。
Questions
Common questions and answers from the video to help you understand the content better.
为什么Python不适合构建高性能的数据交互界面?
Python在UI构建方面能力较弱,并且是异步处理能力较弱的语言之一,不适合构建需要快速响应和高并发的现代浏览器应用。
什么是“首次数据时间”,它与传统前端指标有何不同?
“首次数据时间”衡量用户从打开网页到实际能够查看所需数据所需的时间长度,它关注的是数据可用性,而不是传统的首次内容绘制或首次交互时间。
如何利用云原生文件格式在浏览器中实现数据查询?
通过使用如Parquet等具有内置索引的云原生格式,浏览器可以仅使用HTTP Range Get请求来获取数据集中所需的小块数据,从而实现对大型文件的快速查询。
作者如何通过WASM实现Snappy解压缩的性能优化?
作者通过将C实现的Snappy解压缩编译成WASM,并利用浏览器同步加载小于4KB WASM Blob的特性,将其内联到JavaScript中,避免了额外的网络请求和内存拷贝。
为什么作者建议在构建数据工具时,前端不应被视为事后考虑?
因为用户体验直接取决于界面的性能和交互性;如果前端是事后添加的,通常会导致性能低下和功能受限,而将前端视为核心架构可以带来更快的开发和更好的用户体验。
Useful links
These links were generated based on the content of the video to help you deepen your knowledge about the topics discussed.
