Preloading content with rel="preload"

O valor preload do atributo rel do elemento <link> permite que você escreva solicitações de busca declarativas em seu elemento <head> do HTML, especificando recursos que suas páginas vão precisar logo após o carregamento. Você também pode querer que estes recursos sejam pré-carregados no início do ciclo de vida da página e depois que o mecanismo de renderização do navegador comece a agir. Isso garante que estarão disponíveis mais cedo e que seja menos provável que sua página seja bloqueada do processo de renderizar. Isso aumenta a performance da página. Este artigo oferece um guia básico de como preload funciona.

O básico

Você comumente usa o elemento <link> quando carrega um arquivo de estilo CSS para sua pagina com:

<link rel="stylesheet" href="styles/main.css">

No entanto, aqui nós usamos rel com valor preload, que transforma o elemento <link> em um preloader para praticamente qualquer recurso que você precisar. Você também precisa especificar

  • o caminho para o recurso a ser pré-carregado, no atributo href
  • o tipo de recurso que vc esta pré-carregando, no atributo as.

Um exemplo simples pode se parecer com o seguinte (veja seus JS and CSS example source, e also live):

<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>

Aqui estamos pré-carregando seus arquivos CSS e JavaScript de forma que estarão disponíveis assim que forem necessários mais tarde durante a renderização da página. Este exemplo é um pouco trivial, visto que o browser provavelmente descobre os elementos <link rel="stylesheet">  e <script> no mesmo pedaço de HTML que os preloads, mas o benefício pode ser visto mais claramente, quanto mais tarde os recursos são descobertos e quanto maiores forem eles. Por exemplo:

  • Os recursos apontados de dentro de um arquivo CSS, como fontes ou imagens;
  • Recursos que podem ser solicitados pelo JavaScript, como JSON, scripts importados ou web workers;
  • Imagens maiores e arquivos de vídeo.

preload também possui outras vantagens. Usando o atributo as para especificar o tipo de conteúdo a ser pre-carregado permite que o browser:

  • Priorize o carregamento de recursos com maior precisão;
  • Corresponda solicitações futuras, reutilizando o mesmo recurso, se apropriado;
  • Aplique a content security policy adequada ao recurso;
  • Defina os cabeçalhos corretos de Accept.

Qual tipo de conteúdo pode ser pré-carregado?

Muitos diferentes tipos de conteúdo podem ser pré-carregados. Os valores possíveis para o atributo as são os seguintes:

  • audio: Arquivo de áudio, como usados geralmente em <audio> .
  • document: Um documento HTML destinado a ser incorporado dentro de um <frame> ou <iframe>.
  • embed: Recurso destinado a ser incorporado dentro de um elemento <embed>.
  • fetch: Recurso a ser acessado por um fetch ou XHR request, como um ArrayBuffer ou arquivo JSON.
  • font: Arquivo de fonte.
  • image: Arquivo de imagem.
  • object: Recurso a ser incorporado dentro de um elemento <object>.
  • script: Arquivo JavaScript.
  • style: Estilo CSS.
  • track: Arquivo webVTT.
  • worker: Um web worker JavaScript ou shared worker.
  • video: Arquivo de vídeo, usualmente usado em <video> .

Nota: Você pode ler um pouco mais sobre estes valores e os recursos da web que eles esperam consumir na especificação Preload — veja link element extensions. Observe também que a lista completa de valores que o atributo as  pode assumir é regida pelas definiçoes nas especificaçoes Fetch — veja request destinations.

Incluindo um tipo MIME

<link> pode aceitar um atributo type, o qual contém o MIME type do recurso para o qual o elemento está apontando. Isto é especialmente útil quando pre-carregando recursos — o browser usará o valor do atributo type para trabalhar se ele suportar o recurso, e irá somente iniciar o carregamento se este for o caso, ignorando se não for.

Você pode ver um exemplo disto no nosso exemplo de video (veja o full source code, e também the live version):

<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>

Então neste caso, navegadores que suportem MP4s vão pré-carregar e usar MP4, fazendo o reprodutor de video esperançosamente mais suave/mais responsivo para os usuários. Browsers que não suportem MP4 podem continuar carregando versao WebM, mas não tem as vantagens do pré-carregamento. Isto mostra como conteudo pré-carregado pode ser combinado com a filosofia de aprimoramento progressivo.

Buscas de origem cruzada

Se você tem no seu site as configurações de CORS funcionando corretamente, você pode pré-carregar com sucesso recursos de origem cruzada, desde que você defina um atributo crossorigin no seu elemento <link>.

Um caso interessante em que isso se aplica mesmo se a busca não é de origem cruzada é arquivos de fonte. Por várias razões, elas precisam ser buscadas usando o modo anônimo CORS (veja Font fetching requirements se você esta interesado em todos os detalhes).

Vamos usar este caso como um exemplo, em primeiro lugar porque o carregamento de fontes é realmente um bom caso de uso para pré-carregamento e, em segundo lugar, porque é mais fácil do que configurar um exemplo de solicitação de origem cruzada. Voce pode ver o exemplo completo no source code on GitHub (also see it live):

<head>
  <meta charset="utf-8">
  <title>Web font example</title>

  <link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">
  <link rel="preload" href="fonts/zantroke-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">

  <link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
  ...
</body>

Você verá aqui que não apenas estamos fornecendo as dicas do tipo MIME nos atributos de tipo, mas também estamos fornecendo o atributo  crossorigin para lidar com os problemas de CORS..

Adicionando media

Um bom recurso de alemento <link> é sua abilidade de aceitar atributos media. Estes podem aceitar media types ou full-blown media queries, permitindo que você faça o pré-carregamento responsivo!

Vamos ver um exemplo simples (see it on GitHub — source codelive example):

<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>

Você verá que estamos incluindo atributos de mídia em nossos <link> elementos, de modo que um estreita imagem é pre-carregada se o usuario estiver em um dispositivo de tela estreita, e uma imagem mais ampla é carregada se eles estiverem em um dispositivo de tela maior. Ainda precisamos anexar a imagem correta ao cabeçalho, dependendo do resultado — nos usamos Window.matchMedia / MediaQueryList para fazer isso (veja Testing media queries para mais informaçoes sobre isso).

Isso torna muito mais provável que a fonte estará disponível no momento em que a renderização da página for concluída, reduzindo os problemas de FOUT (flash de texto sem estilo).

Note que isso não precisa ser limitado a imagens, ou até mesmo arquivos do mesmo tipo - pense grande! Talvez você pré-carregue e exiba um diagrama SVG simples se o usuário estiver em uma tela estreita em que a largura de banda e CPU é potencialmente mais limitada ou pré-carregue um bloco complexo de JavaScript e use-o para renderizar um modelo 3D interativo se os recursos do usuário forem mais abundantes.

Scripting and preloads

Outra coisa legal sobre preloads é que você pode executá-los completamente com script, se desejar. Por exemplo, aqui estamos criando uma instancia HTMLLinkElement, em seguida anexando-o ao DOM:

var preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);

Isso significa que o navegador pré-carregará o arquivo JavaScript, mas ainda não o utilizará.

Para usalo, você poderia fazer isso quando desejado:

var preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);

Isso é útil quando você deseja pré-carregar um script, mas adia executá-lo até exatamente quando precisar.

Outros mecanismos de pré-carregamento de recursos

Existem outros recursos de pré-carregamento, mas nenhum é tão adequado ao propósito  <link rel="preload">:

  • <link rel="prefetch">
    tem sido suportado nos navegadores por um longo tempo, mas destina-se à pré-busca de recursos que serão usados ​​na próxima navegação / carregamento da página (por exemplo, quando você vai para a próxima página). Isso é bom, mas não é útil para a página atual! Além disso, os navegadores darão aos recursos de pré-busca uma prioridade menor que os pré-carregados - a página atual é mais importante que a próxima. veja Link prefetching FAQ para mais detalhes.
  • <link rel="prerender"> 

    é usado para renderizar a página da Web especificada em segundo plano, acelerando o carregamento da página se o usuário navegar para ela. Devido ao potencial de desperdiçar largura de banda dos usuários, Chrome trataprerender como um NoState prefetch.

  • <link rel="subresource"> 

    foi suportado no Chrome há algum tempo e tinha a intenção de lidar com recursos de pré-carregamento para o carregamento da página / navegação atual, mas tinha um problema - não havia como calcular uma prioridade para buscar os itens (como não existia naquela época ), então todos acabaram sendo buscados com pouca prioridade, o que não ajudou a situação.

  • Há vários carregadores de recursos baseados em script disponíveis, mas eles não têm nenhum poder sobre a fila de priorização de busca do navegador e estão sujeitos aos mesmos problemas de desempenho.

Especificações

Specification Status Comment
Preload
The definition of 'preload' in that specification.
Candidata a Recomendação mais detalhes sobre  preload.
HTML Living Standard
The definition of 'rel=preload' in that specification.
Padrão em tempo real definições de rel=preload.

Compatibilidade de Browser

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
preload
Experimental
Chrome Full support 50Edge Full support ≤79Firefox No support 56 — 57
Notes
No support 56 — 57
Notes
Notes Disabled due to various web compatibility issues (e.g. bug 1405761).
IE ? Opera Full support 37Safari ? WebView Android Full support 50Chrome Android Full support 50Firefox Android No support 56 — 57
Notes
No support 56 — 57
Notes
Notes Disabled due to various web compatibility issues (e.g. bug 1405761).
Opera Android ? Safari iOS ? Samsung Internet Android Full support 5.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
See implementation notes.
See implementation notes.

Veja também