最近,我采用了服务工作者,通过使用缓存优先策略来加快初始HTML加载:
function cacheFirst () { /* ... */ }
self.addEventListener('fetch', (event) => {
const { request } = event
if (request.mode === 'navigate' && request.method === 'GET') {
event.respondWith(cacheFirst(event))
}
})
它工作正常并且很酷。
但是当我观察到Chrome开发工具的网站性能时,我发现很烦人:我对宁静的api服务器的所有请求都由少量但明显的服务人员开销作为前提。
我看到我所有安静的请求都首先发送给服务人员。而且由于不打算缓存这些请求,因此fetch
事件处理程序只会忽略该事件(不调用event.respondWith
)。然后,正常请求由浏览器自身发出。
令我烦恼的是,与服务人员的这种空程往返大约需要15-40毫秒(在我的Android手机上最多为80-200毫秒)。这对我来说很荒谬,我试图通过消除对缓存结果的304响应来节省15-40毫秒,但是在请求动态数据时引入了15-40毫秒的延迟。
我尝试仅调用event.respondWith(event.request)
来请求不喜欢缓存的请求,但是与删除服务工作者相比,我仍然可以观察到一些开销。
function cacheFirst () { /* ... */ }
self.addEventListener('fetch', (event) => {
const { request } = event
if (request.mode === 'navigate' && request.method === 'GET') {
event.respondWith(cacheFirst(event))
} else {
event.respondWith(fetch(request))
}
})
我在网上搜索时,并没有发现对这种性能缺陷的担忧(这让我怀疑在现实世界中真正使用过IS服务工作者)。
除了我的故事,我的问题是:我能否在请求一个宁静的api(我只是确定不应该对其进行缓存)时绕过服务人员,同时还能保留收益用于可缓存的资源。
答案 0 :(得分:1)
(您可能会在Chrome开发者峰会上发现this recent talk很有趣,因为它更详细地介绍了同一领域。)
您是对的,因为将服务工作者置于Web应用程序和网络之间会产生一定的开销,并且在速度较慢的设备/存储速度较慢的情况下,开销可能会更大。
理想情况下,如果您能够响应来自缓存的“重要”请求,则服务工作者将提高Web应用程序的整体性能。例如,您可以首先对导航请求进行缓存这一事实,这意味着回头客应该比其他人更快地在屏幕上看到内容。
但是您知道您的Web应用程序的网络流量模式是最好的,并且,如果您的Web应用程序发出的大多数请求是针对不可缓存的远程API调用,则增加的服务工作者开销可能会超过您从中获得的收益缓存本地资产。并非每个Web应用程序都属于该类别,是的,有很多“真实世界”的服务工作者表现良好的性能部署。 https://www.pwastats.com/
是一个收集著名示例的网站。关于您关于绕过服务人员获取您仍然必须进入网络的URL的特定问题,当前没有可用的解决方案。服务人员标准小组正在就解决方案进行一些集体讨论,可能涉及在注册服务人员时传递“路由”信息的方法,从而导致服务人员在请求与路由不匹配时不会拦截请求。您可以阅读有关它的更多信息,如果您觉得有什么要补充的,可以参加:https://github.com/w3c/ServiceWorker/issues/1026