No módulo anterior, alguma teoria por trás do caminho crítico de renderização era e como os recursos bloqueadores de renderização e de análise podem atrasar um a renderização inicial da página. Agora que você entende um pouco da teoria por trás você já pode aprender algumas técnicas para otimizar os recursos caminho de renderização.
Conforme uma página é carregada, muitos recursos são referenciados no HTML, que fornecem uma página com sua aparência e layout através de CSS, bem como sua interatividade por meio de JavaScript. Neste módulo, vamos abordar vários conceitos importantes relacionados esses recursos e como eles afetam o tempo de carregamento da página são abordados.
Bloqueio de renderização
Como discutimos no módulo anterior, o CSS é um recurso de render-blocking, já que impede que o navegador renderize conteúdo até que o modelo de objetos CSS (CSSOM). O navegador bloqueia a renderização para evitar que um Flash de Conteúdo sem estilo (FOUC, na sigla em inglês), que não é desejável do ponto de vista da experiência do usuário.
No vídeo anterior, há um breve FOUC em que você pode ver a página sem qualquer estilo. Posteriormente, todos os estilos serão aplicados assim que o CSS da página carregado da rede, e a versão sem estilo da página está imediatamente substituída pela versão estilizada.
De modo geral, um FOUC não é comum, mas o conceito é importante entender para que você saiba por que o navegador bloqueia a renderização da página até que o CSS seja baixado e aplicado à página. Bloqueio de renderização não é necessariamente indesejável, mas você quer minimizar a duração dela em manter seu CSS otimizado.
Bloqueio do analisador
Um recurso que bloqueia o analisador interrompe o analisador HTML, como um <script>
sem os atributos async
ou defer
. Quando o analisador encontra um
<script>
, o navegador precisa avaliar e executar o script antes de
prosseguir com a análise do restante do HTML. Isso ocorre por padrão, pois os scripts podem
modificar ou acessar o DOM durante um período enquanto ele ainda está sendo construído.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Ao usar arquivos JavaScript externos (sem async
ou defer
), o analisador é
bloqueada desde quando o arquivo é descoberto até que ele seja baixado, analisado e
executada. Ao usar JavaScript inline, o analisador é bloqueado de forma semelhante até
o script in-line é analisado e executado.
O leitor de pré-carregamento
A verificação de pré-carregamento é uma otimização do navegador na forma de um HTML secundário
que analisa a resposta HTML bruta para localizar e buscar, de forma especulativa,
recursos antes que o analisador HTML primário os descubra. Para
exemplo, o scanner de pré-carregamento permitiria ao navegador iniciar o download de um
recurso especificado em um elemento <img>
, mesmo quando o analisador HTML está bloqueado
ao buscar e processar recursos como CSS e JavaScript.
Recursos essenciais devem ser incluídos para usar a verificação de pré-carregamento na marcação HTML enviada pelo servidor. Os seguintes padrões de carregamento de recursos são detectável pelo verificador de pré-carregamento:
- Imagens carregadas pelo CSS usando a propriedade
background-image
. Essas imagens referências estão em CSS e não podem ser descobertas pelo scanner de pré-carregamento. - Scripts carregados dinamicamente na forma da marcação de elemento
<script>
injetada no DOM usando JavaScript ou módulos carregados usandoimport()
dinâmica. - HTML renderizado no cliente usando JavaScript. Essa marcação está contida em strings em recursos JavaScript e não é detectável pelo pré-carregamento de leitura.
- Declarações
@import
de CSS.
Todos esses padrões de carregamento de recursos são
descobertos tardiamente e, portanto,
não se beneficiem do scanner de pré-carregamento. Evite-os sempre que possível. Se
evitar esses padrões não é possível. No entanto, você pode usar uma
Dica preload
para evitar atrasos na descoberta de recursos.
CSS
O CSS determina a apresentação e o layout de uma página. Conforme descrito anteriormente, o CSS é um recurso bloqueador de renderização. Otimizar o CSS pode ter um impacto o impacto no tempo total de carregamento da página.
Minificação
Reduzir arquivos CSS reduz o tamanho do arquivo de um recurso CSS, tornando-os mais rápidos para fazer o download. Isso é conseguido principalmente pela remoção de conteúdo de um arquivo CSS de origem, como espaços e outros caracteres invisíveis, e a saída o resultado para um arquivo recém-otimizado:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
Em sua forma mais básica, a minificação de CSS é uma otimização eficaz que pode melhorar a FCP do site e, quem sabe, a LCP em alguns casos. Ferramentas como bundlers podem realizar automaticamente essa otimização para você na produção builds.
Remover CSS não usado
Antes de renderizar qualquer conteúdo, o navegador precisa fazer o download e analisar todos folhas de estilo. O tempo necessário para concluir a análise também inclui estilos que não são usados na página atual. Se você estiver usando um bundler que combina todos os CSSs recursos em um único arquivo, é provável que os usuários façam o download de mais CSS do que necessárias para renderizar a página atual.
Para descobrir um CSS não usado na página atual, use a ferramenta de cobertura no Chrome. do DevTools.
![Uma captura de tela da ferramenta de cobertura no Chrome DevTools. Um arquivo CSS está selecionado no painel inferior, mostrando uma quantidade considerável de CSS não utilizada pelo layout da página atual.](https://web.dev/static/learn/performance/optimize-resource-loading/image/fig-1.png?authuser=19&hl=pt-br)
A remoção de CSS não utilizado tem dois efeitos: além de reduzir o download tempo, você está otimizando a construção da árvore de renderização, já que o navegador precisa processar menos regras CSS.
Evitar declarações @import
de CSS
Embora possa parecer conveniente, evite declarações @import
no CSS:
/* Don't do this: */
@import url('style.css');
Da mesma forma que o elemento <link>
funciona em HTML, a declaração @import
no CSS permite importar um recurso CSS externo de uma folha de estilo. A
a principal diferença entre essas duas abordagens é que o elemento HTML <link>
faz parte da resposta HTML e, portanto, foi descoberto muito antes
arquivo transferido por download por uma declaração @import
.
Isso acontece porque, para que uma declaração @import
seja
descoberto, é necessário primeiro fazer o download do arquivo CSS que o contém. Isso
resulta no conhecido como cadeia de solicitações que, no caso do CSS, causará atrasos.
quanto tempo leva para uma página ser renderizada inicialmente. Outra desvantagem é que
as folhas de estilo carregadas usando uma declaração @import
não podem ser descobertas pelo
o scanner de pré-carregamento e, portanto, se tornam recursos de bloqueio de renderização descobertos tardiamente.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Na maioria dos casos, é possível substituir o @import
usando uma
<link rel="stylesheet">
. Os elementos <link>
permitem que as folhas de estilo sejam
transferidos simultaneamente e reduz o tempo total de carregamento, em oposição ao @import
que fazem o download das folhas de estilo consecutivamente.
CSS essencial inline
O tempo necessário para fazer o download dos arquivos CSS pode aumentar a FCP da página. In-line
estilos importantes no documento <head>
elimina a solicitação de rede para uma
recurso CSS e, quando feito corretamente, pode melhorar os tempos de carregamento iniciais quando uma
o cache do navegador do usuário não está preparado. O CSS restante pode ser carregado
de forma assíncrona ou anexada ao final do elemento <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
Como desvantagem, colocar uma grande quantidade de CSS em linha adiciona mais bytes ao arquivo Resposta HTML. Como os recursos HTML muitas vezes não podem ser armazenados em cache por muito tempo — ou tudo. Isso significa que o CSS embutido não é armazenado em cache para páginas subsequentes que possam usar o mesmo CSS em folhas de estilo externas. Teste e avalie o desempenho desempenho para garantir que compensações valem o esforço.
Demonstrações de CSS
JavaScript
O JavaScript gera a maior parte da interatividade na Web, mas isso tem um custo. Enviar muito JavaScript pode fazer com que sua página da Web demore para responder durante carregamento e pode até causar problemas de capacidade de resposta que atrasam as interações, o que pode ser frustrante para os usuários.
JavaScript bloqueador de renderização
Ao carregar elementos <script>
sem os atributos defer
ou async
, os
o navegador bloqueia a análise e a renderização até que o script seja baixado, analisado e
executada. Da mesma forma, os scripts inline bloqueiam o analisador até que o script seja analisado
e executados.
async
x defer
async
e defer
permitem que scripts externos sejam carregados sem bloquear o HTML.
analisador enquanto os scripts (incluindo scripts inline) com type="module"
estão
adiado automaticamente. No entanto, async
e defer
têm algumas diferenças que
é importante de entender.
Os scripts carregados com async
são analisados e executados imediatamente após o download.
enquanto os scripts carregados com defer
são executados quando a análise do documento HTML é
concluído, isso ocorre ao mesmo tempo que o evento DOMContentLoaded
do navegador.
Além disso, os scripts async
podem ser executados fora de ordem, enquanto os scripts defer
são executadas na ordem em que aparecem na marcação.
Renderização do cliente
De modo geral, evite usar JavaScript para renderizar conteúdos críticos ou elemento da LCP da página. Isso é conhecido como renderização pelo cliente e é uma técnica muito usada em aplicativos de página única (SPAs).
A marcação renderizada pelo JavaScript evita o verificador de pré-carregamento, enquanto os recursos contidas na marcação renderizada pelo cliente não são detectáveis por ela. Isso atrasar o download de recursos cruciais, como uma imagem da LCP. O navegador só começa a fazer o download da imagem da LCP depois que o script é executado e adicionado o elemento ao DOM. Por sua vez, o script só pode ser executado depois de descobertos, baixados e analisados. Isso é conhecido como solicitação crítica em cadeia e precisam ser evitados.
Além disso, a renderização da marcação usando JavaScript tem maior probabilidade de gerar tarefas longas do que a marcação baixada do servidor em resposta a uma solicitação de navegação solicitação. O uso extensivo da renderização de HTML pelo cliente pode afetar negativamente latência de interação. Isso é especialmente verdadeiro nos casos em que o DOM de uma página é muito grande, o que aciona um trabalho de renderização significativo quando o JavaScript modifica ao DOM.
Minificação
Semelhante ao CSS, a redução de JavaScript reduz o tamanho do arquivo do recurso de script. Isso pode levar a downloads mais rápidos, permitindo que o navegador vá para a de análise e compilação de JavaScript mais rapidamente.
Além disso, a minificação de JavaScript vai um passo além da minificação. outros recursos, como CSS. Quando o JavaScript é reduzido, ele não é apenas removido como espaços, tabulações e comentários, mas símbolos na fonte JavaScript são encurtadas. Esse processo é conhecido como uglificação. Para para ver a diferença, use o seguinte código-fonte JavaScript:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Quando o código-fonte JavaScript anterior for uglificado, o resultado poderá parecer parecido com este snippet de código:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
No snippet anterior, é possível ver que a variável legível
scriptElement
na origem é encurtado para t
. Quando aplicada em uma grande
de scripts, as economias podem ser consideráveis, sem afetar
recursos que o JavaScript de produção de um site fornece.
Se você estiver usando um bundler para processar o código-fonte de seu site, a uglificação isso geralmente é feito de modo automático em builds de produção. Upentes, como Terser, por exemplo, também são altamente configuráveis, o que permite ajustar o agressividade do algoritmo de uglificação para conseguir o máximo de economia. No entanto, os padrões de qualquer ferramenta de unificação geralmente são suficientes para causar o equilíbrio certo entre tamanho da saída e preservação de recursos.
Demonstrações de JavaScript
Teste seus conhecimentos
Qual é a melhor forma de carregar vários arquivos CSS no navegador?
@import
.<link>
.O que o verificador de pré-carregamento do navegador faz?
<link rel="preload">
em
um recurso HTML.
Por que o navegador bloqueia temporariamente a análise de HTML por padrão quando fazer o download de recursos JavaScript?
A seguir: como ajudar o navegador com dicas de recursos
Agora que você sabe como os recursos carregados no elemento <head>
podem
afetar o carregamento inicial da página e várias métricas, é hora de prosseguir. Nos próximos
exploramos as dicas de recursos e como elas dão dicas valiosas para
no navegador para começar a carregar recursos e abrir conexões para
servidores antes do que o navegador faria sem eles.