【问题标题】:Serving Angular app as a static content in Express Server在 Express Server 中将 Angular 应用程序作为静态内容提供服务
【发布时间】:2021-11-06 10:56:27
【问题描述】:
我将 Angular 应用程序作为 Express Server 中的静态内容提供服务。当使用 Express 提供静态文件时,Express 默认将 ETag 添加到文件中。因此,每个下一个请求都会首先检查ETag 是否匹配,如果匹配,则不会再次发送文件。我知道 Service Worker 的工作方式类似,它会尝试匹配 hash。有谁知道这两种方法之间的主要区别是什么(使用 ETag 缓存和使用 Service Worker 进行缓存),以及我们何时应该使用其中一种方法?在性能方面什么是最有效的:
- 服务器端缓存和提供 Angular 应用静态文件
- 为缓存实现 Angular Service Worker
- 同时执行 1 和 2
【问题讨论】:
标签:
javascript
node.js
angular
typescript
express
【解决方案1】:
为了提供更好的视角,我还将介绍第三个缓存选项,以澄清差异。
缓存类型
基本上,我们有 3 层可能的缓存层,这取决于从客户端检查它们的优先级:
- Service Worker 缓存(客户端)
- 浏览器缓存,也称为 HTTP 缓存(客户端)
- 服务器端缓存 (CDN)
PS:某些浏览器(例如 Chrome)在 Service Worker 缓存前有一个额外的内存缓存层。
特点/差异
服务工作者是客户端中最可靠的,因为它定义了自己的规则来管理缓存,并提供额外的功能和对缓存内容和缓存方式的细粒度控制。
浏览器缓存是根据资产响应(Cache-Control 和 Expires)中的一些 HTTP 标头定义的,但主要问题是在很多情况下这些标头会被忽略。
例如,我听说对于大于 25Mb 的文件,通常不会缓存它们,特别是在内存有限的移动设备上(我相信由于移动设备使用量的增加,它最近变得更加严格)。
所以在这两个选项之间,我总是选择 Service Worker 缓存以获得更高的可靠性。
现在,与第三个选项交谈,CDN 检查 HTTP 标头以查找 ETag 以破坏缓存。
服务器端缓存的想法是仅在 CDN 上找不到资产的情况下调用源服务器。
现在,在第 1 次和第 3 次之间,主要区别在于 Service Worker 最适合慢速/失败的网络连接和离线,因为缓存是在客户端完成的,所以如果网络关闭,那么 Service Worker 会检索最后缓存的信息,允许流畅的用户体验。
另一方面,服务器端只有在我们能够到达服务器时才起作用,但同时缓存发生在用户设备之外,节省了本地空间,并减少了应用程序的内存消耗。
如您所见,没有正确/错误的答案,只有最适合您的用例。
一些来源
【解决方案2】:
让我们回答你的问题:
这两种方法的主要区别是什么(使用 ETag 缓存和使用 Service Worker 缓存)
两种方案都缓存文件,主要区别是需要到达服务器还是留在本地:
- 对于 ETag,浏览器向服务器请求带有哈希的文件(etag),根据存储在服务器中的文件,服务器将回答“文件未修改,请使用您的本地副本”带有 300 HTTP 响应或“这里是该文件的新版本”带有 200 HTTP 响应和新文件。 在这两种情况下,服务器始终做出决定。而用户将等待往返。
- 使用 Service Worker 方法,您可以在本地决定要做什么。您可以编写一些逻辑来控制什么/何时使用本地副本(缓存)或何时访问服务器。这对于离线功能非常有用,因为逻辑发生在客户端,无需访问服务器。
我们什么时候应该使用一个而不是另一个?
您可以同时使用两者。你可以在Service Worker中定义一些逻辑,如果没有连接则返回本地副本,否则转到服务器。
在性能方面什么是最有效的:
- 服务器端缓存和提供 Angular 应用静态文件
- 为缓存实现 Angular Service Worker
- 同时执行 1 和 2
我推荐的方法是同时使用这两种方法。尽管以不同的方式处理您的文件,但“index.html”文件可能会更改,在这种情况下,请使用 service worker(以防无法访问 Internet),如果可以访问 Internet,则让 Web 服务器使用 etag 进行应答。所有其他静态文件(CSS 和 JS)应该是不可变文件,这是您可以确保本地副本是有效的,在这种情况下,为文件名添加哈希(因此它们始终是唯一文件)并缓存它们。当您拥有应用程序的新版本时,您将修改“index.html”指向新的不可变文件。