上周,我从 Jovian 的代码库中删除了 50,000 多行代码。所有被删除的代码之前都是在生产环境中运行的,这些代码支撑着 Web 应用程序每日处理十万个用户请求。
这一次删除的代码约占我们前端代码库的 70%,它们主要是用 Java、React 和 Next.js 编写的。
令人惊喜的是,我能够在不破坏应用程序的前提下,用短短三天删除超过三分之二的代码。同时,这个过程中几乎没有丢失任何主功能,让应用程序更轻且更易于使用,以及代码库也变得简单易读。
自 2019 年以来,我们一直在致力于构建 Jovian ,该平台也经历了各个演变阶段。随着公司规模的扩大,我们不断添加新功能、页面、按钮和设置,但我们很少考虑删除某些内容(谁会这样做?),我们有意识地努力保持应用程序简单易用,但它仍然积累了大量“功能债”。
我曾在某个地方读到过一句话——典型软件应用程序中超过 80% 的功能几乎从未被使用过。我也在某个地方看到过一个截图,显示了微软 Word 中可用的所有工具:
话说 Jovian 的情况并没有这么糟糕,但拥有复杂的应用程序和庞大的代码库确实使得更改、升级库和添加可能真正重要的新功能变得困难。
起初,我只是想要重写网站
几周前,我起初的想法是对 Web 应用程序进行尝试性重写,相当于推翻之后重头来过。不过,这款 Web 应用程序采用了最新版本的 Next.js 构建,并部署到 Cloudflare Pages。
我很快意识到从头开始全面重写是行不通的。因为重写整个应用程序不仅需要几个月的时间,而且几乎肯定会充满数百个错误。
全面重构 Web 应用程序几乎永远不会成功。即使我们这样做了,所花费的时间也比计划的要长得多。之前我在 Twitter 工作时亲身经历了这一点,在那里我花了几个月的时间将代码从 Ruby on Rails 迁移到 Scala。
然后,我又开始考虑使用渐进式迁移的方法。在这个过程中,也出现了一系列的挑战。举个例子,我创建的新页面在结构和内容上都非常简单,而我们应用程序中的现有页面包含了多个交互式选项卡、按钮和小部件。我们现有的 Web 应用程序使用由 Python 后端提供服务的 REST API,而我想利用服务器操作直接从 Next.js 与我们的数据库进行交互,以使应用程序更快,同时消除托管后端的成本。这需要将数百个包含数万行业务逻辑的 API 端点从 Python 迁移到 Java,而我并不期待这样做。
一时之间,似乎已经没有办法摆脱这种僵局了。该应用程序及其代码库看起来就像一头巨大的大象,只能缓慢、小步前进,而且根本不愿意移动。
每次在 VS Code 中打开代码库时,我都会遇到很大的阻力,因为涉及的工作量实在是太多了。
给 Web应用程序“减肥”
然后,几天前,我突然意识到,通过“减肥”我可以走得更快。
我可以从屏幕上删除不必要的小部件和按钮,将其迁移到新堆栈(幸运的是,Next.js 支持渐进式迁移),然后再添加回删除的元素。
接下来的事情,只能用“屠杀”来形容:
我并没有打算删除三分之二的代码库。我想删除足以开始迁移一个模块的内容。
于是,我在 Google Analytics 中查找了过去 30 天内每个模块的页面访问量,以确定从哪里开始。
虽然我知道某些页面的访问频率低于其他页面,但我惊讶地发现有些模块占页面访问量的比例不到 0.1%。这意味着我可以完全删除它们,而不会影响 99.9% 的用户。我可以删除包含数十个文件和数千行代码的整个目录。
当我从应用程序的其余部分中删除很少使用的模块及其入口点时,慢慢地发现应用程序变得越来越简单,选项卡、页面和菜单项越来越少。删除未使用的代码也感觉很好。
随着代码库变小,我对迁移所经历的阻力和焦虑也开始减少。最初我对删除我们花了几周或几个月构建的模块感到难过,但我知道我总能从 Git 历史记录中取回我将来需要的任何内容。
删除很少使用的整个模块后,我继续删除占流量不到 0.5% 的各个屏幕和弹出窗口。我再次惊讶地发现可以删除数百个文件而不影响 99.5% 的用户。事实上,这对他们产生了很好的影响。五个选项卡变成了三个,然后是两个,然后是一个,此时,选项卡可以从页面中完全删除。现在许多页面都有更简单的结构和单一的主要操作。更少的 API 调用导致更快的页面加载和屏幕转换。感觉棒极了!
删除所有不必要的模块和页面后,我开始在 Google Analytics 中进一步挖掘,以确定剩余页面上的功能的使用频率。
我发现了一些很少使用的功能、几乎从未点击过的按钮以及从未见过的菜单项。所以,我开始删除它们。我拿走的越多,我就越喜欢剩下的。我删除了几个侧边栏、下拉菜单、按钮、小部件、弹出窗口以及支持它们所需的内部应用程序状态和条件逻辑。这也使得代码更容易理解,这应该会进一步简化迁移。最初看似需要几个月的努力,现在感觉就像我可以在几周内完成的事情。
总结
沉没成本谬误和损失厌恶是人类的偏见,使我们很难放弃不再需要的东西。
我仍然担心我可能拿走了太多或删除了一些重要的东西,但分析表明事实并非如此。正如今天访问该网站的用户数量与清理之前一样,他们可以(并且正在做)几乎他们之前所做的所有事情。新用户无疑会发现该平台更易于导航且更易于使用。
我有多少其他应用程序可能会受益于每隔几年删除 70% 的代码。它将降低维护开销,使他们能够更快地移动,减少加载时间,并运送更小的软件包,同时改善用户体验并改进他们的软件。
“完美的实现不是在没有什么可以添加的时候,而是在没有什么可以删除的时候”——Antoine de Saint-Exupery
作者:手扶拖拉斯基