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

BCD tables only load in the browser

Veja também