Subterranean Flower

link要素によるResource Hintsを使用してリソースの先読みを行う

Author
古都こと
ふよんとえんよぷよぐやま!!!

ウェブサイトの読み込み最適化は、開発者たちを悩ませる永遠の課題です。特にページ遷移時の読み込みに関しては、開発者側からなかなか手を出せない状態でした。そんな状況も、Resource Hintsを使えば大きく変わります。

Resouce Hints

Resource Hintsはlink要素を利用したリソース先読みのための仕組みです。使い方は簡単で、head要素内に、該当するlink要素を置くだけでブラウザが自動的に読み込みを行ってくれます。

<link rel="dns-prefetch" href="//example.com">

Resource Hintsの種類は以下の4種類で、状況によって使い分けることができます。

  • dns-prefetch
  • preconnect
  • prefetch
  • prerender

対応ブラウザ

対応ブラウザに関しては、現在のところあまり多くはありません。詳しくはcaniuseのResource Hintsをご覧ください。

dns-prefetch

dns-prefetchは事前に名前解決を行うためのResource Hintsです。

<link rel="dns-prefetch" href="//example.com">

link要素を複数並べることで、複数のdns-prefetchが可能です。CDNなど、事前に接続することがわかっている場面で使用することができるでしょう。

preconnect

preconnectはdns-prefetchに加え、TCPのハンドシェイク、TLSのネゴシエーションなどを行います。

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

複数のpreconnectが可能です。クロスオリジンのpreconnectも可能です。

crossorigin属性には以下の値が指定できます:

  • anonymous
  • use-credentials

単にcrossoriginとだけ書いた場合は、crossorigin=”anonymous”と同じです。

prefetch

prefetchはpreconnectの更に先を行き、リソースの取得を実際に行います。

<link rel="prefetch" href="//example.com/next-page.html" as="html" crossorigin="use-credentials">
<link rel="prefetch" href="/library.js" as="script">

複数のprefetchが可能です。内容があらかじめ定まっている、静的であるコンテンツに対して使用すると有効でしょう。クロスオリジンのprefetchも可能です。

as属性はオプションであり、指定する必要はありませんが、指定しておけばブラウザにとって最適化しやすくなるでしょう。

指定できるas属性の値の一部を、以下に示します:

  • audio
  • video
  • track
  • script
  • style
  • font
  • image
  • fetch
  • worker
  • embed
  • object(object要素で使用するオブジェクト)
  • document(iframe要素で使用するページ)

全ての値を見たい場合は、Fetch APIの仕様をご覧ください。

prerender

prerenderはページのすべてのリソースをprefetchし、バックグラウンドでページの描画までを行います。これによりユーザ側からするとprerenderしたページへの遷移は瞬時に終わったように見えます。

<link rel="prerender" href="//example.com/next-page.html">

なお、一般的なブラウザではprerenderの対象は1ページまでに制限されています。また、長い時間アクセスしなかった場合などにはレンダリングが破棄される可能性もあります。

pr属性

Resource Hintsにはprobability(使用する可能性)を表すpr属性を指定することができます。pr属性が割り当てられていると、それに従いブラウザが先読みの最適化をすることができます。

<link rel="dns-prefetch" href="//widget.com" pr="0.75">
<link rel="preconnect" href="//cdn.example.com" pr="0.42">
<link rel="prefetch" href="//example.com/next-page.html" pr="0.75">
<link rel="prerender" href="//example.com/thankyou.html" pr="0.25">

pr属性を省略すると、ブラウザが独自にpr値を割り当てます。

また、prに1.0を指定しても、必ずしもブラウザによって先読みが実行されるとは保証できません。

link rel=”preload”

Resource Hintsと似た機能に、preloadというものがあります。これはResource Hintsのprefetchと似たような使い方をすることができます。

<link rel="preload" href="/assets/font.woff2" as="font" type="font/woff2">
<link rel="preload" href="/style/other.css" as="style">
<link rel="preload" href="//example.com/resource" as="fetch" crossorigin>
<link rel="preload" href="https://fonts.example.com/font.woff2" as="font" crossorigin type="font/woff2">

preloadはResource Hintsのprefetchとは、実行されるタイミングおよび優先度が異なります。prefetchは優先度の低い先読みで、「おそらく次のページで必要になるであろうリソースだと思われる」を表します。一方preloadは優先度が高く「現在のページで”必ず”必要になるリソース」を表します。

次のページで必要になる場合はprefetch、現在のページで必ず必要になる場合はpreloadを使うといいでしょう。「現在のページ」で必要になるリソースは、例えば画像やフォントなどが挙げられます。

各ブラウザの対応状況はcaniuseのpreloadの項目をご覧ください。

JavaScriptからの利用

現在、Resource Hintsおよびpreloadは、JavaScript側から利用可能なAPIは用意されていません。そのため、JavaScriptから動的に利用するためには、link要素を作りhead要素に追加する必要があります。

var hint = document.createElement("link");
hint.rel = "prefetch";
hint.as = "html";
hint.href = "/article/part3.html";
document.head.appendChild(hint);

ここではprefetchの例を示しましたが、他のrelの種類でも可能です。