diff options
Diffstat (limited to 'files/zh-cn/orphaned/web/html/preloading_content/index.html')
-rw-r--r-- | files/zh-cn/orphaned/web/html/preloading_content/index.html | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/files/zh-cn/orphaned/web/html/preloading_content/index.html b/files/zh-cn/orphaned/web/html/preloading_content/index.html deleted file mode 100644 index 454ea6a38b..0000000000 --- a/files/zh-cn/orphaned/web/html/preloading_content/index.html +++ /dev/null @@ -1,289 +0,0 @@ ---- -title: 通过rel="preload"进行内容预加载 -slug: orphaned/Web/HTML/Preloading_content -tags: - - HTML - - JavaScript - - Link - - as - - 媒体 - - 媒体查询 - - 性能 - - 性能优化 - - 指南 - - 预加载 -translation_of: Web/HTML/Preloading_content -original_slug: Web/HTML/Preloading_content ---- -<p class="summary"> {{htmlelement("link")}} 元素的 {{htmlattrxref("rel", "link")}} 属性的属性值<code>preload</code>能够让你在你的HTML页面中 {{htmlelement("head")}}元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源,你可能希望在页面加载的生命周期的早期阶段就开始获取,在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。本文提供了一个如何有效使用<code>preload</code>机制的基本说明。</p> - -<h2 id="基础部分">基础部分</h2> - -<p><code><link></code> 标签最常见的应用情形就是被用来加载CSS文件,进而装饰你的页面:</p> - -<pre class="brush: html notranslate"><link rel="stylesheet" href="styles/main.css"></pre> - -<p>但是在这里,我们将使用<code>preload</code>作为<code>rel</code>属性的属性值。这种做法将把<code><link></code> 元素塞入一个预加载器中,这个预加载器也将用于其他我们所需要的,各种各样的,任意类型的资源。为了完成基本的配置,你还需要通过 {{htmlattrxref("href", "link")}}和{{htmlattrxref("as", "link")}} 属性指定需要被预加载资源的资源路径及其类型。</p> - -<p>一个简单的例子可能看起来像下面这样 (在这里可以查看示例的<a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/js-and-css">JS和CSS源代码</a>,或是<a href="https://mdn.github.io/html-examples/link-rel-preload/js-and-css/">在线实例</a>)</p> - -<pre class="brush: html notranslate"><head> - <meta charset="utf-8"> - <title>JS and CSS preload example</title> - - <link rel="preload" href="style.css" as="style"> - <link rel="preload" href="main.js" as="script"> - - <link rel="stylesheet" href="style.css"> -</head> - -<body> - <h1>bouncing balls</h1> - <canvas></canvas> - - <script src="main.js"></script> -</body></pre> - -<p>在这里,我们预加载了CSS和JavaScript文件,所以在随后的页面渲染中,一旦需要使用它们,它们就会立即可用。这个例子本身可能有些平淡,但预加载的好处可以更清晰直观的得到展示,在随后的渲染过程中,这些资源得到有效使用。对于更大的文件来说,也是如此。 例如那些在CSS文件中指向的资源,比如字体或是图片;再比如更大的图片和视频文件。</p> - -<p><code>preload</code> 还有许多其他好处。使用 <code>as</code> 来指定将要预加载的内容的类型,将使得浏览器能够:</p> - -<ul> - <li>更精确地优化资源加载优先级。</li> - <li>匹配未来的加载需求,在适当的情况下,重复利用同一资源。</li> - <li>为资源应用正确的<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP">内容安全策略</a>。</li> - <li>为资源设置正确的 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept" title="The Accept request HTTP header advertises which content types, expressed as MIME types, the client is able to understand. Using content negotiation, the server then selects one of the proposals, uses it and informs the client of its choice with the Content-Type response header. Browsers set adequate values for this header depending of the context where the request is done: when fetching a CSS stylesheet a different value is set for the request than when fetching an image, video or a script."><code>Accept</code></a> 请求头。</li> -</ul> - -<h3 id="哪些类型的内容可以被预加载?">哪些类型的内容可以被预加载?</h3> - -<p>许多不同类型的内容都可以被预加载,一些主要可用的<code>as</code> 属性值列举如下:</p> - -<ul> - <li><code>audio</code>: 音频文件。</li> - <li><code>document</code>: 一个将要被嵌入到{{htmlelement("frame")}}或{{htmlelement("iframe")}}内部的HTML文档。</li> - <li><code>embed</code>: 一个将要被嵌入到{{htmlelement("embed")}}元素内部的资源。</li> - <li><code>fetch</code>: 那些将要通过fetch和XHR请求来获取的资源,比如一个ArrayBuffer或JSON文件。</li> - <li><code>font</code>: 字体文件。</li> - <li><code>image</code>: 图片文件。</li> - <li><code>object</code>: 一个将会被嵌入到{{htmlelement("embed")}}元素内的文件。</li> - <li><code>script</code>: JavaScript文件。</li> - <li><code>style</code>: 样式表。</li> - <li><code>track</code>: WebVTT文件。</li> - <li><code>worker</code>: 一个JavaScript的web worker或shared worker。</li> - <li><code>video</code>: 视频文件。</li> -</ul> - -<div class="note"> -<p><strong>注意</strong>: 你可以通过进一步阅读<a href="https://w3c.github.io/preload/#link-element-extensions">link element extensions</a>来了解关于这些属性值以及其他在Preload方案中预期将采纳的特性的细节。同样需要注意的是,关于<code>as</code>属性的有效值得完整列表是由Fetch方案来制定的,可以查看<a href="https://fetch.spec.whatwg.org/#concept-request-destination">request destinations</a>来进行了解。</p> -</div> - -<h2 id="包含一个MIME类型">包含一个MIME类型</h2> - -<p><code><link></code> 元素可以接受一个{{htmlattrxref("type", "link")}}属性。这一属性可以包含该元素所指向资源的MIME类型。在浏览器进行预加载的时候,这个属性值将会非常有用——浏览器将使用<code>type</code>属性来判断它是否支持这一资源,如果浏览器支持这一类型资源的预加载,下载将会开始,否则便对其加以忽略。</p> - -<p>你可以在我们的视频示例中看到一个与此有关的示例(查看<a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/video">完整源码</a>,也可以查看<a href="https://mdn.github.io/html-examples/link-rel-preload/video/">在线示例</a>):</p> - -<pre class="brush: html notranslate"><head> - <meta charset="utf-8"> - <title>Video preload example</title> - - <link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4"> -</head> -<body> - <video controls> - <source src="sintel-short.mp4" type="video/mp4"> - <source src="sintel-short.webm" type="video/webm"> - <p>Your browser doesn't support HTML5 video. Here is a <a href="sintel-short.mp4">link to the video</a> instead.</p> - </video> -</body></pre> - -<p>在这个实例中,支持MP4格式的浏览器将仅预加载并使用MP4资源,以使得视频播放器的表现尽可能的流畅,或者说,为用户提供更好的响应。而不支持MP4格式的浏览器仍然能够加载视频的WebM版本,但无法体验到预加载带来的良好体验。这个例子展示了预加载机制如何与渐进式增强的哲学进行有机的结合。</p> - -<h2 id="跨域获取">跨域获取</h2> - -<p>如果你已经有了一个可以正确工作的<a href="/en-US/docs/Web/HTTP/Access_control_CORS">CORS</a>设置,那么你也可以同样成功的预加载那些跨域资源,只需要你在<code><link></code>元素中设置好{{htmlattrxref("crossorigin","link")}}属性即可。</p> - -<p>一个有趣的情况是,如果你需要获取的是字体文件,那么即使是非跨域的情况下,也需要应用这一属性。因为各种各样的原因,这些获取请求必须使用以匿名模式使用CORS(如果你对其中的细节感兴趣,可以查看<a href="https://drafts.csswg.org/css-fonts/#font-fetching-requirements">Font fetching requirements</a>一文)。</p> - -<p>我们将以这个情况作为一个示例——首先是由于字体文件的加载是预加载方面一个好的用例,其次,这也比真正的配置一个跨域请求的例子要简单许多。你可以查看 <a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/fonts">在Github上的示例源代码</a>(也可以查看<a href="https://mdn.github.io/html-examples/link-rel-preload/fonts/">在线示例</a>):</p> - -<pre class="brush: html notranslate"><head> - <meta charset="utf-8"> - <title>Web font example</title> - - <link rel="preload" href="fonts/cicle_fina-webfont.eot" as="font" type="application/vnd.ms-fontobject" crossorigin="anonymous"> - <link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous"> - <link rel="preload" href="fonts/cicle_fina-webfont.woff" as="font" type="font/woff" crossorigin="anonymous"> - <link rel="preload" href="fonts/cicle_fina-webfont.ttf" as="font" type="font/ttf" crossorigin="anonymous"> - <link rel="preload" href="fonts/cicle_fina-webfont.svg" as="font" type="image/svg+xml" crossorigin="anonymous"> - - <link rel="preload" href="fonts/zantroke-webfont.eot" as="font" type="application/vnd.ms-fontobject" crossorigin="anonymous"> - <link rel="preload" href="fonts/zantroke-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous"> - <link rel="preload" href="fonts/zantroke-webfont.woff" as="font" type="font/woff" crossorigin="anonymous"> - <link rel="preload" href="fonts/zantroke-webfont.ttf" as="font" type="font/ttf" crossorigin="anonymous"> - <link rel="preload" href="fonts/zantroke-webfont.svg" as="font" type="image/svg+xml" crossorigin="anonymous"> - - <link href="style.css" rel="stylesheet" type="text/css"> -</head> -<body> - ... -</body></pre> - -<p>你可以看到,在这里,我们不仅通过配置<code>type</code>属性提供了一个MIME类型的暗示,我们也提供了一个<code>crossorigin</code> 属性来处理CORS问题。</p> - -<h2 id="包含媒体">包含媒体</h2> - -<p><code><link></code>元素有一个很棒的特性是它们能够接受一个{{htmlattrxref("media", "link")}}属性。它们可以接受<a href="/en-US/docs/Web/CSS/@media#Media_types">媒体类型</a>或有效的<a href="/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">媒体查询</a>作为属性值,这将令你能够使用响应式的预加载!</p> - -<p>让我们来看一个简单的示例(可以查看<a href="https://github.com/mdn/html-examples/tree/master/link-rel-preload/media">Github上的源代码</a>或<a href="https://mdn.github.io/html-examples/link-rel-preload/media/">在线示例</a>):</p> - -<pre class="brush: html notranslate"><head> - <meta charset="utf-8"> - <title>Responsive preload example</title> - - <link rel="preload" href="bg-image-narrow.png" as="image" media="(max-width: 600px)"> - <link rel="preload" href="bg-image-wide.png" as="image" media="(min-width: 601px)"> - - <link rel="stylesheet" href="main.css"> -</head> -<body> - <header> - <h1>My site</h1> - </header> - - <script> - var mediaQueryList = window.matchMedia("(max-width: 600px)"); - var header = document.querySelector('header'); - - if(mediaQueryList.matches) { - header.style.backgroundImage = 'url(bg-image-narrow.png)'; - } else { - header.style.backgroundImage = 'url(bg-image-wide.png)'; - } - </script> -</body></pre> - -<p>你可以看到我们在<code><link></code>元素中包含了一个<code>media</code>属性,因此,当用户在使用较窄屏幕的设备时,较窄的图片将会被预加载,而在较宽的设备上,较宽的图片将被预加载。然后我们仍需要在header元素上附加合适的图片——通过{{domxref("Window.matchMedia")}} / {{domxref("MediaQueryList")}} 来加以实现(可以查看<a href="/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries">Testing media queries</a>一文来了解更多信息)。</p> - -<p>这一特性将使另一种情况成为可能——字体在随着页面渲染完成的时候即可使用,减少了FOUT (无样式字体闪烁,flash of unstyled text)问题。</p> - -<p>值得注意的是,这一特特性并不仅限于图片,或其他有着同样类型的文件,还有更多想象空间。比如,你可以在用户仅有较窄的屏幕,CPU和带宽资源较为有限的情况下预加载并展示一个简单的SVG图表,而在用户资源较为充裕的时候再去加载一系列复杂的JavaScript文件以显示一个有交互功能的3D模型。</p> - -<h2 id="脚本化与预加载">脚本化与预加载</h2> - -<p>另一项很棒的关于预加载的事情是,如果需要,你可以完全以脚本化的方式来执行这些预加载操作。例如,我们在这里创建一个{{domxref("HTMLLinkElement")}}实例,然后将他们附加到DOM上:</p> - -<pre class="brush: js notranslate"><code class="language-javascript"><span class="keyword token">var</span> preloadLink <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">"link"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> -preloadLink<span class="punctuation token">.</span>href <span class="operator token">=</span> <span class="string token">"myscript.js"</span><span class="punctuation token">;</span> -preloadLink<span class="punctuation token">.</span>rel <span class="operator token">=</span> <span class="string token">"preload"</span><span class="punctuation token">;</span> -preloadLink<span class="punctuation token">.</span><span class="keyword token">as</span> <span class="operator token">=</span> <span class="string token">"script"</span><span class="punctuation token">;</span> -document<span class="punctuation token">.</span>head<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>preloadLink<span class="punctuation token">)</span><span class="punctuation token">;</span> -</code></pre> - -<p>这意味着浏览器将预加载这个JavaScript文件,但并不实际执行它。</p> - -<p>如果要对其加以执行,在需要的时候,你可以执行:</p> - -<pre class="brush: js notranslate"><code class="language-javascript"><span class="keyword token">var</span> preloadedScript <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">"script"</span><span class="punctuation token">)</span><span class="punctuation token">;</span> -preloadedScript<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">"myscript.js"</span><span class="punctuation token">;</span> -document<span class="punctuation token">.</span>body<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>preloadedScript<span class="punctuation token">)</span><span class="punctuation token">;</span> -</code></pre> - -<p>当你需要预加载一个脚本,但需要推迟到需要的时候才令其执行时,这种方式会特别有用。</p> - -<h2 id="其他资源预加载机制">其他资源预加载机制</h2> - -<p>还存在一些其他预加载机制,但没有哪个会比<code><link rel="preload"></code>在大多数情况下更符合你的需要和预期:</p> - -<ul> - <li><code><link rel="prefetch"></code> 已经被许多浏览器支持了相当长的时间,但它是意图预获取一些资源,以备下一个导航/页面使用(比如,当你去到下一个页面时)。这很好,但对当前的页面并没有什么助益。此外,浏览器会给使用<code>prefetch</code>的资源一个相对较低的优先级——与使用<code>preload</code>的资源相比。毕竟,当前的页面比下一个页面相对更加重要。查看<a href="/en-US/docs/Web/HTTP/Link_prefetching_FAQ">Link prefetching FAQ</a>可以了解更多细节。</li> - <li><code><link rel="subresource"></code>被Chrome支持了有一段时间,并且已经有些搔到预加载当前导航/页面(所含有的资源)的痒处了。但它有一个问题——没有办法处理所获取内容的优先级(<code>as</code>也并不存在),所以最终,这些资源会以一个相当低的优先级被加载,这使得它能提供的帮助相当有限。</li> - <li>除以上这些以外,还有大量的基于脚本的资源加载器。但这些加载器对于浏览器的加载优先级队列完全束手无策,这也使得他们不得不屈服于同样的性能问题。</li> -</ul> - -<h2 id="Specifications" name="Specifications">相关规范/草案</h2> - -<table class="standard-table"> - <thead> - <tr> - <th scope="col">Specification</th> - <th scope="col">Status</th> - <th scope="col">Comment</th> - </tr> - </thead> - <tbody> - <tr> - <td>{{SpecName('Preload','#x2.link-type-preload','preload')}}</td> - <td>{{Spec2('Preload')}}</td> - <td><code>preload</code> 的更多详情</td> - </tr> - <tr> - <td>{{SpecName('HTML WHATWG', '#link-type-preload', 'rel=preload')}}</td> - <td>{{Spec2('HTML WHATWG')}}</td> - <td><code>rel=preload</code> 的定义</td> - </tr> - </tbody> -</table> - -<h2 id="浏览器兼容性">浏览器兼容性</h2> - -<div>{{CompatibilityTable}}</div> - -<div id="compat-desktop"> -<table class="compat-table"> - <tbody> - <tr> - <th>Feature</th> - <th>Chrome</th> - <th>Firefox (Gecko)</th> - <th>Internet Explorer</th> - <th>Opera</th> - <th>Safari</th> - </tr> - <tr> - <td>Basic support</td> - <td>{{CompatChrome(50.0)}}</td> - <td>{{CompatGeckoDesktop("56")}}<sup>[1]</sup></td> - <td>{{CompatNo}}</td> - <td>47</td> - <td>11</td> - </tr> - </tbody> -</table> -</div> - -<div id="compat-mobile"> -<table class="compat-table"> - <tbody> - <tr> - <th>Feature</th> - <th>Android</th> - <th>Android Webview</th> - <th>Firefox Mobile (Gecko)</th> - <th>IE Mobile</th> - <th>Opera Mobile</th> - <th>Safari Mobile</th> - <th>Chrome for Android</th> - </tr> - <tr> - <td>Basic support</td> - <td>{{CompatAndroid(56)}}</td> - <td>{{CompatChrome(50.0)}}</td> - <td>{{CompatGeckoMobile("56")}}<sup>[1]</sup></td> - <td>{{CompatNo}}</td> - <td>{{CompatVersionUnknown}}</td> - <td>11</td> - <td>{{CompatChrome(50.0)}}</td> - </tr> - </tbody> -</table> -</div> - -<p>[1] Firefox支持对于如下内容的预加载({{htmlattrxref("as","link")}}属性的有效值)—— <code>script</code>,<code>style</code>,<code>image</code>,<code>video</code>,<code>audio</code>,<code>track</code>,<code>font</code>, 以及 <code>fetch</code>。关于所支持的字体类型的预加载被定义在<a href="https://www.iana.org/assignments/media-types/media-types.xhtml#font">fonts media type list</a> 中(注意,<code>font/collection</code>不被支持)。同样需要注意的是,当前的Firefox仅支持可缓存资源的预加载。</p> - -<h2 id="其他参考">其他参考</h2> - -<ul> - <li><a href="https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/">Preload: What Is It Good For?</a> by Yoav Weiss</li> -</ul> |