链接预取跨子域有效吗?


10

从简单的登录页面单击到重量级的单页面应用程序时,我一直在尝试使用类似的方法来提高性能:

<link rel="prefetch" href="https://example.com" as="document" />
<link rel="prefetch" href="https://example.com/app.js" as="script" />
<link rel="prefetch" href="https://example.com/app.css" as="style" />

当我的目标网页位于子域上时,似乎没有明显的性能提升。说,https://subdomain.example.com

当我点击要访问的链接时https://example.com,我仍然在Chrome的“网络”标签中看到app.jsapp.css加载了很长的延迟:

预取资源 预取的资源下载时间

这是禁用预取的相同资源:

资源下载时间,无需预取

总共花费的时间大致相同。


请求标有预取缓存的资产之一的标头:

一般:

Request URL: https://example.com/css/app.bffe365a.css
Request Method: GET
Status Code: 200  (from prefetch cache)
Remote Address: 13.226.219.19:443
Referrer Policy: no-referrer-when-downgrade

响应:

accept-ranges: bytes
cache-control: max-age=31536000
content-encoding: gzip
content-length: 39682
content-type: text/css
date: Mon, 06 Jan 2020 21:42:53 GMT
etag: "d6f5135674904979a2dfa9dab1d2c440"
last-modified: Mon, 06 Jan 2020 20:46:46 GMT
server: AmazonS3
status: 200
via: 1.1 example.cloudfront.net (CloudFront)
x-amz-cf-id: dO3yiCoPErExrE2BLYbUJaVye32FIJXXxMdI4neDGzGX9a6gcCDumg==
x-amz-cf-pop: LAX50-C1
x-amz-id-2: 1O0LmihxpHIywEaMQWX7G3FDAzxtH9tZq1T/jeVLMzifFSJSIIJSS6+175H61kKdAq6iEbwfs2I=
x-amz-request-id: AF35C178092B65D4
x-cache: Hit from cloudfront

请求:

DNT: 1
Referer: https://example.com/auth/join
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36

我的问题是:如果Chrome指示使用了预取缓存,那么为什么会有大量的内容下载时间?

Chrome似乎具有不同类型的缓存:预取缓存,磁盘缓存和内存缓存。磁盘缓存和内存缓存非常快(加载时间分别为5ms和0ms)。但是,有时300ms下载时间的预取缓存几乎没有用。我可以得到为什么会发生这种情况的技术解释吗?Chrome的错误吗?我使用的是Chrome 79.0.3945.117。


预取用于加快未来导航,看到一个简要的解释(web.dev/link-prefetch
穆罕默德Yaseer

是的,预取会加快以后的导航速度。那为什么不以我的情况加快速度呢?请参见时序图。
Maros

您可以尝试将子域的内容放置在另一个域上,并检查加载时间是否也相同吗?您似乎已经指出,通过显示非子域(即其他域)案例的工作原理,未显示子域可能是一个问题。如果子域存在问题,那么下一步将是研究是否需要进行调整的Chrome配置设置,或者
Martin

还是在具有类似工具集的其他浏览器(例如Firefox Inspector或Opera)上,子域和/或独立域的加载时间相同?如果您所引用的其他使用不同引擎的浏览器发生相同的计时问题(我不确定哪个也不再使用),则可能是一个错误-我完全可以相信这可能是Chrome错误如果这些记录的时间值在其他浏览器上明显不同。
马丁

Answers:


0

添加<link rel=prefetch>到网页可以使浏览器下载用户将来可能需要的整个页面或某些资源(例如脚本或CSS文件)。这可以改善“首次内容丰富​​的绘画”和“互动时间”等指标,并且通常可以使后续导航看起来立即可以加载。

在此处输入图片说明

预取提示会消耗不立即需要的资源的额外字节,因此需要谨慎地应用此技术。仅在确信用户将需要资源时才预取资源。当用户的连接速度较慢时,请考虑不预取。您可以使用Network Information API进行检测。

有多种方法可以确定要预取的链接。最简单的方法是预取当前页面上的第一个链接或前几个链接。还有一些库使用更复杂的方法,这将在本文后面的https://web.dev/link-prefetch/中进行解释。


我一直在寻找一个解释,为什么在我的特殊情况下,链接预取不能加快速度。是因为子域,服务人员还是其他原因?如果查看我的屏幕截图,您会发现尽管预取了浏览器,但浏览器仍在重新下载内容。
Maros

0

我只能猜。通过实验,只有您才能找到自信的答案。有太多变量要说明。但是这里有一些想法:

  1. prefetch是浏览器的提示。浏览器可以出于某些任意原因忽略它。除此之外,它具有最低的优先级。
  2. 例如,以防万一,请检查您的浏览器设置:(
    Menu/Settings/Advanced/Privacy and security/Preload pages for faster browsing and searching
    或类似的内容)。
  3. 如果碰巧您正在使用移动互联网,那也可能是一个问题。
    https://www.technipages.com/google-chrome-prefetch
  4. 您从目标网页导航到的速度有多快example.com
  5. 检查您的服务器日志以查看它是否曾经收到prefetch请求。
  6. 检查您的服务器是否根据请求设置了一些奇怪的标头prefetch。例如Cache-Control: no-cache。是的,我看到您有cache-control: max-age=31536000,所以如果服务器将为同一请求发送不同的标头,那真是很奇怪(嗯... 几乎相同,至少您没有说过是,而且至少可以是一些标头,表明它是一个prefetch请求),但是奇怪的事情发生了。

  7. 您可能应该尝试添加crossorigin属性。例如

    <link rel="prefetch" href="https://example.com/app.css" as="style" crossorigin />

    在这里https://www.w3.org/TR/resource-hints/您可以找到此示例

    <link rel="preconnect" href="//example.com">
    <link rel="preconnect" href="//cdn.example.com" crossorigin>

    与您的情况非常相关,但不幸的是没有任何解释。

  8. 在您问题的原始版本中,您提到过服务人员...如果他们下载某些内容,或者甚至您自己手动下载某些内容,也可能是问题所在。由于优先级最低prefetch

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Link_prefetching_FAQ#What_if_I.27m_downloading_something_in_the_background.3F_Will_link_prefetching_compete_for_bandwidth.3F

    如果您使用Mozilla下载内容,则链接预取将被延迟,直到完成所有后台下载为止

    我认为Chrome也是如此。

  9. 您是否尝试过将登录页面移至根域?如果是,并且prefetch按预期工作,则是-子域是问题的原因。GUI消息Status Code: 200 (from prefetch cache)可能只是一个小故障。因为最近prefetch,Chrome 中的某些行为才开始发生变化。我还不知道事情是否会解决。基本上,是的,您很有可能prefetch只能来自同一来源。

    https://docs.google.com/document/d/1bKGDIePAuF6YXmmrwM33LeLvtuCsla3vTspsxsNp-f8/edit


阅读您的答案后,一些随机的注释:我从登录页面到example.com的浏览速度非常慢,从而有足够的时间加载所有资源。我在Chrome中禁用了服务人员的情况下进行了上述测试。我认为crossorigin属性用于其他方面。我确实尝试过使用它,但是没有运气。最坏的情况是,我会通过将登录页面移至根域来进行您建议的测试。我希望这里的答案可以节省我的工作。
Maros

1
你尝试过FF吗?在上方的MDN链接中:“ Mozilla可以从其他主机上预取文档吗?是。链接预取没有同源限制。将预取限制为仅来自同一服务器的URL不会提高浏览器的安全性。” 该段落可以过时,但仍然可以。很高兴知道他们在Chrome上的行为是否有所不同。
x00

我尝试过,但是我无法禁用似乎优先于预取缓存的服务人员。我可以再试一次。
Maros

@Maros,以某种方式您不拥有代码,或者存在一些技术问题?
x00

-1

您应该添加以下代码,以防万一您是子域,并且您希望从域中获取资源

<link rel="preconnect" href="https://example.com">
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.