支持 ETag 头部

我觉得 ETag 会对页面加载产生显著的性能提升,因为大多数 HTML 页面并未被缓存。这样,如果客户端已经下载过该页面,服务器就无需再次提供。

我可能说错了,但 Discourse 已经高度依赖客户端 JavaScript,因此客户端下载的数据量非常小。几乎所有内容都在首次访问时加载,随后被缓存。说实话,我不确定 ETags 能在多大程度上优化这一缓存过程。

例如,我的页面首次加载约为 800KB,第二次加载则约为 40KB。

2 个赞

Discourse 本身的设计与配置已相当完善,非常适合缓存。

大多数网站资源(如 JavaScript、CSS)都拥有唯一的 URL,这些 URL 会在每次更新网站时根据资源的哈希值生成,因此可以设置较长的缓存时间。

我认为网站上传的内容(如图片、头像等)也使用了唯一的 URL。

大多数可浏览的完整页面都是动态生成的,不应进行激进的缓存。理论上,可以采用类似 ETag 的缓存机制,在每次页面加载时检查是否有新发布或编辑的帖子。我不太清楚团队为何决定不采用这种方式。

3 个赞

我应该澄清一下:资源确实缓存得很好——我指的是 HTML 文档(首次请求)。

你能看到的大部分完整页面都是动态的,不应被激进地缓存。我想,也许可以实现某种 ETag 缓存机制,在每次页面加载时检查是否有新增或编辑过的帖子。我不确定团队为何决定不这样做。

是的,这基本上就是我所说的内容,但我认为 ETag 并不是像那样手动生成的——它们可以基于所服务的原始 HTML 生成,并告知客户端:“嘿,这和你之前看到的一模一样,直接使用它即可”。

问题是,据我所知,客户端的 JavaScript 已经实现了这一点。因此,HTML 不会来回传输。

1 个赞

HTML 从服务器加载 JSON,该 JSON 请求本可以使用 ETag。但目前并未使用,不过我不确定团队对此的论点是什么。

1 个赞

首次请求页面时,确实会在通过 XHR 从服务器加载 JSON 之前渲染内容,您说得对,这也在发生。

您可以通过在 Chrome 调试器中查看“Document”类型的网络请求来验证这一点,它应该(至少在我的情况下)已经渲染了分类。

以下是从文档请求中渲染的内容示例:

您的请求没有意义,因为 Discourse 是一个 JavaScript 应用,它不获取 HTML,所有“页面”都是通过可执行的 JavaScript 代码实时构建的。

1 个赞

您的请求毫无意义,因为 Discourse 是一个 JavaScript 应用程序,它不检索 HTML。

我完全尊重您在此方面的经验和专业知识,但我已经运行过数十个使用 ETag 的 JavaScript 渲染 Web 应用程序(在根响应中,如果内容可以复用的话)。

所有“页面”都是通过可执行的 JavaScript 代码实时构建的。

我上面发布的截图是客户端代码运行之前返回的 HTML,因此后端(我假设是 Rails)肯定有内容在提供此路由。

除了这个站点之外,我查看过的每一个 Discourse 社区最初都会返回一个不包含 JavaScript 的站点版本,其中所有内容都已渲染,这大概是为了爬虫。

如果我完全搞错了,我深表歉意,但我不认为我是在“胡说八道”,我可能只是错了

1 个赞

仅针对爬虫用户代理,因此这并非一个有用的观察。

仅适用于爬虫用户代理

这与我运行此命令时看到的结果不符:

curl -H "User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" https://community.midi.city/

这不是一个爬虫用户代理,但它却返回了上述内容。


无论如何,我认为关于我请求 ETag 的答复是“否”,所以感谢你的反馈,也许将来会重新考虑这一点。

正确,出于哲学和技术两方面的原因,答案都是明确且坚决的“不”。

(资产是另一个问题,但使用带 GUID 的唯一文件名是更优的方法,因此 ETag 总体上已有些过时。)

即使是针对 API 也是如此吗?我理解对于较小的请求来说,可能不值得这么做,但主题视图的大小可能高达 20KB,累积起来会很多。不过,除非有新帖子,否则很少有人会反复查看主题……

这正是关键所在。对于重复查看完全相同的内容,如果您处于离线状态,我们已直接从浏览器缓存渲染所有内容,无需访问服务器。

若要升级以实现即使在线也能加载,则涉及缓存失效机制,因此这自然颇具挑战。

2 个赞

哦,很高兴听到这能正常工作。我原本以为 cache-control: no-cache, no-store 头意味着 API 响应永远不会进入浏览器的缓存。

它们不是。嗯,情况比较复杂。这里涉及多个缓存机制 :sweat_smile:

它不会进入大家熟知和喜爱的传统浏览器缓存。但是,浏览器在 JavaScript 中暴露了一个 Cache Web API,用于缓存响应,以便提供对先前已阅读内容的离线导航。

5 个赞