
不要自己造轮子:一位老程序员的 Web 设计吐槽
当每个网站都重新发明浏览器已经做好的功能——自定义滚动条、密码输入框、日期选择器——最终受苦的是用户。这篇文章来自 Hacker News 热帖,引发无数共鸣。
原文来源:Susam Pal - "Don't Roll Your Own" — 在密码学的世界里有一个著名原则:不要自己实现加密算法。但在 Web 开发的世界里,无数网站正在"重新发明"浏览器已经做得很好的功能——而且通常做得更差。
密码学的教训
在加密领域,有一条被反复验证的原则:不要自己实现加密算法。
这并不是说没有人可以写加密代码。但意思是说,对于生产环境中保护用户敏感数据的软件,你不应该依赖一个未经社区审查的私有实现。你应该使用经过验证的、被广泛使用的加密库。
好消息是,这已经成为行业标准做法。二十年前不是这样的——我见过不少有问题的自实现 RC4 代码,初始化向量不对、密钥流可预测、明文泄露到密文中。但现在,主流电商网站和银行都不会用自制的加密算法。
为什么 Web 设计也需要类似原则
Web 设计当然不是加密。一个坏的滚动条不会像坏的加密算法那样泄露你的银行密码。但我真心希望 Web 设计也有类似的原则。
有很多方面,开发者真的不应该自己造轮子——尤其是当浏览器已经做得很好的时候。
当然,有时候你确实需要自定义实现。但我想聚焦在那些不应该自己造轮子的场景,以及为什么这样做会让用户体验变差。
自定义滚动行为
在所有问题中,最让我烦躁的是网站的自定义滚动效果。我已经习惯了页面的滚动方式——鼠标滚轮、触摸板、键盘上下键——这些在浏览器里都工作得完美无缺。
当你用自己实现的方式覆盖浏览器的默认滚动行为,页面就"坏"了。页面滚动太快或者太慢。键盘滚动可能不工作或者工作得怪怪的。你把我早已熟悉到不需要想的东西,变成了一个我必须费心去适应的东西。
我见过一些网站的自定义滚动,在 Mac 上还算流畅,但在 Windows 或者 Linux 上就是灾难。有的滚动效果在触控板上完全失灵。有的为了"平滑滚动"的视觉效果,让翻页变得迟钝。
最讽刺的是:很多现代浏览器本身已经有平滑滚动功能了。你只需要一个 CSS 属性 scroll-behavior: smooth; 就能获得原生、高性能的平滑滚动效果。为什么还要写几百行 JavaScript 来重新实现?
自定义链接导航
浏览器处理链接的能力,可以说是它存在的全部意义。跟踪链接是浏览器的核心功能。你根本不应该干涉这个行为。
如果你觉得你需要干涉,先想想你想达到的目的是什么,值不值得破坏正常的链接导航。
在这方面,GitHub 是我见过最糟糕的典型案例。当你点击 GitHub 上的一个链接——文件链接、Issue 链接——它会触发一大坨 JavaScript 代码来处理这次导航。
我不确定是不是只有我注意到:GitHub 上点击链接有时候加载时间特别长。讽刺的是,很多时候右键→在新标签页中打开比直接点击还要快——因为新标签页打开的是直接 URL,绕过了 GitHub 那套 JS 导航逻辑。
实际上,这就是在说:你们公司的单页应用(SPA)路由实现,大概率不如浏览器原生的链接导航快。
自定义密码输入框
谢天谢地,这种问题这些年变少了。浏览器自带的密码输入框功能相当完善:
- 自动提示保存密码
- 自动填充已保存的密码
- 生成强密码
- 在不安全的 HTTP 连接上发出警告
- 与密码管理器协同工作
- 与手机键盘配合
- 与无障碍工具配合
当你用一个自制的假密码框替换浏览器自带的密码字段,你很可能破坏了上面所有这些功能。
更糟糕的是,很多自定义密码框用的是普通的文本输入框,然后把字符显示成圆点。在这种情况下,浏览器、操作系统、辅助工具都把它当成普通可见文本处理——也就是说,密码可能会以你完全意想不到的方式暴露出去。
自定义日期选择器
我知道 <input type="date"> 不支持选择日期范围。但这没关系。你可以提供两个日期输入框,一个开始日期,一个结束日期。我愿意接受这种小小的不便,只要我能在同一个浏览器里用同一种方式选择日期。
但我不愿意的是,在十个不同的网站上,学习十种不同的日期选择器用法。
现在的日期选择器实现真是五花八门:
- 有些要你从月份视图"缩放到"年份视图才能选年份
- 选了年份后,又不能直接改月份了——得回到月份视图
- 有些让你必须点"上一年"按钮整整四十次,才能选到出生年份(如果你年纪稍大的话)
- 有些根本不让你直接输入日期
不。我不想学习你的日历控件。我只想用我的浏览器自带的日期选择器,它的设计很合理——比你那个自定义实现合理多了。
如果你的目标浏览器不支持原生日期选择,可以在原生日期选择器旁边补充一个自定义控件,而不是替换掉它。
自定义表单控件的通用问题
基本上,不要乱动表单控件。
它们几乎总是在解决一些问题的同时引入新的问题——通常引入的问题比解决的还多。
而且,在你折腾控件的同时,别每隔几个月就重新设计一次网站界面!我可以适应新设计,但我的上了年纪的亲戚们不行。对他们来说,每一次界面改版,就相当于重新学一个工具。
如果每个网站都每隔几个月搞一次大改版,他们就得花大量的时间重新学习那些熟悉的东西——而且没有任何功能上的收益。
想象一下,如果有一天你发现你的 Linux 发行版把所有核心命令和参数都改了。或者你每天早上起床,发现洗衣机的按钮位置全换了。这不可爱。
那么什么时候应该自己造轮子?
当然,也有很多合理的自造轮子的场景。比如:
- 你正在做一个全新的交互范式,浏览器没有原生支持
- 你的应用程序有特殊的无障碍需求,原生控件无法满足
- 你需要支持的目标平台限制(比如某些浏览器不支持
<input type="date">) - 你是做 UI 组件库的,你的职责就是提供这些自定义控件
关键是:在你决定自定义一个浏览器已经有的功能之前,先确认你真的需要这么做。
一点来自用户的恳求
我不是什么用户体验专家。所有这些只是我作为一个普通 Web 用户的真实感受。有些网站确实需要用自定义控件来提供更好的体验——但我见过的大部分情况,都是在破坏一个本来很好的体验。
下次你在 Sprint 计划里看到"优化滚动效果"或者"重新设计日期选择器"的时候——先问一句:我们做的这个,真的比浏览器自带的更好吗?
大概率不是。
© 2026 四月 · CC BY-NC-SA 4.0
原文链接:https://aprilzz.com/ramble/dont-roll-your-own