《「时间裂隙」问题》存档

本贴是《「时间裂隙」问题》一文的存档。其中,「时间裂隙」也常使用以下的词汇来描述:

  • 时间裂隙
  • 时空裂隙
  • 时间夹缝
5 个赞

一、诞生

2015 年左右,前端人发明并推行了一种新的技术,叫「PWA」。PWA 中的 Web Worker 技术是一大亮点,这项技术实现了很多功能,其中一项是「托管网络请求」。这个功能可以接管所有的网络请求,不管处在何种状态。例如,在浏览器离线的情况下,使用缓存填充请求,给用户仍然显示出页面来。

下面是一个基于 PWA 技术的计算器,它的所有程序文件只需要加载一次,并且断网也能使用:

3 个赞

二、使用

这真的非常棒。尤其是上面提到的「断网也能用」功能,我觉得首先 Koishi 文档这样的静态文档站就应该上这样的技术吧。这类文档站的普遍特点是,站点基本就是由静态内容(一堆字和一堆图)组成的,这样离线状态下只需要从缓存中加载这些内容就可以了。

VuePress 当然也是这么想的。他们推出了官方的 @vuepress/plugin-pwa 插件,实现了上面的逻辑。文档站不需要自己再手动实现这些逻辑。

5 个赞

三、实现

PWA 的实现也非常简单。两句话:

  1. PWA 插件会在服务器生成一个「最新版本」文件,这个文件存放了当前站点的最新版本的状态。每次打开网站时,本地的 PWA 程序去请求这个文件。这个文件更新了,就下载一下,把本地的换成新的版本;没更新就啥也不用下载了,节省了大批服务器的出口流量。
  2. 那要是浏览器里的 PWA 程序没下载到这个文件,就说明用户现在处于断网状态,那我就直接拿本地缓存的文件给你看,这样你断网也能看 Koishi 文档了

总结一下:我觉得 PWA 是天才发明,就干上面这两件事,就保证了:

  • 用户永远能看最新文档,而且重复内容不会重新下载,节省出口流量
  • 用户断网状态下照样能看我们的文档
5 个赞

四、三年以后

就这样,三年过去了。

三年之后,VuePress 已经逐渐退出舞台了,现在主流的文档框架是 VitePress。我们把 Koishi 文档迁移到了 VitePress。

神奇的事情发生了!

  • 用户浏览器里的 PWA 程序,没有下载到 VuePress 生成的「最新版本」文件
  • PWA:「那就说明用户现在处于断网状态,那我就直接拿本地的文件给你看」
  • 于是,用户看到了 PWA 呈现的,本地的,旧版的文档。
3 个赞

五、解决

怎么解决这个问题呢?

  1. 刷新肯定是没法解决的;
  2. 强制刷新(Command-Shift-R)可以解决,但下一次打开你依然会看到 PWA 准备的旧版文档;
  3. F12 打开 Application,点「Clear site data」;这样做可以解决几乎一切的网站缓存问题,但下一次打开依然是旧版文档。

正确的做法有两种:

  1. F12 打开Application 点「Service Workers」,然后点「Unregister」
  2. 浏览器中输入 chrome://serviceworker-internals,找到 koishi.js.org,然后点「Unregister」

可以看到,没有任何一种 面向用户 的方法来解决这个问题。要想解决,必须使用 F12,或打开浏览器内部页面。

3 个赞

六、「时间裂隙」

好的!现在我们终于找到这个问题的解法了;虽然解法很麻烦,但能够根治问题,也算值了。

接下来通知我们的用户,进行一遍这个操作就可以了!

——于是,我们最终到达了「时间裂隙」问题的核心:


「时间裂隙」问题:

你无法通知你的用户,因为他们看不到新版文档

6 个赞

七、终

你可能会思考:「文档上不能通知,那开个群,在群里通知,或者在 GitHub 上通知,都可以啊」

但文档是作者与用户建立联系的开始,因为用户第一次接触到这个项目一定是通过文档。如果无法在文档上通知,那么任何其他的手段都是无法实现的。

对目前的 Koishi 而言,只要你搜索「Koishi」,排名第一的永远是「时间裂隙」文档。 如果文档上无法告诉用户怎么解除 PWA,那么文档上自然也无法告诉用户「加群,有急事」,自然也无法告诉用户「看 GitHub」。


最终,我们选择这样做:

  1. koishi.js.org 上的文档从 VitePress 换回 VuePress,并在上面添加红框,提示这是旧版文档
  2. 购入 新的域名 koishi.chat,使用 VitePress,用作新的官网
3 个赞

八、无法实现的自杀

你可能又会思考:「难道一个网站部署 PWA 以后,要想解除,就只能让用户通过 F12 操作了?这不可能,这太蠢了」

确实。PWA 的确提供了解除自己的 API,只要调用这个 API,就可以实现「自杀」。然而,浏览器并没有实现「防呆」机制,这意味着 PWA 的解除依赖于作者第一次编写 PWA 代码的时候有没有考虑到这个问题。如果作者第一次发布的 PWA 程序没有考虑到,那么之后想补救也不可能了,下载了第一版 PWA 程序的用户将会永远迷失在「时间裂隙」里。

进一步思考的话,你会发现,即使有这个机制,「什么时候自杀」也是一个大问题。以 Koishi 文档为例,你可能觉得「获取不到新文件的时候自杀」就可以实现,但「获取不到新文件」本身也可能有各种各样的原因:

  • 用户没网了
  • 服务器刚好在更新系统
  • 服务器 IP 地址换了,DNS 解析尚未更新

什么时候才可以下「我的 PWA 可以自杀了」的决定?这需要经过多次的设计和实际测试才得出结论,但很显然当年的 PWA 推进者们并不是所有人都给出了完美的答案。

4 个赞

九、搜索引擎的权重

从群友处得知,Google 为了给用户提供更有价值的结果,想出了很多很偏门的权重策略,包括:

  1. 统计一个网站的年龄。 一般来讲,存在时间更久的网站总是比那些刚成立的网站质量高。那么,我们就可以统计每个网站的年龄,并增加历史悠久的网站的权重。
  2. 统计旧内容的比例。 这招是对付抄袭站的好方法(你用百度搜会看到大量机翻 StackOverflow 的网站),如果一个网站上有其他网站早已出现的内容,就降低这个站的权重。

Google 在搜索排名上真的很有一套,上面的方法确保了靠前的位置永远是那些质量更高,输出原创内容的网站,而不是新站或抄袭站。


你有没有发现—— koishi.chat 刚好精准命中了上面两点:

  1. koishi.chat 的网站年龄总是比 koishi.js.org 低(并且年龄差 永不变
  2. koishi.chat 上的 几乎所有内容 都是 koishi.js.org 的重复内容

这意味着,koishi.chat 是一个新的、以抄袭起家的网站。Google 会降低这个站点的权重,而抬高 koishi.js.org 的权重。

——并将永远如此。

在今天,或在以后,在 Google 上搜索「Koishi」,旧站 koishi.js.org 将永远排在第一。 我们目前没有解决这一问题的方法。

5 个赞

看完标题已经开始笑了

2 个赞

看完标题已经开始笑了

2 个赞

但是断网也可以看文档真的很酷

2 个赞

时空裂荚

2 个赞

有一个办法可以解决,可以完全废弃koishi.js.org中除将用户引导到新域名之外的一切内容,有以下好处:

  • koishi.chat 上不再存在 koishi.js.org 的重复内容
  • 即使始终将koishi.js.org作为入口,也不影响用户获取最新内容。
1 个赞

可以这么做,不过必须仍然写在 VuePress v1 里。

举个例子:

之前我们为什么没有这么做来着,我记得 jsorg 只是不许 302 吧?

2 个赞

因为不好拿 VuePress v1 写这个

1 个赞


1 个赞