极简主义开发实践:我做了一个每天只有一道题的Web应用
一、缘起:为什么做这样一个“反商业化”的项目?
作为一名Web开发者,我平时喜欢用一些脑力小游戏来给自己“热身”。但市面上的解谜App和网站让我越来越不耐烦——它们总是充满了社交排名、弹窗广告、无尽的体力值、每日签到……这些设计本质上只有一个目的:抢占你的时间。
于是我做了一个决定:做一个“反商业化”的网站——Minute Cryptic。它的核心逻辑极其克制:每天只发布一道英文逻辑解谜题(Cryptic Clue)。全站没有广告、没有弹窗,甚至不需要注册登录。你打开网页,动脑,关掉网页,仅此而已。
今天这篇文章,我想从技术角度复盘这个项目的架构设计、核心功能实现以及我在“做减法”过程中的一些思考。希望对同样在探索独立开发的朋友有所启发。
二、产品约束即设计语言
在动手写代码之前,我先给自己定下了一套“约束条件”。这些约束最终塑造了整个项目的技术选型:
- 每天一道题:不需要内容管理系统,不需要复杂的数据库查询
- 零用户系统:不注册、不登录、不追踪——这意味着没有用户表、没有认证模块
- 3级递进式提示:帮助用户但不直接给答案——需要一套轻量级的状态管理
- 视频兜底讲解:每道题配有视频链接,实在解不出可以看复盘
这些约束看似是功能的“缺失”,实际上帮我砍掉了80%的复杂性。后面你会发现,整个项目没有用到数据库,没有用到用户系统,甚至没有用到前端框架。
三、前端:原生三件套足够了
3.1 技术选型的“减法”
网站前端采用了纯粹的 HTML + CSS + Vanilla JS,没有使用任何框架。
很多朋友问我为什么不直接用 React 或 Vue。说实话,这个项目一开始我确实考虑过框架方案,但仔细分析了需求之后发现:
- 页面只有一个核心交互:输入答案、查看提示、观看视频
- 没有复杂的组件嵌套,没有多页面路由
- 不需要虚拟DOM的性能优化,因为DOM节点本身就很少
- 整个首屏资源大小控制在几十KB以内
在这个场景下,框架带来的收益几乎为零,反而增加了打包体积和构建复杂度。在确定框架能带来明确收益之前,先用原生方案——这是我这个项目最大的技术心得。
3.2 DOM交互的核心逻辑
谜题页面的核心交互其实是一个简单的状态机:
const PuzzleState = {
INITIAL: 'initial', // 展示谜面,等待输入
WRONG: 'wrong', // 答案错误,给出轻微提示
HINT_1: 'hint_1', // 展示一级提示
HINT_2: 'hint_2', // 展示二级提示
HINT_3: 'hint_3', // 展示三级提示
SOLVED: 'solved', // 答案正确,展示视频链接
};
整个页面的渲染逻辑就是根据当前状态,动态显示或隐藏对应的提示区域。没有用到任何状态管理库,纯粹靠事件驱动 + DOM操作完成。
四、数据层:Markdown驱动的极简架构
4.1 为什么不用数据库?
这是我做这个项目时反复思考过的一个问题。传统思路是建一张puzzles表,包含谜面、提示、答案、发布日期等字段,然后通过RESTful API查询。
但我问了自己一个问题:“这个项目的数据量有多大?”
每天一条记录,一年才365条。这个数据量用文件系统完全够用,而且不需要维护数据库实例,不需要处理连接池,不需要担心数据迁移。
最终我选择了用 YAML格式的数据文件来管理每日谜题:
# 2026-05-27.yml
date: 2026-05-27
clue: "Right following tear, it's a waterway (5)"
author: "Minute Cryptic"
hint1: "The definition part is 'it's a waterway'"
hint2: "First letter: R"
hint3: "This is a charade clue - combine two parts"
videoUrl: "https://www.youtube.com/watch?v=xxx"
answer: "RIVER"
4.2 文件驱动的API设计
后端是一个轻量级的Node.js API服务,核心逻辑非常简单:
- 根据当前日期拼接文件路径:
/data/puzzles/2026-05-27.yml - 使用
js-yaml库读取并解析文件 - 将解析后的JSON返回给前端
- 前端收到数据后渲染谜题页面
这种设计的优势非常明显:
- 零依赖数据库:不需要MySQL、PostgreSQL或MongoDB,运维成本极低
- 数据即代码:谜题文件可以用Git进行版本管理,方便协作和回滚
- 部署简单:整个应用打包后可以直接部署到任何支持Node.js的VPS,甚至可以用静态导出
五、无状态的用户追踪:localStorage就够了
5.1 为什么不需要用户表?
大多数Web应用的核心复杂度其实不在业务逻辑,而在用户系统——注册、登录、认证、权限、会话管理……一整套基础设施搭建起来,项目复杂度直接翻倍。
Minute Cryptic的产品逻辑完全不需要知道“你是谁”,只需要知道“你在这个页面做了什么”。用户猜到了第几步提示?这个状态直接存在浏览器的localStorage里就足够了:
const hintState = {
puzzleDate: '2026-05-27',
currentHintLevel: 2,
hasSolved: false,
};
localStorage.setItem('minute_cryptic_state', JSON.stringify(hintState));
第二天用户再次访问时,前端读取localStorage中的状态,自动恢复到上次的进度。整个逻辑在前端完成,后端完全不需要参与。
5.2 设计考量
这种方案有几个好处:
- 隐私友好:用户数据完全留在本地,不需要后端存储任何个人信息
- 零后端成本:不需要维护用户表、不需要处理认证Token
- 离线可用:如果配合Service Worker,甚至可以做到离线解谜
当然它也有局限性——用户换了浏览器或设备,状态就丢失了。但考虑到Minute Cryptic的定位是“每天5分钟的脑力热身”,这个取舍是值得的。
六、提示系统的渐进式设计:这个功能让我花了最多时间
6.1 设计思路
这是整个项目中最值得分享的功能设计。直接显示答案是最简单的做法,但那会毁掉解谜的所有乐趣。我的目标是设计一个 “教学式引导”——像导师一样逐级给线索,让用户自己“啊哈”顿悟。
最终我设计了4级递进规则:
| 提示等级 | 展示内容 | 设计意图 |
|---|---|---|
| 一级提示 | 高亮谜面中“定义”的部分 | 告诉用户这道题的突破口在哪 |
| 二级提示 | 给出首字母 | 提供最直接的线索 |
| 三级提示 | 告知谜题类型(字谜/双关/藏词) | 缩小推理范围 |
| 兜底方案 | 视频讲解链接 | 完整复盘整个推理过程 |
6.2 前端实现
用户每次点击“获取提示”按钮,前端会判断当前hintLevel,然后从API返回的谜题数据中读取对应等级的提示内容,动态渲染到页面上。同时更新localStorage中的状态。
function showNextHint() {
const state = getHintState();
if (state.currentHintLevel >= 3) {
showVideoLink();
return;
}
state.currentHintLevel++;
const hintText = puzzleData.hints[state.currentHintLevel - 1];
renderHint(hintText);
saveHintState(state);
}
6.3 实际效果与用户反馈
这个功能上线后,用户的反馈让我很意外——很多人说这是他们“坚持下来”的原因。传统的解谜App中,卡住 = 挫败 = 流失。但通过渐进式提示,用户即使解不出题,也能在引导中学到解谜技巧。很多用户说,他们从“每道题都需要看提示”逐渐进阶到“大部分题能独立解出”——这种可以感知到的进步本身,就是最好的用户留存机制。
七、部署与性能优化
7.1 部署方案
项目部署在一台基础配置的VPS上,使用Nginx做反向代理,Node.js进程通过PM2管理。由于没有数据库依赖,整个部署流程非常简单:
git pull拉取最新代码npm install安装依赖pm2 restart app重启服务
每次添加新谜题只需要在/data/puzzles/目录下新增一个YAML文件,不需要任何数据库操作。
7.2 性能优化
因为本身就很轻量,性能优化主要集中在几个方面:
- 静态资源缓存:CSS和JS文件设置长期缓存策略
- Gzip压缩:Nginx开启Gzip,HTML传输体积减小70%以上
- CDN加速:视频文件托管在YouTube,不占用服务器带宽
整个站点首屏加载时间控制在500ms以内(国内网络环境),PageSpeed Insights评分保持在95分以上。
八、开发过程中的经验总结
8.1 值得坚持的决策
- 不用框架是对的:对于一个功能聚焦的小项目,原生方案完全够用,而且省去了框架升级、依赖管理等隐性成本。
- 文件系统替代数据库是正确的:数据量小的场景下,文件系统远比数据库简单可靠。
- localStorage管理状态是合适的:无用户系统的产品完全可以跑通,隐私友好且运维简单。
8.2 如果重新做,我会改进的地方
- 题型扩展的灵活性:目前只支持一种谜题类型(Cryptic Clue),如果要扩展新题型,当前的数据结构需要重构。应该在设计初期就考虑多题型的兼容。
- 国际化支持:网站目前只有英文,但已经有非英语国家的用户在玩。如果做i18n,前端渲染逻辑需要重新设计。
- 离线能力:如果配合Service Worker做PWA,可以让用户在无网络环境下也能玩历史题目。
8.3 给独立开发者的建议
在AI盛行的时代,我们总想着用代码去取代人类思考。但做这个网站让我发现,为真实的人类设计一个纯粹的脑力游戏,反而是最有趣的事情。
写在最后
这个项目上线后没有花过一分钱推广,全靠喜欢解谜的用户自发传播。目前在全球已经有约18万日活用户,被新西兰国家电台专题报道,甚至还出了一本实体书。
欢迎各位同行来体验:Minute Cryptic。如果你对技术实现有任何疑问,或者有自己的极简开发经验想分享,欢迎在评论区交流。

浙公网安备 33010602011771号