CSS que bloqueia a renderização

Ilya Grigorik
Ilya Grigorik

Publicado em 31 de março de 2014

Por padrão, o CSS é tratado como um recurso bloqueador de renderização. Isso significa que o navegador não renderiza nenhum conteúdo processado até que o CSSOM seja construído. Mantenha seu CSS enxuto, entregue-o o mais rápido possível e use tipos de mídia e consultas para desbloquear a renderização.

Na construção da árvore de renderização, vimos que o caminho crítico de renderização exige que o DOM e o CSSOM construam a árvore de renderização. Isso gera impacto importante no desempenho: tanto o HTML quanto o CSS são recursos bloqueadores de renderização. O HTML é óbvio, pois sem o DOM não teríamos nada para renderizar, mas a exigência do CSS pode ser menos óbvia. O que acontece se tentarmos renderizar uma página normal sem que o CSS bloqueie a renderização?

Resumo

  • Por padrão, o CSS é tratado como um recurso bloqueador de renderização.
  • Os tipos e consultas de mídia nos permitem marcar alguns recursos CSS como não bloqueadores de renderização.
  • O navegador faz o download de todos os recursos CSS, independentemente do comportamento com ou sem bloqueio.
NYTimes com CSS
The New York Times com CSS
NYTimes sem CSS
The New York Times sem CSS (FOUC)

O exemplo anterior, que mostra o site do New York Times com e sem CSS, demonstra por que a renderização é bloqueada até que o CSS esteja disponível. Sem o CSS, a página fica relativamente inutilizável. A experiência à direita é frequentemente chamada de relâmpago de conteúdo não estilizado (FOUC, na sigla em inglês). O navegador bloqueia a renderização até que tenha tanto o DOM quanto o CSSOM.

O CSS é um recurso bloqueador de renderização. Leve-o ao cliente o quanto antes para otimizar o tempo da primeira renderização.

Porém, e se temos alguns estilos CSS que são usados somente em determinadas circunstâncias, por exemplo, quando a página está sendo exibida ou projetada em um monitor maior? Seria bom se não precisássemos bloquear a renderização nesses recursos.

Os "tipos de mídia" e as "consultas de mídia" do CSS permitem resolver estes casos de uso:

<link href="style.css" rel="stylesheet" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="other.css" rel="stylesheet" media="(min-width: 40em)" />

Uma consulta de mídia consiste em um tipo de mídia e zero ou mais expressões que verificam as condições de determinados recursos de mídia. Por exemplo, a primeira declaração da nossa folha de estilo não fornece um tipo ou consulta de mídia. Por isso, ela se aplica a todos os casos, o que, em outras palavras, significa que sempre haverá bloqueio de renderização. Por outro lado, a segunda declaração da folha de estilo é aplicada apenas quando o conteúdo está sendo impresso. Talvez você queira reorganizar o layout, mudar as fontes e outras considerações importantes de design para impressão. Portanto, essa declaração da folha de estilo não precisa bloquear a renderização da página quando ela é carregada pela primeira vez. Por fim, a última declaração da folha de estilo traz uma "consulta de mídia", que é executada pelo navegador. Se as condições forem atendidas, o navegador bloqueará a renderização até que a folha de estilo seja baixada e processada.

Usando consultas de mídia, podemos adaptar a apresentação a casos de uso específicos, como exibição ou impressão, bem como para condições dinâmicas, como alterações na orientação da tela e eventos de redimensionamento, entre outros. Ao declarar os recursos da folha de estilo, preste muita atenção ao tipo de mídia e às consultas, porque eles afetam muito o desempenho do caminho crítico de renderização.

Considere estes exemplos:

<link href="style.css" rel="stylesheet" />
<link href="style.css" rel="stylesheet" media="all" />
<link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
<link href="print.css" rel="stylesheet" media="print" />
  • A primeira declaração bloqueia a renderização e atende a todas as condições.
  • A segunda declaração também bloqueia a renderização: "all" é o tipo padrão. Se você não especificar um tipo, ele será definido implicitamente como "all". Portanto, a primeira e a segunda declarações são, na verdade, equivalentes.
  • A terceira declaração tem uma consulta de mídia dinâmica, que é avaliada quando a página é carregada. Dependendo da orientação do dispositivo durante o carregamento da página, portrait.css pode bloquear a renderização ou não.
  • A última declaração só é aplicada quando a página está sendo impressa ("print"). Portanto, não bloqueia a renderização quando a página é carregada pela primeira vez no navegador.

Por fim, observe que "bloqueador de renderização" indica apenas se o navegador tem que suspender a renderização inicial da página durante a execução desse recurso. Em todo caso, o navegador ainda baixa o ativo CSS, embora com menor prioridade para os recursos não bloqueadores.

Feedback