← 文章 / 编程开发
Hacker News 6小时前 · 2026-10-05 06:29:53 · 3 阅读

为什么开发者不愿优先使用平台原生功能?

多年来,Web 标准、性能和无障碍领域的倡导者一直在呼吁 Web 开发者“使用平台”。我自己也常常是其中的倡导者之一。

其逻辑很简单:既然浏览器能替你搞定,你为什么还要自己用 JavaScript 从头造轮子?无论你要实现什么功能,自己写的代码性能大概率不如浏览器自带功能,体验也会更差。

不过,我觉得也有必要站在另一面思考,至少可以借此理解那些“平台怀疑论者”开发者的立场。如果“使用平台”真的如此显而易见,为什么这么多人似乎仍需被说服?

最直观的原因是历史因素:在很长一段时间里,浏览器一直落后于其上层生态。像 jQuery 这样的库填补了浏览器实现相应 API 之前的关键空白。即便 API 已落地,你可能还得等待 IE6 这类落后浏览器被淘汰后才能放心使用。如今,大多数浏览器已是常青模式(Safari 有点争议,不过一年更新 7 次左右也算不错了),但直到 2020 年代初期,Web 开发者面对的仍是一个充满坑洼不平的 Web 环境。在那种环境下,自己封装方案是个合理的选择。

另一个原因是熟悉度:当你习惯了在 npm 上找 React 组件,遇到问题时往往下意识就去那里找,不管手头任务是否适合。如果你在 npm 搜索“sticky positioning”,你会发现没有哪个包会告诉你“傻瓜,直接用 CSS 的 position: sticky 就行了”。

很多时候,即便有了健壮的标准化基础,npm 上的库依然填补了框架易用性与底层平台之间的空白。我始终觉得耐人寻味:许多 React 开发者宁愿坚守 JSX 和 React 惯用法——原生 DOM API 让他们觉得“膈应”——却毫不犹豫地使用底层库,哪怕那些库里随处可见原生 DOM 操作。举个例子,虚拟列表库为了极致性能,可以大方使用原生 DOM API,同时暴露出更高级的抽象原语,让初学 React 的开发者也能轻松理解。从这个角度看,React 组件生态催生了一种自然的分工:经验更丰富的开发者将陌生的平台 API 封装成更熟悉的形态,交付给下游使用。 这种效应部分源于文档。许多 npm 包都配有精心编写的 README 或网站,提供示例、教程和截图。而在 MDN 成为 Web 文档首选目的地(web.dev 则是谷歌面向未来的补充)之前,Web 平台文档散落在各类博客、StackOverflow 以及像 CSS Tricks 这样的站点中。而这些网站往往只是建议你直接用 jQuery 或 GreenSock 这类知名库。
Screenshot of the Dragula website saying "drag and drop so simple it hurts" with a logo and stylized purple page versus the MDN page for the Drag and Drop API which looks much more subdued in comparison
Dragula 官网对比 Drag and Drop 的 MDN 页面。平心而论,前者看起来还是更有吸引力。

不过,如果只是第三方库和平台 API 之争,我认为还不足以完全解释开发者对“用平台能力”的抵触。懒得动手(好像我刚才已经说过一遍了?)、只想找个现成方案解决问题的开发者,其实并不在乎方案来自 npm、浏览器,还是从别人 GitHub Gist 里抄来的——他们只想把问题解决掉,然后继续干活。所以我还想探讨另一种反对“用平台能力”的来源。

对某一类开发者来说,自己造轮子就是更有意思。而且自己写的代码往往更容易理解和维护,尤其是当你对 Web 平台没有百科全书式的了解时。此外,自己动手做出来的东西还会产生一种“宜家效应”——你会更愿意去维护和折腾自己的代码。

举个例子,假设你想做一个模态对话框。你可能大致清楚它应该是什么效果:内容显示在屏幕上,背景仍然可见但被部分遮挡,也许点击对话框外部就能关闭它。于是你伸手就用了 position:absolute 和 z-index 来定位——啊,背景还在滚动,得禁用 body 上的 overflow……然后如果你懂一些无障碍知识,就会意识到还要处理 Esc 键关闭、实现焦点陷阱、把焦点还给打开对话框的那个元素,还有……

对许多开发者而言,我刚才描述的场景简直是一场噩梦(也是制造半残功能的好办法)。但对另一部分开发者来说,这听起来简直太好玩了!想想在动手搭建的过程中,你能学到多少东西。再想想你可以怎样加入自己的风格:加个动画、换个主题、加一个可选的关闭按钮……不知不觉间,你就攒下了一个足以上架 npm 的库。这比直接拿来 <dialog> 用就收工要有趣得多——后者实在太无聊了。

对很多人来说,在 <dialog> 这类 API 出现之前,我们就是这样学 Web 平台的!如今许多鼓吹「直接用平台能力」的人,自己以前也写过 polyfill、shim 和库。我知道这一点,因为我自己就是其中之一。在开发 PouchDB 期间,我花了多年时间做 IndexedDB、WebSQL 和其他浏览器存储 API 的工具开发,这段经历让我足够自信,敢于坐在 W3C 标准会议的表格里,甚至直接给 IndexedDB 规范提 issue 和拉 PR。如果没有平台缺口这种外部压力逼我去填补,我不确定自己是否会有兴趣或动力去积累到那样的专业深度。

当然,自己动手未必总是好事。有时候,纯粹是因为无知。特别是在 Web 平台上,我猜 JavaScript 方案泛滥、把本可用 CSS 解决的难题也硬拿 JS 来写,其中一个原因就是:很多开发者压根没花时间去深入理解 CSS 是怎么工作的。

说实话,CSS 在过往确实难懂,这也是这个网站叫“CSS Tricks”的原因。像 清除浮动、float 布局 以及 min-width: 0 技巧 这些特性,一点都不直观。与其费尽心思去理解 CSS 的内部算法,不如直接想象你想要的命令式逻辑,然后用 JavaScript 把它表达出来,这样往往简单得多。更何况,多年来 CSS 一直没有提供直接的方式来表达一些常见需求,比如 文本行截断、textarea 自适应调整、隐藏滚动条 等。所以开发者自然会使用他们更熟悉的工具来自行实现这些功能。

我甚至觉得这种“回避平台”的现象并不局限于 Web 领域。它适用于任何在不完全理解的平台上进行开发的场景。比如,在我负责的工作中,我们用 ClickHouse 来存储各类分析数据。有一次,我同事和我就如何在一个列中存储大型 JSON 数据产生了分歧:他设计了一套系统在存储前进行压缩,而我把数据放到一个独立的键值存储中,只在 ClickHouse 里插入对应的键。结果证明,我们俩都错了!ClickHouse 本身就会自动压缩数据,而且作为一个列式数据库,如果直接把数据交给 ClickHouse 处理,反而能在跨行数据上获得更好的压缩效果。至于那个独立的键值存储,只不过是列式 SELECT 已经能实现的功能的简陋替代品罢了。

这些道理,我是真正花了时间通读 ClickHouse 文档、又写了个基准测试验证猜想之后才意识到的。最后我震惊地发现,我们造出来的东西又慢又笨重,还不如平台自带的功能。这和 JavaScript 与 web 平台的故事惊人地相似,让人无法忽视。

我相信,如果你是 iOS 或 Android 开发者,或者在做游戏引擎上的开发,实际上只要是在某个平台层之上做开发的程序员,多半都有类似的经历。为什么那些满头白发的资深工程师总有一个经典形象:能把初级工程师写得盘根错节的代码,换成一行搞定?这正是原因所在。学得越多,你就越能凭借对整个系统端到端运作方式的理解,做出最小的改动来实现同样的功能(长期来看也减轻了维护负担)。

这篇文章我一直非常努力地想避开 AI 的话题(过去一年已经聊烂了),但还是忍不住想:AI 编程会给这种现象带来什么影响?我有乐观和悲观两种看法:

  • 乐观:LLM 对你所用的平台知识渊博,能精准选对平台 API,用一句模糊的英文需求就实现想要的效果。而且这种方案大概率比用户态代码更快更正确,agent 经过严格的测试和基准比较后会倾向选它。此外,当开发者不再亲手写代码时,“宜家效应”也就消失了。
  • 悲观:LLM 似乎天生爱重复造轮子——比如无视已有的辅助函数,偏要自己再写一遍一模一样的——自定义的、不合平台习惯的代码量会暴增。开发者不会让 agent 做足够的测试、尝试足够多的替代方案,而是直接提交第一版草稿。既然永远可以继续加本轮,agent 就会不断迭代那些本不该存在的过度工程方案。

在我使用 AI 编码工具的过程中,这两种现象我都见过。我希望随着模型和编码工具包变得更强,未来的趋势会朝着乐观的方向发展,但我无法保证。

无论如何,这是我关于“使用平台”这一理念的一些冗长且略显矛盾的思考。作为一句箴言,我很爱它,因为它能简洁地表达出一种感受:当你面对一堆繁琐冗长的“意大利面”式代码时,你会感叹如果作者能更懂底层架构,代码会多么优美优雅。但我也曾就是那个作者,我也享受过构建那些看似杂乱实则精妙代码的快乐(至少对我来说是精妙的),所以我认为有必要理解这些开发者的出发点。正因如此,我相信只要平台还在,我们就会不断听到“使用平台”的呼声。

你可以在 fediverse 或 Lobsters 上发表评论。

原始来源: Hacker News

评论 (0)