TinyPilot:第 23 个月
一句话总结
历时八个月的改版终于完成了!
亮点
- TinyPilot 网站改版终于完成。
- 我学会了制作 Debian 软件包,竟意外地简单。
- 我已经放弃了 Vue 以及前端框架。
目标评分
每个月初,我都会定下当月想要完成的目标。以下是本月目标的完成情况:
发布一篇关于使用 TinyPilot 搭建家庭实验室 NAS 服务器的博文和视频
这是一年多来我发布的第一篇非回顾或年终总结类的博文。它在 reddit 上的反响平平,但在 Hacker News 上冲到了第 2 名。
这篇博文为 TinyPilot 网站带来了大量访客,使月独立访客达到 1.4 万,创下历史新高,比此前纪录高出 30%。我花了约 45 小时撰写博文和制作视频,这样的成果让投入的时间物有所值。
完成 TinyPilot 网站改版
- 结果:终于完成了!
- 评分:A
改版终于完成了。过去四个月里,我每个月都以为项目就要收尾了,但总有意外导致延期。现在,它正式完工了。
聘请营销机构或自由职业者
- 结果:6 月初聘请了一名自由职业者
- 评分:B
我找到一家看起来可能合适的机构,但总感觉不太放心。我们就一份为期三个月的合同谈妥了价格,可在我同意之后,他们又要求改成至少五个月。这是一个很大的危险信号。我继续尝试与他们协商,但他们的方案都让人觉得不靠谱,所以最终结束了洽谈。
幸运的是,我的电气工程合作公司推荐了一位数字营销自由职业者。从第一次通话起,他就比我接触过的其他人都更合适,于是我当场就聘用了他。
TinyPilot 数据
| 指标 | 2022 年 4 月 | 2022 年 5 月 | 变化 |
|---|---|---|---|
| 独立访客 | 5,268 | 14,296 | +9,028 (+171%) |
| 总页面浏览量 | 11,974 | 24,131 | +12,157 (+102%) |
| 销售收入 | $43,771.00 | $54,844.20 | +$11,073.20 (+25%) |
| 企业订阅 | $47.75 | $47.75 | 0 |
| 版税 | $2,253.61 | $3,269.56 | +$1,015.95 (+45%) |
| 总收入 | $46,072.36 | $58,161.51 | +$12,089.15 (+26%) |
| 利润 | -$19,392.76 | $6,445.38 | +$25,838.14 (+inf%) |
本月在访客和销量方面表现强劲。访客量几乎翻了三倍,销量增长了 25%。
大部分访客来自 Hacker News,不过似乎对销量影响不大。在文章登上 Hacker News 之前,销量就已经有望比 4 月增长约 25%。效果可能会有所滞后,因为 6 月初的开局异常强劲。
TinyPilot 网站改版
唉,说起这次改版。
该怎么说呢?
它已经拖了好几个月,而结束似乎永远就在几周之后。
在项目初期面试设计师和机构时,我说希望花 8千至1.5万美元、在几个月内完成改版。我明确表示,绝对不想花六个月和 4 万美元之后,才能看出改动是否对销量有实际影响。
结果,项目花了八个月,耗资 4.6 万美元。我恰恰掉进了自己想避免的陷阱。
我会就这次经历另写一篇更长的博文,但主要失误有:
- 范围过于宽泛:我本应控制好范围,先从品牌重塑做起,而不是让机构扩展成一次全面改版。
- 工时报告太慢:我本应坚持让机构实时向我报告计费工时,而不是延迟两周。如果看不到一项任务耗时多久,我就无法在发现超出预期时及时调整范围。
- 进度安排需要更透明:我本应要求对方就时间线进行更多沟通,这样就不会对项目拖延如此之久感到意外。
- 管理投入不足:我曾以为每月工作 40 小时的机构与每月工作 40 小时的个人自由职业者所需的管理成本大致相同。机构涉及更多人,而人越多就意味着需要更多管理。
不过,我们来看看成果。该项目对结账流程中的三个页面进行了重新设计:着陆页、产品页和购物车页面:


着陆页改版前后对比


产品页改版前后对比


购物车页面改版前后对比
抛开花费不谈,我对结果很满意。我认为新设计无疑比之前的好。新标志和图片让项目看起来更专业、更有辨识度。
新设计确实更好,但它真的值 4.6 万美元吗?
如果能回到过去,我肯定不会为改版投入这么多钱和时间。不过,它仍有可能收回成本。
除固定成本外,TinyPilot 销售收入的 70% 是利润。这意味着改版需要带来 6.6 万美元的额外销售额才能回本。如果它能让销量提升 10%,那么月均销售额就会从 5 万美元增至 5.5 万美元,大约一年就能回本。如果更好的营销能吸引更多客户访问网站,回本还会更快。
Debian 软件包其实很简单
我在 TinyPilot 上做的一个奇怪设计决策是其安装和更新机制。我们使用 Ansible 来实现,它是一款为运维工程师大规模部署系统而设计的工具。我曾用 Ansible 为我的 Raspberry Pi 部署首个 TinyPilot 原型。这个流程可行,所以我们就一直沿用了下来。
我知道在 Linux 上安装软件有更好的方案,但我没有相关经验。TinyPilot 在配置 Raspberry Pi 硬件功能方面有特殊需求,所以我很担心将标准安装工具适配到这些需求的过程。于是我们继续使用 Ansible,因为它运行正常,也没有造成什么问题。只是速度有点慢,本该几秒完成的安装要花两分钟,但还能接受。
两年过去了,我们已经把 Ansible 用到了极限。安装过程变得越来越复杂,更新甚至要花五分多钟。
我以前考虑过 Debian 软件包(例如 apt-get),但听说过关于 Debian 打包工具的负面评价。再加上还要涉及仓库服务器、密钥对和软件包签名流程?光是搭好基础似乎就要花很大功夫,真正做起来更是痛苦不堪。
作为一次尝试,我试着构建了一个 Debian 软件包,结果发现远比我担心的要容易。Debian 软件包不过是具有特定文件夹结构和几个特殊文件的压缩包。我大约花了一小时就做出了第一个可用的 .deb 文件。
至于仓库服务器和密钥对?结果发现它们是可选的。你完全可以直接分发 .deb 软件包文件,根本不需要仓库。
debhelper 这个创建 Debian 软件包的官方工具,确实如传闻中那样令人困惑和难用,但它并非必需。我们发现直接跳过 debhelper、手动生成 Debian 的元数据文件反而更容易。
更棒的是,我们不必一次性从 Ansible 惊险地切换到 Debian 软件包。我们可以按自己的节奏,逐步将逻辑从 Ansible 迁移到 Debian 软件包。
我们的第一个 Debian 软件包是为 Janus 制作的,这是一个开源的 WebRTC 服务器。过去我们需要在每台设备上从源码编译该应用,耗时约 30 分钟。而新的 Debian 软件包只需几秒即可安装完成。即使我们需要 32 位 ARM 二进制文件,也可以使用 Docker 的 QEMU 集成功能在 x64 云服务器上构建 Debian 软件包。我们用于编译和打包的所有代码都是开源的。
以下是我们在学习 Debian 软件包时觉得有用的资料:
搜索广告趋于平稳
上次计算时,Google 搜索广告看起来效果惊人。我在 Google Ads 上每花 1 美元就能赚取 0.69 美元的利润。但随着时间推移、数据增多,情况就没那么乐观了。
上个月统计时,我纳入了 4 月和 5 月第一周的数据。那第一周后来被证明是个异常值,所以按月细分后,利润就没那么高了:
| 指标 | 4 月 | 5 月 |
|---|---|---|
| 广告支出 | $804.12 | $4,283.71 |
| 展示次数 | 5,270 | 239,498 |
| 点击次数 | 351 | 3,327 |
| 点击率 (CTR) | 6.6% | 1.4% |
| 单次点击费用 (CPC) | $2.29 | $1.29 |
| 转化带来的收入 | $1,314.91 | $7,649.60 |
| 广告支出回报率 (ROAS) | 1.63 | 1.79 |
我的收入中约有 30% 用于硬件和人力成本,因此 ROAS 为 1.43 时大致盈亏平衡(1.43 - 30% = 1.0),高于此值即为盈利。5 月的 ROAS 为 1.79,意味着每花 1 美元广告费仍能赚 0.26 美元,所以我会继续投放。
TinyPilot 新聘的数字营销顾问审查了我的 Google Ads 账户,发现了几处我在低价值关键词上花费过多的地方,因此未来几个月我们很可能会改善这些数据。
业余项目
PicoShare
PicoShare 是我在 3 月发布的一款开源工具,用于分享那些因体积过大而无法通过电子邮件发送的文件。
5 月,我新增了上传后编辑文件元数据的功能:

5 月,我在 PicoShare 中新增了编辑文件元数据的支持。
最初,你只能在上传文件时添加备注并选择过期时间,且这些决定一旦做出就无法更改。现在,PicoShare 更加灵活,允许你随时更改文件的元数据和过期日期。
添加编辑界面后,我意识到这是让文件删除流程更防误操作的好机会。以前,在文件列表中点击删除按钮,文件就会直接消失——没有确认,也无法撤销。现在,删除文件需要先进入编辑界面,点击删除,然后再确认删除:

我添加了确认对话框以减少误删文件的情况。
WanderJest
2020 年初,我曾在开发 WanderJest,这是一个帮助人们查找附近现场喜剧演出的网站。由于疫情,我在 3 月暂停了该网站。随着生活逐渐恢复正常,我在周末和晚上又开始重新捣鼓 WanderJest。
在开发 PicoShare 的过程中,让我印象深刻的一点是,更简单的技术栈能多么显著地提升我的开发效率:
| PicoShare | WanderJest | |
|---|---|---|
| 后端 | Go | Go |
| 前端 | Go templates + HTML5 | Vue 2 |
| 数据存储 | SQLite + Litestream | Firestore |
Firestore 拖慢了我的进度,因为修改数据模式非常困难。我所知道的唯一方法就是编写自定义迁移代码并部署到生产服务器。而使用 SQLite,我只需下载生产数据库,编写一些 SQL 查询来摆弄它,然后再推送回服务器即可。
我现在正在重构 WanderJest,用 Go 模板替换 Vue,用 SQLite 替换 Firestore。


当前的基于 Vue 的 WanderJest 网站(左)与正在用 Go HTML 模板重构的新版 WanderJest(右)对比
用 Go 编写前端比我预期的要容易。前期的开发体验不如 Vue 那么好。我很想要条件渲染或响应式属性,而在原生 JS 中是得不到这些的。但总体而言,用 Go 渲染页面要简单得多。
使用 Vue 时,我在页面上渲染数据的流程是:
- 后端从数据存储中检索数据。
- 后端衍生出一份仅包含希望与前端共享属性的数据副本。
- 后端将数据序列化为 JSON。
- 前端从后端获取 JSON 数据。
- 前端根据从后端获取的数据填充页面元素。
相比之下,使用 Go 模板渲染页面只需两步:
- 后端从数据存储中检索数据。
- 后端用来自数据存储的数据填充页面模板。
当你在 Go 中渲染前端时,你可以省去所有关于后端向前端暴露哪些数据、如何序列化和反序列化、以及如何管理本地缓存的工作。
要等到功能与 Vue 版本持平后才能确定,但我认为有望将总代码行数减少约 50%。
收尾
完成了什么?
- 完成了 TinyPilot 网站改版。
- 发布了新的 TinyPilot 版本。
- 发布了一篇关于我的家庭实验室 NAS 服务器的新博文。
- 聘请了一名数字营销自由职业者。
经验教训
- Debian 软件包比想象中简单。
- 没有前端框架,生活更轻松。
下月目标
- 为安装 TinyPilot 创建一个自包含的 tarball。
- 完成关于 TinyPilot 网站改版的长篇博文初稿。
- 将付费搜索广告的 ROAS 提升至 2.0。
随机一篇博客