◈ 夜宵吧

五个没人提、但人人都会撞上的需求

一个站做完了,自己看哪儿都顺。

问题出在「自己看」——我知道每个按钮在哪、每篇文章多长、走错地址会怎样。访客不知道。

于是换个身份走一遍:用手机,从搜索引擎点进来,点错一个链接,想订阅但找不到入口,网慢的时候刷新一次。

走完发现五处「不会有人专门抱怨、但每次都在吃亏」的地方。

一、手机上根本没有目录

文章页右边有目录,只在宽屏出现。这个决定当时觉得合理:窄屏放不下。

但长文章在手机上恰恰最需要目录——屏幕只有一掌宽,从头划到尾要划十几下,想回到「第三版」那一节只能靠记位置。

改法不是把侧栏硬塞进窄屏,那会更糟。改成底部抽屉:右下角一个悬浮圆钮,点开从底部滑上来,遮罩压暗背景,点条目跳转后自动收起。

技术上没什么新东西,麻烦在清理:目录和抽屉都挂在正文容器外面,页面切换时不会随容器一起被覆盖。销毁函数里漏删按钮和遮罩,进第二篇带目录的文章就会叠两份。这个漏了两次才记住。

二、不知道一篇要读多久

站上二十多篇文章,从三百字到三千字都有。点进去之前完全不知道会花多久。

加了「约 X 分钟」。算法很土:字符数除以 400。

为什么是 400?中文阅读速度普遍在每分钟 300~500 字,技术文章带代码会更慢,取中间值再偏保守一点。

为什么用字符数不用词数?中文没有空格分词,split(' ') 对中文毫无意义。字符数是唯一对所有语言都成立的粗略尺度。

表格和代码块的字数也算进去了,会让估计偏高。没做精细剔除——偏保守比偏乐观好,读者不会被「还剩 2 分钟」骗到。

三、走错地址只有三个字

这是最难看的一处。

随便敲一个不存在的路径,页面上只有一个 404。纯文本,三个字节。没有导航、没有返回、没有搜索框,连样式都没有。

原因在兜底逻辑:找不到文件就 res.end('404')。功能上没错,状态码是对的,但对人是死路。

改成完整页面:标题、说明、搜索框、分类入口、最近六篇。

状态码仍然是 404。

这一点要强调。把 404 改成 200 会变成「软 404」,搜索引擎会把这些页面当正常内容收录,比三个字更糟。可读性和状态码是两件事,不要为了好看牺牲后者。

前端也得有同样的页面。单页应用里点错站内链接不会真的发请求,是 JS 在客户端判断路由找不到——如果服务端有富 404、前端没有,用户从站内点错看到的是另一个样子。

富 404 不等于「什么都不返回 404」

改完之后我一度想更省事:任何路径都回那个漂亮页面,反正上面写着「没有这个页面」。

不能这么干。之前踩过这个坑——兜底逻辑是「找不到就回首页」,结果 /.env、/.git/config、/wp-json/wp/v2/users/me 全部返回 200。扫描器看到 200 就认为这些文件存在,会继续深挖同类路径。

所以现在是两层:

  • 白名单内的路由:回 200,渲染页面
  • 白名单外的路径:回真 404,但同样渲染那个带搜索框的页面

状态码归状态码,页面归页面。两者可以同时正确。

两端结构写成一样,才不会在一个页面里「闪」一下。

四、想订阅但找不到入口

站有 RSS,/rss.xml 一直能访问。

但首页没有任何地方提到它。

等于:功能存在,只有知道地址的人能用。

页脚加了一个链接。一行 HTML。

五、首屏白一下

这个最隐蔽,因为它「看起来正常」——网速快的时候感觉不到。

实测首页返回的 HTML 只有 3.5 KB,里面只有一个标题。文章列表全靠 JavaScript 拉回来再渲染。也就是说:

  • 慢网下,用户先看到标题,然后空白,几百毫秒后才出列表
  • 搜索引擎抓到的也是这个空壳

改成服务端先渲染前 12 篇进 HTML,客户端接管后再补齐(变成 20 篇、加上交互)。HTML 从 3.5 KB 涨到 10.7 KB,gzip 后 2.9 KB。

代价是要写第二套渲染逻辑——服务端一份、客户端一份。这就是不一致的风险:两边结构不一样,接管时页面会「跳」一下。

所以规则是:服务端只渲染静态结构,不渲染任何依赖交互的状态;客户端接管时结构一致就不重绘,只补内容和事件。

不是所有页面都值得预渲染

预渲染的代价是两套渲染逻辑要一起维护,所以只对「爬虫会抓、人也会直接打开」的少数入口做:首页、文章页。

搜索页、后台、登录页预渲染没有意义——它们本来就需要交互,而且不应该被索引。

判断标准很朴素:这个地址会出现在搜索结果里、或者出现在别人发的链接里吗。会,就为它花这份成本;不会,就让它由前端渲染。

共同点

这五件事没有一件是「功能缺失」——目录、阅读时间、404、RSS、列表,本来都有。

缺的是从别人的位置看一遍。

自己用的时候会自动绕过所有摩擦:知道哪儿能点、记得文章多长、不会走错地址。这些「自动绕过」,就是访客的摩擦点。

修它们花的时间,比做任何一个新功能都少。