简体   繁体   English

如何使预取链接与 JavaScript 文件一起使用?

[英]How to make prefetch link work with JavaScript file?

I'm trying to use prefetching (via a link with rel="prefetch") for a JavaScript resource in an html page.我正在尝试对 html 页面中的 JavaScript 资源使用预取(通过带有 rel="prefetch" 的链接)。 In Chrome, I see the prefetch request get kicked off with a "Type" of "javascript".在 Chrome 中,我看到预取请求以“javascript”的“类型”启动。 If I subsequently try and fetch the same JavaScript resource by inserting a script tag into the page, I'd expect this to be fetched from the browser cache, rather than a new request being fired off to fetch the resource from the CDN.如果我随后尝试通过在页面中插入脚本标记来获取相同的 JavaScript 资源,我希望这是从浏览器缓存中获取的,而不是触发新请求以从 CDN 获取资源。 However, this is not the case.然而,这种情况并非如此。 I see a new request being made with the "Type" of "script".我看到使用“脚本”的“类型”发出了一个新请求。 I'm assuming that the issue is related to the mismatch in type between this request and the prefetch request.我假设问题与此请求和预取请求之间的类型不匹配有关。

Is there a way to force the prefetch request to use a type of script or some other way to avoid the JavaScript file being fetched again?有没有办法强制预取请求使用某种类型的脚本或其他方式来避免再次提取 JavaScript 文件?

I've tried using an "as" attribute value of "script", but that seems to have no effect.我试过使用“script”的“as”属性值,但这似乎没有效果。

I'm aware that rel="preload" is an alternative option.我知道 rel="preload" 是一个替代选项。 This works, but the usual advice seems to be that preloading is only appropriate for resources you're about to use and prefetching is a better choice for resources you will use after navigating elsewhere in your web page.这是有效的,但通常的建议似乎是预加载仅适用于您将要使用的资源,而预取是您在浏览网页中的其他位置后将使用的资源的更好选择。 Chrome also warns if you use preload and don't use the resource within a few seconds.如果您使用预加载并且在几秒钟内不使用资源,Chrome 也会发出警告。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <link rel="prefetch" href="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular-cookies.js" />
    <script type="text/javascript">
        setTimeout(function() {
             const scriptElement = document.createElement("script");
             scriptElement.src = "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular-cookies.js";
             document.head.appendChild(scriptElement);
         }, 2000);
    </script>
</head>
<body>
</body>
</html>

See above for example repro code.参见上面的示例重现代码。 I'd expect the script tag inside the setTimeout to use the already fetched resource, but instead I see a new request being fired off.我希望 setTimeout 中的脚本标签使用已经获取的资源,但我看到一个新的请求被触发。

I figured this one out, finally.我终于想通了这一点。 You're likely seeing this happen because Disable Cache is on in Chrome dev tools: Disabling Chrome cache for website development您可能会看到这种情况发生,因为在 Chrome 开发工具中启用了禁用缓存:为网站开发禁用 Chrome 缓存

This doesn't just disable previously-cached assets – it also means that something like this would download an asset twice:这不仅会禁用先前缓存的资产 - 这也意味着这样的事情会下载资产两次:

<script src="foo.js">
<script src="foo.js">

With that checkbox unchecked , you should successfully see your asset getting cached:取消选中该复选框后,您应该会成功看到您的资产被缓存:

预取缓存资源的屏幕截图

That all being said, it is very important to note that in my testing, Chrome is not smart enough to realize that a prefetch and a regular download for the same resource is happening at the same time – it won't attempt to cache one for the other.话虽如此,重要的是要注意,在我的测试中,Chrome 不够聪明,无法意识到同一资源的预取和常规下载同时发生——它不会尝试缓存一个另一个。 So if your prefetching takes longer than your setTimeout millisecond value, you will see duplicate downloads!因此,如果您的预取时间超过setTimeout毫秒值,您将看到重复的下载!

This is certainly because what you and I are doing here is in some ways an abuse of prefetching.这当然是因为你和我在这里所做的在某些方面是对预取的滥用。 It's supposed to be a way to download resources used for the next navigation.它应该是一种下载用于下一个导航的资源的方法。 C'est la vie!这就是生活!

Is there a way to force the prefetch request to use a type of script or some other way to avoid the JavaScript file being fetched again?有没有办法强制预取请求使用某种类型的脚本或其他方式来避免再次提取 JavaScript 文件?

I've tried using an "as" attribute value of "script", but that seems to have no effect.我试过使用“script”的“as”属性值,但这似乎没有效果。

Just as a final note, the type differences of script and javascript are to be expected.最后要注意的是, scriptjavascripttype差异是可以预料的。 This is Dev Tools trying to tell you that one of the files is going to be executed and the other is merely getting downloaded.这是 Dev Tools 试图告诉您其中一个文件将被执行,而另一个文件只是被下载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM