Preço caro de estilos. Relatório Yandex

Carregar CSS em uma página é uma operação de bloqueio. Se o carregamento assíncrono do JavaScript não estiver visível para o usuário, a aparência lenta dos estilos poderá expulsar um visitante impaciente do site. Como carregar CSS da maneira mais eficiente e transparente possível para os usuários? Nikita Dubko está tentando descobrirDarkMeFoDy do grupo de interface de pesquisa Yandex em Minsk.


- Olá a todos. Vou falar sobre os estilos. Todo mundo está falando sobre TypeScript e TypeScript hoje. E eu vou falar sobre o script estilo Cascade.

Pouco sobre mim. Sou desenvolvedor da Bielorrússia - depois do filme Dudya, digo isso em todos os lugares. Você pode ter ouvido minha voz no podcast de padrões da Web e, se você encontrar erros de digitação no feed de notícias dos padrões da Web, provavelmente sou eu também.

Pouco aviso. Haverá várias insanidades no relatório - trate tudo o que digo com grandes críticas. Pense por que você pode usar essas técnicas e por que não precisa delas. Algumas coisas serão realmente loucas. Vai.

Pelo que?


Para começar - por que falar sobre otimização de CSS?

Se você começar a procurar nos mecanismos de pesquisa downloads rápidos de JS, há muitos resultados. Se você procura um carregamento rápido de CSS, a parte superior nem exibe o CSS necessário.



Se você olhar para o Google, existem 111 milhões de resultados sobre JS e CSS, apenas 26 milhões,

então talvez isso não importe? Por que falar sobre isso? Se você procurar relatórios de desempenho JS, encontrará muitos deles. Há sobre React, sobre todos os tipos de outras estruturas, sobre Vanilla, etc. Mas sobre CSS, encontrei apenas um relatório. Harry Roberts em 2018 leu um relatório interessante sobre o desempenho do CSS. Eu pensei ter encontrado um segundo relatóriopor Roma Dvornova, “CSS Parsim: dicas e truques de desempenho”. Mas acabou sendo um relatório JS que analisa CSS. Não é exatamente o que precisamos.

Acontece que eles não pensam muito em CSS. É uma vergonha.

Mas quando vou para a web, geralmente vejo HTML. E também vejo CSS que estiliza a página. Mas eu não vejo JS. JS é algo que move CSS e HTML em uma página para deixar tudo bonito. Este é um script. E se o JS não carregar, não será tão ruim quanto se o CSS não carregar.

Erros no JS caem silenciosamente no console. E é improvável que o usuário comum entre no DevTools para procurar: "Ah, você está aí, um erro no console". Mas se o CSS não carregar, talvez você não veja tudo o que precisa.

A propósito, existem estudos sobre o fato de que o principal é causar uma primeira impressão.38% dos usuários podem acessar o site e, se perceberem que é diretamente nojento, sairão imediatamente. E 88% vão tolerar, usá-lo uma vez e, em seguida, eles nunca retornam e dificilmente aconselharão seu site.

Agora que estamos todos sentados em casa, o tráfego da Internet aumentou especialmente. E precisamos pensar em como fornecer com eficiência quaisquer recursos aos usuários.

Vamos tentar contar do ponto de vista do Yandex. Se pudermos otimizar cada entrega do Yandex por 100 ms e fornecer, digamos, 200 milhões de páginas por dia (não sei o número exato), neste dia economizaremos 0,1 s * 200 milhões = 232 pessoas-dia. Apenas otimizando a saída por 100 milissegundos. E CSS também faz isso.

Vamos jogar um pouco de detetives e descobrir como tirar o máximo proveito dos estilos de carregamento.

A medida!


O primeiro conselho é sempre medir tudo. Não há sentido em fazer otimizações teoricamente. Você pode supor que a otimização funcione no seu caso, mas medições reais mostrarão que nada disso. Essa é a regra mais importante de qualquer otimização. Andrei Prokopyuk, da equipe SERP Velocity do HolyJS, falou muito bem sobre como fazemos isso , não vou me repetir.

Quais ferramentas de medição existem?

- Se você deseja medir em dispositivos mais ou menos reais, lento, não tão legal quanto o seu, use o WebPageTest . Eu costumo fazer medições lá.

- Você possui o Lighthouse se usar navegadores baseados no Chromium. Ele, como medições locais, mostra coisas muito boas.

- Se você tem certeza de que pode fazer tudo sozinho, vá para o DevTools, na guia Desempenho. Tem muitos detalhes, você pode iniciar suas próprias métricas e analisá-las.



Naturalmente, no desempenho, é necessário definir condições reais. Você está sentado no seu laptop legal com Internet legal no escritório, tudo é incrível aqui, mas eles vêm até você e dizem: "Estou lento". E você diz: "Tudo funciona para mim". Não faça assim.

Sempre tente verificar como o usuário, nas condições do metrô ou em outro lugar, usará seu site. Para fazer isso, você precisa configurar uma Internet muito lenta. Também é aconselhável desacelerar a CPU, porque alguém pode vir até você a partir de um Nokia 3110. Ele também precisa mostrar o site.

Mais importante: avalie em usuários reais. Existe essa métrica, mais precisamente, todo um conjunto de métricas - RUM, Real User Monitoring. É quando você mede não o que acontece sinteticamente no seu código, mas as métricas de usuários reais na produção. Por exemplo, do carregamento de uma página para uma ação. Uma ação é, por exemplo, algo que funciona no navegador ou até mesmo um clique em algum elemento importante.

Lembre-se de que você não está desenvolvendo para robôs. Sotka em Lighthouse - é ótimo, é muito bom. Portanto, você cumpre pelo menos os requisitos que o Farol define. Mas existem usuários reais e, se o usuário não conseguir ver a página ao carregar o Lighthouse, você está fazendo algo errado.



Existem métricas importantes para se concentrar. Esta é a primeira pintura com conteúdo, quando o primeiro conteúdo aparecer em sua página com o qual você pode fazer algo, leia. Essa métrica é enviada nos navegadores Chromium, você pode obtê-la.



Recentemente, você ainda pode ver a Maior pintura com conteúdo. Muitas vezes acontece que você tem uma página de mídia e é importante, por exemplo, ver uma foto nela. Então você precisa dessa métrica específica.

Carregamento CSS


Vamos finalmente passar ao CSS, como o CSS é carregado. As recepções são conhecidas há muito tempo. Há um caminho de renderização crítica, um caminho de renderização crítica. É sobre o que o navegador faz desde o momento do envio da solicitação do recurso até o momento em que os pixels são exibidos na tela do usuário. Sobre isso, também, há vários artigos e relatórios. Mas vamos dar uma rápida olhada em como esse navegador faz isso.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>

Ele começa a baixar HTML, vê tags. Ele gradualmente os analisa, entende o que fazer com eles. Carrega. Veio através do link. Deve ser usado. Mas como? Primeiro você precisa fazer o download. O download é lento. Quando carrega, começa a analisar mais a página.

 <!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS —  </title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>
<body>
    <h1>-!</h1>
</body>
</html>

Se deparar com outro link, será bloqueado novamente e não permitirá a execução. Bloqueia JS, bloqueia a análise. E até inicializar, não faz nada. Mas então começa a trabalhar mais.

<link>


Vamos aprofundar - o que acontece quando você acessa o link?



Gravar para onde vamos é padrão. Existe um estilo CSS que fica em algum lugar. Agora está na moda colocar todas as estatísticas na CDN.

Onde ir?


Primeiro, o navegador precisa entender para onde ir.



Ele vê o URL e precisa entender esse URL - sobre o que é? Estamos acostumados ao fato de que o URL é um identificador de site.



Mas fisicamente precisamos obter o endereço IP desta URL e ir para a máquina física real no endereço IP.



Para o seu CDN, ele receberá um registro no DNS e será direcionado diretamente para o endereço IP. Como alguém pode acelerar neste caso?



Uma ideia maluca é reduzir a distância do usuário ao servidor DNS. Pegue e transplante o usuário. Por exemplo, para exibir a mensagem: "Sente-se mais perto" ou "Aproxime-se".

Você pode especificar imediatamente o endereço IP no link. Por que precisamos procurar DNS, resolver domínios, se você pode fornecer imediatamente o resultado por endereço IP? Essa é uma maneira louca, mas no caso dos servidores DNS globais do DDoS, ele pode até salvá-lo.

E podemos nos livrar de obter um endereço IP.



Passando para o index.html ou para outro arquivo, você já sabe o endereço de domínio para onde vai. Aqui está exatamente o caso em que, em vez de armazenar estática em um domínio ou subdomínio separado, você pode colocar a estatística mais próxima do seu domínio, a saber, o próprio domínio. Então o DNS não precisa ser resolvido, ele já está.



Nós descobrimos para onde ir. Mas podemos fazer essas coisas com antecedência para o navegador. Se, por exemplo, sua folha de estilos for carregada muito mais tarde através da árvore do DOM, você poderá dizer ao navegador usando <link rel = "dns-prefetch"> que "Eu ainda não vou lá, mas você aquece os recursos, definitivamente precisarei deles mais tarde "

Com esta entrada, você diz ao navegador para descer e obter esse DNS. Quando o link aparecer no código, o navegador já saberá o endereço IP deste domínio. Você pode fazer essas coisas preliminares. A mesma coisa, por exemplo, antes de entrar na próxima página, para onde você definitivamente irá.

Ok, o navegador sabe para onde ir. Ele precisa entender como ir.

Como ir


Estamos assistindo o protocolo. Agora, é claro, https é um requisito direto. A inclusão de mecanismos de pesquisa marcará seus sites não em https com formulários como não totalmente seguros.

Encontrei uma série incrível de quadrinhos sobre como o quadro funciona https. Mas somos pessoas de TI, adoramos diagramas complexos legais e quadrinhos engraçados são fáceis demais.



Aqui, formulei com minhas próprias palavras como o https funciona. Primeiro você obtém um certificado SSL do seu servidor. Em seguida, você deve verificar o certificado em uma autoridade de certificação. Estes são servidores especiais que sabem o que é válido e o que não é, e podem solicitar navegadores: "Sim, está tudo bem aqui, use este certificado".

A seguir, é apresentada a geração de chaves para comunicação entre o servidor e o cliente, criptografia e descriptografia usando chaves diferentes. O processo é interessante se você o examinar em termos de criptografia. Mas queremos acelerar. Quão?



Podemos novamente transferir o usuário para mais perto dos servidores. Já temos um DNS, agora podemos aproximá-lo da autoridade de certificação. E colocar entre esses servidores será perfeito.

Você pode desativar o https, por que precisamos dele? Nós gastamos tempo obtendo um certificado, criptografar, descriptografar. Na verdade não. Este é o conselho mais prejudicial do relatório, não faça isso. https é proteção de dados do usuário, e http / 2 não funcionará sem https, e http / 2 é outra maneira de acelerar.



Há também a tecnologia de grampeamento OCSP. Você pode verificar um certificado sem uma autoridade de certificação. Provavelmente isso está mais próximo do DevOps. Você precisa configurar seu servidor de uma certa maneira para que ele possa armazenar em cache a resposta da Autoridade de Certificação e emitir para o usuário: "Acredite, meu certificado é realmente real". Assim, podemos salvar pelo menos a etapa em que vamos à autoridade de certificação.

Mas há uma nuance - no Chrome, isso não funciona e por um longo tempo. Mas para o usuário de outros navegadores, você pode acelerar esse processo.

Eu já disse duas vezes que é necessário transplantar o usuário, e a ideia está subindo no ar - para aproximar o servidor do usuário. Eu não descobri nada de novo para você. Esta é uma CDN, uma rede de entrega de conteúdo distribuído. A idéia é que você possa usar o sidienki pronto, criar sua própria infraestrutura de forma independente e colocar vários servidores em todo o mundo, tanto quanto o dinheiro e as oportunidades permitirem. Mas você precisa organizar o servidor para que um usuário da Austrália vá para servidores australianos. Aqui a velocidade da luz joga com você, quanto menor a distância, mais rápido os elétrons a passam.

Vamos cavar mais fundo. O que mais está acontecendo na solicitação? De fato, https é apenas um invólucro sobre http. Não é apenas um invólucro legal. E se for ainda mais profundo, o http é uma solicitação da família TCP / IP.



Como os pacotes e bytes são enviados na rede para que todos os navegadores, clientes e servidores se comuniquem? A primeira coisa que um cliente / servidor faz em uma conexão TCP / IP é um handshake.

Mas em 2020, a OMS recomenda evitar apertos de mão. Existe uma tecnologia TCP Fast Open tão legal. Você pode, no momento do aperto de mão, evitar toda a cadeia “Olá, eu sou um cliente” - “Olá, eu sou um servidor” - “Eu acredito em você” - “E eu acredito em você. Vai". Você já pode enviar dados úteis neste momento. E se o aperto de mão foi bem-sucedido, parte dos dados úteis passou. Este é o TCP Fast Open.

O que pegar?


Vamos descobrir o que o cliente deve buscar no servidor. O principal não é que o cliente pegue algo do servidor, mas o servidor entregue os dados ao cliente. Então você pode pensar: User-Agent. Posso obter o User-Agent do cliente, descobrir em qual navegador o usuário efetuou login. Descubra aproximadamente se este navegador não me engana.

.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}

Digamos que ele fez login no Firefox. Como de costume, eu tenho um assembly no qual o autoprefixer está conectado à uma brega, gerou um monte de código para mim. Sim, é uma abordagem legal de que tudo funcionará em qualquer lugar. Mas eu já sei que o usuário efetuou login no Firefox.

Por que não desligar todo o excesso? Concordo, há muito menos linhas, enviamos menos bytes, isso é legal.

Temos uma versão lite do SERP, Granny. Vitaly Kharisov falou sobre elavithar, relatório de classe nos dias de padrões da Web. Ele usa exatamente essa abordagem. Podemos gerar vários pacotes e entregá-los a diferentes clientes de maneiras diferentes. Eles pesam muito menos, porque o Firefox é seu, o WebKit é seu, e funciona, é verificado.



Mais longe. Provavelmente processamos solicitações de usuários, sabemos que a pessoa está autorizada e usamos algumas informações pessoais para ela. É lógico que devemos obter algo do banco de dados. Mas nem todos! Existem coisas estáticas que não diferem para nenhum dos usuários, elas são exatamente iguais.

James Akvuh leu um relatório interessante sobre isso“Renderização do lado do servidor. Faça Você Mesmo". Qual é o ponto? Você já sabe que possui HTML e algum tipo de CSS que é o mesmo para todos os usuários. Antes de escolher qualquer dado, você pode gerar a saída desses dados estáticos e enviar imediatamente o mais útil em um fluxo do servidor. E depois disso - vá para os dados, receba-os rapidamente, converta-os em modelos e entregue-os ao cliente. E o usuário já verá algo útil.



Nós implementamos isso há muito tempo. Temos na SERP, na página principal de pesquisa, duas fases - pré-pesquisa e pós-pesquisa. A pré-pesquisa é quando enviamos todas as peças que não precisam de conhecimento sobre qual usuário efetuou login. Já podemos dar a ele, por exemplo, um chapéu.

Ou seja, temos uma barra de pesquisa que o usuário pode começar a usar antes que todo o resto seja carregado. Isso é útil em uma conexão lenta. Nós fazemos isso, funciona.

E eu também falei sobre http / 2. Isso é totalmente suportado pelos navegadores modernos; portanto, se você ainda não o configurou no servidor, descubra como configurá-lo.

O Server Push é uma tecnologia interessante que diz: “Navegador, ainda não lhe dei o conhecimento de que você precisa de algum tipo de CSS. Mas eu sei exatamente o que é necessário. Então segure, pré-carregue.





Não é díficil. Você precisa configurar alguns cabeçalhos no servidor e tudo começará a funcionar. Se o navegador não conhece esse título, nada vai quebrar, isso é o mais bonito. Vamos cavar ainda mais. TCP Já falamos sobre isso: um aperto de mão, bytes são enviados.



Lave as mãos após um aperto de mão. Porém, em termos de TCP, começamos a encaminhar bytes e os algoritmos são otimizados o suficiente para que o servidor cliente não fique ocioso.

Portanto, um determinado segmento de dados é enviado primeiro. Por padrão, (isso pode ser alterado nas configurações), são 1460 bytes. O servidor não envia informações em um segmento. Ele envia janelas.

A primeira janela é 14600 bytes, dez segmentos. Então, se a conexão for boa, ele começa a ampliar as janelas. Se a conexão for ruim, poderá reduzir a janela. O que é importante entender? Existe a primeira janela de dez segmentos, na qual você deve ajustar o site inteiro, se desejar. E então haverá a velocidade máxima do conteúdo. Vitaliy Kharisov também leu um relatório sobre isso . E sim, é possível ajustar um site com tudo o que você precisa em uma janela se você desativar, por exemplo, o JS.

Uma nuance importante. Quando você preenche um segmento inteiro, é um segmento. Mas se você enviar apenas um byte extra, o servidor ainda enviará um segmento extra inteiro.



Você pode fazer uma otimização interessante, reduzir a produção em um kilobyte inteiro, mas não verá nada nas suas medições - talvez por isso. Tente fazer a otimização normalmente em vários segmentos.

Estranho: sou um tipógrafo e digo coisas complexas para servidores. Vamos nos aproximar ainda mais do CSS real.

Enviar menos


Então, enviamos menos para o usuário, menos segmentos, chega mais rápido, o usuário fica feliz.



Minificação. Ela foi criada em seus projetos. Existem várias ferramentas interessantes, plug-ins de pacotes da web, configurações de gole - em geral, você vai descobrir por si mesmo. Você pode personalizá-lo manualmente, mas parece apenas quando você tem certeza de que pode compactar seu CSS mais frio do que qualquer CSSO.

Lembre-se de ativar a compactação. Se pelo menos o gzip não estiver ativado em 2020, você definitivamente está fazendo algo errado, porque esta é uma técnica de compressão antiga. Em geral, em 2020, é hora de usar brotli. Essa é uma boa maneira de reduzir um pouco a saída nos navegadores Chromium. Ou, se você não deseja oferecer suporte ao brotli, pelo menos pode tentar o zopfli.

Esse é um algoritmo de compactação bastante lento para o gzip, que simplesmente fornece os melhores resultados de compactação e descompacta tão rápido quanto o gzip comum. Portanto, o zopfli precisa ser configurado com sabedoria e usado somente quando você não precisa enviar dados em tempo real. Você pode configurar os arquivadores gzip a serem coletados durante a montagem usando o algoritmo zopfli, e enviados estaticamente já, de fato, não estão em movimento. Isso pode ajudá-lo. Mas também meça os resultados.



Todos esses algoritmos usam algum tipo de dicionário: um dicionário é construído com base na repetição de fragmentos de código. Mas às vezes eles dizem: é necessário alinhar, se alinhamos, então nos livramos da solicitação. Vincular todo o CSS em HTML será muito rápido. O truque é que o gzip funciona um pouco mais eficientemente quando você divide os estilos e o HTML, porque os dicionários são diferentes, mais eficientes.

No meu caso, peguei a página de inicialização, vinculei a inicialização e comparei as duas versões. O gzip sobre recursos individuais é 150 bytes a menos. Sim, o ganho é muito pequeno. Aqui também é preciso medir tudo. Mas no seu caso, isso pode, por exemplo, reduzir o número de segmentos em um.

Como otimizar o código? Não estou falando de minificação. Tire o que você não está usando no projeto. Provavelmente você possui um código que nunca será executado no cliente. Pelo que?



Para que você possa automatizar isso, guias especiais são incorporadas ao navegador, por exemplo, no Chrome DevTools, isso é Cobertura, que informa: "Eu não usei esse CSS ou esse JS, você pode cortá-lo".

Mas você pode ter foco, ativo, algo instalado usando JS. Você precisa simular todas as ações possíveis no site, só assim você terá certeza de que esse CSS poderá ser cortado. Chris Coyer tem um bom artigo de revisão sobre ferramentas automáticas que tentam fazer tudo com foco e foco. Mas ele chegou à conclusão de que era impossível automatizar isso. Ainda não deu certo.

Há um bom relatório de Anton Kholkin da Booking.com, onde eles também tentaram remover montes de código legado. Mas eles tinham uma peculiaridade: um código legado que vinha de projetos externos. Foi necessário removê-lo. Veja que soluções interessantes eles encontraram.

Você mesmo pode tentar jogar com o mesmo Puppeteer, que é como o Chrome. Você pode fazer testes que passam automaticamente por tudo, tentar pairar, se concentrar. E use essa mesma cobertura.

Minha colega Vitya Khomyakovvictor-homyakovfiz meu próprio script , como encontrar duplicatas e estilos em uma página. Basta pegar, copiar e colar. Ele escreverá para você no console: "esse seletor, ao que parece, você não precisa". Até o ponto que acabou de entrar no DevTools. É incrivel.



Um recurso que eu realmente gosto nas ferramentas dos desenvolvedores do Firefox: uma oportunidade de ver estilos que parecem ser usados, mas na verdade o navegador não os aplica.

Por exemplo, você pode definir display: inline e parece que este display: inline não faz sentido definir tamanhos. Ou alinhamento vertical, funciona apenas para células em linha ou tabela. Até agora, só vi no Firefox que ele pode destacar: "você não precisa dessa linha".

Aqui também é preciso ter cuidado: talvez você use esse estilo para colar a classe posteriormente. Mas, na minha opinião, um recurso interessante.

Faça a si mesmo a pergunta agora: você precisa de todo o Bootstrap no projeto? Coloque qualquer estrutura CSS usada em vez do Bootstrap. Provavelmente, você usa o Bootstrap para grades e elementos mais ou menos comuns e metade do Bootstrap não é necessário.

Tente usar a montagem corretamente. Quase todas as estruturas CSS modernas permitem que você use o código-fonte para montagem e selecione apenas o que você precisa. Isso pode reduzir drasticamente o tamanho do pacote CSS.

Não doar sem uso. Em vez de procurar meu legado, você pode usar o entendimento no nível de compilação de que esta página não usará esse CSS.

Por exemplo, uma pilha BEM completa permite que você faça a montagem para que você, já fornecendo a página, possa construir uma árvore de todos os componentes dos blocos BEM que estarão na página. O BEM permite determinar que, se esse bloco não estiver na página, não há necessidade de carregar esse CSS. Envie apenas o necessário.

Até os funcionários do Google dizem : use o BEM, ele pode realmente ajudá-lo na otimização.

Eu não acredito que digo isso em voz alta, mas neste caso o CSS-in-JS parece ser uma boa abordagem. Quando você escreve componentes independentes independentes e configura cuidadosamente o assembly ou determina em tempo de execução quais blocos são usados ​​e quais não são, você pode se livrar do problema de encontrar um código legado simplesmente não enviando esse código ao cliente. Parece fácil, mas é necessária disciplina. Pense nisso com antecedência no início do projeto.



Que outra opção existe? Um pouco louco. Neste código, parece que o estilo não é necessário, porque usamos uma div - o padrão já é display: block. E vamos excluir todos os padrões? Se em seu projeto você tiver certeza de que a marcação HTML nunca será alterada novamente - passe pelos valores padrão que o navegador já fornece e remova-os.

Menos estilos - ótimo! Mas isso é novamente uma ideia maluca. O CSS não precisa saber sobre HTML, porque é um estilo. É bastante independente, você deve conectá-lo a outro projeto, ele deve funcionar lá. E sim, é difícil de manter. Mude a etiqueta - tudo quebra. Ideia louca como prometido.

Use variáveis. CSS possui variáveis ​​muito antigas, como currentColor.



Muitas vezes, existe um padrão: você deseja, por exemplo, criar um botão cujo texto e borda sejam da mesma cor. E, ao passar o mouse, mudamos os dois. Pelo que?



Há uma variável currentColor que recebe um valor da cor e você a coloca, por exemplo, na borda, proxy essa propriedade e altera apenas uma linha ao passar o mouse, focalizar, ativo, o que você quiser. Isso parece conveniente, e o código se tornou uma linha a menos. Você pode otimizar. A propósito, neste exemplo, você não pode usar a tarefa de cor da borda, porque, por padrão, ela já recebe um valor da propriedade color.

Às vezes, é muito triste observar como o base64 é usado. No CSS, era recomendado ativamente antes: use base64 para injetar pequenos ícones. Se ele se encaixa em um segmento sobre o TCP, é bom para você.



Mas Harry Roberts tambémConduziu um estudo elegante sobre como a base64 afeta o carregamento da página. Sim, há menos solicitações, mas esses estilos são analisados ​​às vezes mais lentamente.

Ok, a análise é uma operação muito rápida, o usuário provavelmente não notará. Mas temos uma métrica importante - a primeira renderização, para que o usuário veja algo na página. Nos celulares, a primeira renderização, de acordo com um estudo de Harry Roberts, ocorre dez vezes depois. Pense se você precisa do base64? Sim, há menos solicitações, mas isso teve algum efeito?

E por favor não use base64 para SVG. Porque o SVG é ótimo para usar o codificador de URL. Julia Bukhvalova tem uma ferramenta legal: Entre, cole seu SVG e ele exibirá o CSS em um formato pronto para colar. Você pode perceber que não há base64, mas algumas coisas escaparam que no CSS podem não ser percebidas corretamente. É muito mais eficiente.

Em média, o base64 oferece um acréscimo de 30% ao tamanho do que você comprime. Pelo que?

Use tecnologia moderna. Talvez seja necessário oferecer suporte ao Internet Explorer - os argumentos usuais ao falar sobre grades.



Mas pense bem: se você não tem suporte para o IE e ainda digita em float ou tabelas, pode usar grades para criar um layout de três colunas com uma diferença de 20 pixels - essa é a distância entre as colunas. Três linhas Bem, cinco, considerando o anúncio em si.

Tente isso em um carro alegórico. E quero dizer que alteramos três linhas, incluindo o nome das classes, se você tocar em HTML. Eu não encontrei uma maneira de fazer o mesmo legal em um carro alegórico. Jogue fora suas decisões. Mas use a tecnologia moderna. Eles permitem que você indique de forma mais compacta a marcação.



Você pode experimentar o Atomic CSS. O que é isso? Você escreve esses nomes de classe um pouco loucos. Depois de algum tempo, você começa a entender que é você quem define a cor de fundo ou apenas a cor. Estes são os "recursos" para CSS. Mas você tem um conjunto fixo de CSS que você usa em HTML como uma indicação de estilo. E o CSS está subitamente ficando menor. Para projetos grandes, ele realmente se tornará menor, porque há menos estilos únicos. Mas você está desenvolvendo HTML.



Você pode olhar na direção do Tailwind CSS, que agora está ganhando popularidade. Não é CSS atômico, trata-se de classes de utilidade, semelhantes ao Bootstrap, apenas mais utilitárias. Você pode usar um conjunto específico. O suficiente parece ser suficiente para você. Um conjunto de classes que executam suas funções. Você também pode tentar, mas não exagere.



Outra idéia maluca - por que precisamos de nomes de classe inteiros no cliente? Sim, é conveniente para desenvolvimento e depuração, mas vamos pegar todos os nomes de classe e transformá-los em uma letra. Será menos.

Aqui está um artigo sobre como fazer isso. Você pode configurar o webpack ou outro plug-in ao criar. Mas não decolou de nós. Nós tentamos.

Aconteceu que o gzip é tão legal que tudo foi muito bem otimizado para nós, e o BEM e o gzip são incrivelmente amigáveis. Como as construções de texto são repetidas para descrever blocos e elementos no código.

Em geral, isso nos deu quase nenhum lucro. Mas se, por exemplo, você não tiver o BEM e um monte de classes diferentes, poderá tentar.

Importante: medir. Meça todas essas peças experimentais. Talvez agora funcione para você e, em seguida, você alterou levemente a arquitetura do projeto, ele começou a se montar de maneira diferente e tudo ficou mais lento.

Baixe!


Até agora, eu só falei sobre como baixar um arquivo. Nós o baixamos. O que o usuário viu todo esse tempo?



Ele viu uma tela tão incrível. Enquanto estávamos baixando, a tela estava em branco. Fizemos o download e o navegador inicia mais seis etapas. Seja um pouco paciente, vou falar sobre eles um pouco mais rápido do que sobre o download.



Vamos começar com a análise. A análise é quando um navegador baixa um fluxo de bytes e começa a dividi-lo em entidades que ele entende.



Por exemplo, ele se deparou com importação. Isso novamente deve ser baixado. Leia a primeira parte do relatório novamente? A importação é uma operação de bloqueio. Mas os navegadores são inteligentes. Eles têm um scanner de pré-carregamento. Eu disse que tudo está bloqueado lá, isso não é verdade. Os navegadores sabem que, por exemplo, se houver três tags de link seguidas que seguem o estilo, quando eu baixar o primeiro, você poderá começar a baixar o segundo e o terceiro. Ele não pode analisar, porque toda a estrutura da análise é interrompida. Mas faça o download com antecedência - pode.



Então importar é uma coisa ruim. Se os estilos forem consistentes em HTML, o navegador verá que iremos além em outro arquivo.



E se você o inserir diretamente na importação, primeiro faça o download do seu style.css e veja a importação. Ele começa a analisar esse CSS ... Sim, bloqueamos tudo de uma maneira nova e procuramos o arquivo! Assim, você pode fazer uma cachoeira legal com desoptimização no site.

Esqueça a importação ou configure para que não haja importação após a compilação. Para o ambiente de desenvolvimento, ok, mas não para o usuário.



Em seguida, passamos pelas etapas de construção de árvores, usando o Cascade.



Tudo isso também é descrito por um longo tempo. O CSS Object Model é construído - uma árvore especial de como o navegador mapeia tags, classes para estilos. Ele vincula tudo ao DOM e faz essas conexões muito rapidamente. Quando você muda alguma coisa, basta que ele mude dentro da árvore.



Quanto maior o seletor, mais difícil é para o navegador desenhar uma árvore. Ele precisa analisar o seletor, convertê-lo em estruturas em árvore. E se você inseriu! Importante lá, ele deve levar isso em conta.



Parece que é hora de falar sobre o BEM novamente. Mas o BEM não é necessário se você souber usar classes de utilitário, se uma classe for responsável por uma funcionalidade e elas não interferirem entre si. Então construir uma árvore é muito simples. Você tem uma estrutura bastante plana e, em seguida, o navegador deve vinculá-lo corretamente ao DOM.



Se você fizer isso, eles dizem que esses seletores desaceleram a análise de CSS. Mas essas são lendas há muito tempo, a diferença é tão pequena para o navegador que, no projeto médio, você não perceberá se otimizar seletores com asteriscos. Mas você gostaria de desenvolver e manter esse código?



Eu costumava ouvir dicas: tente colocar tudo em um atalho. background é um atalho para muitas outras propriedades. Colocamos tudo em uma propriedade e ela se torna ideal.

Por bytes, sim, está ficando menor. Mas se você deseja otimizar a composição do CSS OM, o navegador ainda fará com que todas essas propriedades ocorram em segundo plano. Os navegadores para cada elemento DOM criam uma tabela de todas as propriedades que ele pode ter. Quando você olha para os valores calculados do DevTools, eles não estão lá porque o navegador os calculou de acordo com seus requisitos. Ele armazena isso na memória, porque é muito mais fácil reescrever uma propriedade e tudo funciona.

Esse também é um conselho muito estranho, mas se você quiser acelerar o CSS OM, poderá definir imediatamente todas as propriedades, uma de cada vez. Isso pode funcionar. Mas o tamanho do pacote aumentará bastante. Você precisa medir. Duvido que dê lucro, mas de repente!

Quando o CSS OM é criado, o JS também está bloqueado neste momento. Se a construção do OM CSS demorar dois segundos, o JS falhará. Embora eu não possa imaginar como você conseguiu escrever tanto em CSS que a árvore foi criada por dois segundos.



Além disso, o navegador faz o Layout. Esta é a localização de todos os elementos DOM, o uso de posições. Ele entende onde o elemento deve estar localizado e com quais dimensões. Parece que, nesta fase, o usuário já deve ver algum tipo de imagem. Mas ele vê tudo na janela de exibição, pode olhar através de uma janela limitada. Se algo não está certo por baixo, ele simplesmente não vê.



A idéia é chamada CSS crítico e também é bastante antiga. Você insere algumas coisas importantes para a primeira tela no início do download. Por exemplo, em linha no seu HTML, livre-se de quaisquer solicitações adicionais. O usuário vê essa tela primeiro e depois faz o download como quiser. Provavelmente, ele começará a rolar quando tiver tempo para carregá-lo.



Isso é feito simplesmente. Existem ferramentas que automatizam tudo isso, incluindo plugins para webpack e React. Basta pesquisar e configurar corretamente.

- github.com/addyosmani/critical
- github.com/pocketjoso/penthouse
- github.com/anthonygore/html-critical-webpack-plugin
- github.com/GoogleChromeLabs/critters



Tenha uma boa abordagemdo Filament Group - como carregar de forma assíncrona sem bloquear o CSS. Tudo é bem simples.

Quando você colocar <link rel = preload>, diga ao navegador: “Vou precisar desse estilo, mas agora não estamos bloqueando nada. Faça o download agora, armazene em cache e, quando eu voltar, comece a criar o CSS OM. ” E você só precisa colocar onload e processar que "ok, desde que eu baixei, faça rel = stylesheet, habilite a análise".

Uma abordagem bastante simples, mas use-a com sabedoria também. Se você tiver muita pré-carga, poderá fazer pior.



Você também pode brincar com expressões de mídia. Cole-os e diga ao navegador: "esse estilo não é mais necessário agora, mas quando essa expressão de mídia funcionar, será necessário". O navegador também fará o download proativamente, mas com uma prioridade mais baixa e sem bloqueio.



Outra abordagem maluca, mas não tão louca - quando você tem o http / 2 push. Você pode incorporar CSS bem na frente do bloco. Sem CSS, seu bloco não ficará muito bom. Então, por que não incorporar o CSS necessário para o próximo bloco antes desse bloco? Isso é lógico, e o envio http / 2 permitirá que você o otimize.

Uma abordagem simples. Se você expandi-lo, use carregamento lento. Por que um usuário deve baixar algo que ele não usará? Você pode configurar os componentes do React para que, se ele nunca atingiu a área de visibilidade da página, por que deveria baixar os estilos para si mesmo?

Explore a API do Intersection Observer e poderá acelerar drasticamente sua página.



O último passo é desenhar e aplicar em camadas compostas, colá-las e assim por diante.



O navegador cria camadas compostas em um grande número de casos. Na minha opinião, apenas um quarto do código fonte do Chromium se encaixa aqui . Você pode ver por si mesmo quando ele cria camadas compostas no código do navegador.

A memória de vídeo é limitada, especialmente em telefones celulares. Se você trouxer tudo para novas camadas para otimizar as animações usando o will-change: transform ou qualquer outra coisa, poderá estar piorando.

Crie menos camadas - exatamente o necessário para a otimização atual.

Ótimo, todos nós analisamos.

E se eu voltar?


E se eu voltar à página? Esta é apenas a primeira vez que fui.

Voltando à página, parece que consigo baixar tudo instantaneamente. Eu já baixei todos os recursos, por que não usá-los uma segunda vez?



Se o servidor não fornecer o cabeçalho de controle de cache, o navegador tentará armazenar em cache seu arquivo para reutilizá-lo. Você pode configurar seu servidor por padrão, digamos: "armazene em cache esse arquivo por um ano inteiro". Não mudará. Mas, nesse caso, você precisa lidar com o problema de invalidação do cache global. Mas este é o tópico de um relatório separado.

Use trabalhadores de serviço! 2020, é hora, Aplicativos Web Progressivos! Kirill Chugainov teve um bom relatóriosobre como os Trabalhadores em Serviço podem ser usados ​​para diferentes ocasiões. Nesse caso, você intercepta a solicitação CSS, salva-a e, se o navegador seguir esse estilo pela segunda vez, afaste-a do cache.

Mas o navegador não promete nada a você. Você sempre pode enfrentar o fato de o navegador ficar sem memória. Ele tentará armazenar em cache, mas não há memória. O armazenamento em cache não é cem por cento. Sempre lide com essas situações.

Você pode tentar usar o armazenamento local. Mas ele é muito lento. Às vezes, o download de um arquivo é mais rápido do que ir para a API de armazenamento local.

Você pode tentar o banco de dados interno do navegador. Mas meça. Talvez uma viagem ao JS leve mais tempo devido a um processador fraco.

Você também pode informar com antecedência ao navegador que fará o download de algo.



<link rel> - saiba como esse atributo funciona. Há pré-conexão, pré-busca, pré-renderização - quero falar sobre isso separadamente. Ele diz: “Estou nesta página agora e depois irei para a próxima. Faça o download de tudo para esta página na guia segundo plano e desenhe. ” Coisas legais. Não funciona em lugar nenhum.



De certa forma, ele é suportado no IE e Edge. No Chrome, ele realmente não faz isso, não é renderizado. Funciona como pré-busca: baixa esses arquivos e caches. Infelizmente, um pré-renderizador completo não funciona em lugar nenhum.

Mas você pode desenvolver essa ideia. Por exemplo, no aplicativo Yandex - naturalmente, não usando CSS - é feito um pré-renderizador. Quando você está procurando algo, é provável que obtenha resultados instantaneamente. Nós podemos prever onde você vai, e com antecedência pelos nossos próprios métodos de ir buscar todos os recursos necessários.

Qual é o próximo? Havia muitos links. Também aconselho a olhar para uma incrível coleção de otimização de tudo, desde Vanya Akuloviamakulov. Veja como otimizar HTML, JS e assembly.

E não se esqueça de arrumar. Agora, meu conselho realmente funciona, sugerindo como fazê-lo rapidamente, mas provavelmente, depois de cinco anos, eles serão prejudiciais. Haverá algum tipo de tecnologia que será incompatível com eles. Acompanhe isso e tente manter seu código ideal, inclusive depois de um tempo. Obrigado pela atenção.

All Articles