我觉得 ETag 会对页面加载产生显著的性能提升,因为大多数 HTML 页面并未被缓存。这样,如果客户端已经下载过该页面,服务器就无需再次提供。
我可能说错了,但 Discourse 已经高度依赖客户端 JavaScript,因此客户端下载的数据量非常小。几乎所有内容都在首次访问时加载,随后被缓存。说实话,我不确定 ETags 能在多大程度上优化这一缓存过程。
例如,我的页面首次加载约为 800KB,第二次加载则约为 40KB。
Discourse 本身的设计与配置已相当完善,非常适合缓存。
大多数网站资源(如 JavaScript、CSS)都拥有唯一的 URL,这些 URL 会在每次更新网站时根据资源的哈希值生成,因此可以设置较长的缓存时间。
我认为网站上传的内容(如图片、头像等)也使用了唯一的 URL。
大多数可浏览的完整页面都是动态生成的,不应进行激进的缓存。理论上,可以采用类似 ETag 的缓存机制,在每次页面加载时检查是否有新发布或编辑的帖子。我不太清楚团队为何决定不采用这种方式。
我应该澄清一下:资源确实缓存得很好——我指的是 HTML 文档(首次请求)。
你能看到的大部分完整页面都是动态的,不应被激进地缓存。我想,也许可以实现某种 ETag 缓存机制,在每次页面加载时检查是否有新增或编辑过的帖子。我不确定团队为何决定不这样做。
是的,这基本上就是我所说的内容,但我认为 ETag 并不是像那样手动生成的——它们可以基于所服务的原始 HTML 生成,并告知客户端:“嘿,这和你之前看到的一模一样,直接使用它即可”。
问题是,据我所知,客户端的 JavaScript 已经实现了这一点。因此,HTML 不会来回传输。
HTML 从服务器加载 JSON,该 JSON 请求本可以使用 ETag。但目前并未使用,不过我不确定团队对此的论点是什么。
首次请求页面时,确实会在通过 XHR 从服务器加载 JSON 之前渲染内容,您说得对,这也在发生。
您可以通过在 Chrome 调试器中查看“Document”类型的网络请求来验证这一点,它应该(至少在我的情况下)已经渲染了分类。
以下是从文档请求中渲染的内容示例:
您的请求没有意义,因为 Discourse 是一个 JavaScript 应用,它不获取 HTML,所有“页面”都是通过可执行的 JavaScript 代码实时构建的。
您的请求毫无意义,因为 Discourse 是一个 JavaScript 应用程序,它不检索 HTML。
我完全尊重您在此方面的经验和专业知识,但我已经运行过数十个使用 ETag 的 JavaScript 渲染 Web 应用程序(在根响应中,如果内容可以复用的话)。
所有“页面”都是通过可执行的 JavaScript 代码实时构建的。
我上面发布的截图是客户端代码运行之前返回的 HTML,因此后端(我假设是 Rails)肯定有内容在提供此路由。
除了这个站点之外,我查看过的每一个 Discourse 社区最初都会返回一个不包含 JavaScript 的站点版本,其中所有内容都已渲染,这大概是为了爬虫。
如果我完全搞错了,我深表歉意,但我不认为我是在“胡说八道”,我可能只是错了。
仅针对爬虫用户代理,因此这并非一个有用的观察。
仅适用于爬虫用户代理
这与我运行此命令时看到的结果不符:
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,累积起来会很多。不过,除非有新帖子,否则很少有人会反复查看主题……
这正是关键所在。对于重复查看完全相同的内容,如果您处于离线状态,我们已直接从浏览器缓存渲染所有内容,无需访问服务器。
若要升级以实现即使在线也能加载,则涉及缓存失效机制,因此这自然颇具挑战。
哦,很高兴听到这能正常工作。我原本以为 cache-control: no-cache, no-store 头意味着 API 响应永远不会进入浏览器的缓存。
它们不是。嗯,情况比较复杂。这里涉及多个缓存机制 ![]()
它不会进入大家熟知和喜爱的传统浏览器缓存。但是,浏览器在 JavaScript 中暴露了一个 Cache Web API,用于缓存响应,以便提供对先前已阅读内容的离线导航。
