RenderingNG

Pronto para a próxima geração de conteúdo da Web

Chris Harrelson
Chris Harrelson

Sou Chris Harrelson, o chefe de engenharia de renderização (transformação de HTML e CSS em pixels) no Blink. Estou há mais de oito anos na área do desempenho de renderização na Web, com o objetivo pessoal de fazer o que puder para que a experiência do usuário na Web seja mais rápida, fácil e confiável. Quero muito contar a você o que fizemos nesse tempo para construir uma nova arquitetura moderna do mecanismo de renderização do Chromium. Conseguir isso foi um enorme trabalho de amor, e espero que você goste de ouvir sobre isso.

Em 2021, concluiremos em grande parte o processo de design, construção e lançamento dessa arquitetura. Vamos chamá-la de RenderingNG, já que é realmente uma arquitetura de renderização de última geração que supera muito o que veio antes. A renderização está em andamento há pelo menos oito anos e representa o trabalho coletivo de muitos desenvolvedores dedicados do Chromium. Ela libera uma enorme quantidade de potencial para a próxima geração de conteúdo da Web rápido, fluido, confiável, responsivo e interativo. É também uma referência que, acredito, define um novo padrão mínimo para todos os mecanismos de renderização da web nos quais os desenvolvedores podem confiar.

Esboço dos diferentes elementos da RenderizaçãoNG
RenderingNG

Esta postagem do blog é a primeira de uma série, em que explicaremos o que criamos, por que o criamos e como funciona. Nesta primeira postagem, começarei com:

  • Nosso objetivo principal.
  • A pirâmide do sucesso: princípios que orientam nosso trabalho e exemplos desses princípios na prática.
  • Os recursos e funcionalidades possibilitados pela renderização.
  • Uma visão geral de alto nível dos principais componentes do projeto do RenderingNG.

Estrela Norte

O principal objetivo que motiva o RenderingNG é que a implementação do mecanismo de navegador e a riqueza das APIs de renderização não sejam um fator limitante da UX na Web.

Não se preocupe com bugs do navegador que tornam os recursos não confiáveis ou prejudicam a renderização do site.

Não deve haver penhascos de desempenho misteriosos. Além disso, você não precisa contornar a falta de recursos integrados.

Isso deve funcionar.

Acredito que o RenderingNG é um grande passo em direção a esse objetivo principal. Antes do RenderingNG, era possível adicionar recursos de renderização e melhorar o desempenho, mas tinha dificuldade para tornar esses recursos confiáveis para os desenvolvedores, e havia muitos problemas de desempenho. Agora temos uma arquitetura que supera sistematicamente muitos desses problemas e também desbloqueia recursos avançados que não eram considerados viáveis antes. Ele:

  • Tem recursos essenciais em diferentes combos de plataforma, dispositivo e sistema operacional.
  • Tem desempenho previsível e confiável.
  • Maximiza o uso das capacidades de hardware (núcleos, GPU, resolução de tela, taxas de atualização, APIs de varredura de baixo nível).
  • Executa apenas o trabalho necessário para exibir conteúdo visível.
  • Tem suporte integrado para padrões comuns de design visual, animação e design de interação.
  • Fornece APIs de desenvolvedor para gerenciar facilmente os custos de renderização.
  • Fornece pontos de extensão de pipeline de renderização para suplementos do desenvolvedor.
  • Otimiza todo o conteúdo: HTML, CSS, tela 2D, tela 3D, imagens, vídeo e fontes.

Comparação com outros mecanismos de renderização do navegador

A Gecko e o Webkit também implementaram a maioria dos recursos de arquitetura descritos nestas postagens do blog e, em alguns casos, os adicionaram antes do Chromium. O que é ótimo! Embora um navegador cada vez mais rápido e confiável seja motivo de comemoração e um impacto real, o objetivo final é melhorar a linha de base para todos os navegadores, para que os desenvolvedores possam confiar nele.

A pirâmide do sucesso

Minha filosofia é que o sucesso é o resultado de, primeiro, alcançar a confiabilidade, depois o desempenho escalonável e, por fim, a extensibilidade.

Pirâmide com rótulos Confiabilidade na base, Desempenho no meio, Extensibilidade na parte superior

Assim como acontece com uma pirâmide da vida real, cada nível fornece uma base necessariamente sólida para o nível acima.

Confiabilidade

Esboço mostrando como os recursos da renderizaçãoNG podem ser adicionados sem um grande aumento na frustração

Para que seja possível criar experiências do usuário avançadas e complexas, a primeira coisa que precisamos é de uma plataforma sólida. Os recursos e fundamentos principais precisam funcionar corretamente e continuar funcionando ao longo do tempo. Também é importante que esses recursos tenham uma boa composição e não tenham bugs ou comportamento estranho nos casos extremos.

O esboço mostra a natureza circular adicionando atributos, recebendo feedback e melhorando a confiabilidade

Por esse motivo, a confiabilidade é a parte mais importante do RenderingNG. E a confiabilidade é o resultado de bons testes, loops de feedback de qualidade, métricas e padrões de design de software.

Para dar uma noção da importância da confiabilidade, passamos a maior parte dos últimos oito anos acertando só essa parte. Primeiro, criamos um conhecimento profundo sobre o sistema, aprendendo com relatórios de bugs onde estavam os pontos fracos e corrigi-los, fazendo inicializações de testes abrangentes e entendendo as necessidades de desempenho dos sites e as limitações do desempenho do Chromium. Em seguida, projetamos e lançamos os principais padrões de design e estruturas de dados com cuidado e incrementalidade. Só então estávamos prontos para adicionar primitivos de última geração para design responsivo, escalonabilidade e personalização de renderização.

O gráfico de esboço mostra a melhoria da confiabilidade, do desempenho e da extensibilidade ao longo do tempo

Isso não quer dizer que nada foi melhorado no Chromium ao longo desse período. Na verdade, o contrário é verdadeiro. Esses anos vimos um aumento constante e contínuo na confiabilidade e no desempenho, à medida que refatoramos e lançamos cada melhoria passo a passo.

Testes e métricas

Nos últimos 8 anos, adicionamos dezenas de milhares de testes de unidade, desempenho e integração. Além disso, desenvolvemos métricas abrangentes que avaliam muitos aspectos do comportamento da renderização do Chromium em testes locais, em comparativos de mercado de desempenho e em sites reais, com usuários e dispositivos reais.

Mas, mesmo que haja muitos bugs ou diferenças de comportamento entre os navegadores, por mais que o mecanismo de renderização de outro navegador seja excelente. Para resolver isso, também maximizamos o uso dos Testes da plataforma da Web. Cada um desses testes verifica um padrão de uso da plataforma da Web que todos os navegadores devem tentar passar. Também monitoramos as métricas para passar mais testes ao longo do tempo e aumentar a compatibilidade principal.

Os Web Platform Tests são uma iniciativa colaborativa. Por exemplo, os engenheiros do Chromium adicionaram apenas cerca de 10% do total de testes WPT para recursos de CSS. Outros fornecedores de navegadores, colaboradores independentes e autores de especificações contribuem com o restante. É preciso uma vila para criar a Web interoperável!

Testes aprovados em diferentes mecanismos
A partir de wpt.fyi/compat2021, medir a taxa de aprovação de WPTs para recursos principais

Bons padrões de design de software

A entrega confiável de software de qualidade será muito mais fácil se o código for fácil de entender e projetado de maneira a minimizar a probabilidade de bugs. Teremos muito mais a dizer sobre o design do software do RenderingNG nas próximas postagens do blog.

Desempenho escalonável

Atingir um ótimo desempenho nas dimensões de velocidade, memória e uso de energia é o segundo aspecto mais importante da RenderizaçãoNG. Queremos que as interações com todos os sites sejam suaves e responsivas, mas sem sacrificar a estabilidade do dispositivo.

Mas não queremos apenas desempenho, queremos um desempenho escalonável, uma arquitetura que tenha um bom desempenho confiável em máquinas de baixo e alto desempenho e em várias plataformas de SO. Eu chamo isso de escalonamento vertical, aproveitando tudo o que o dispositivo de hardware pode alcançar e reduzindo a escala, de maximizar a eficiência e reduzir a demanda no sistema quando necessário.

Para isso, precisávamos fazer o uso máximo do armazenamento em cache, do isolamento de desempenho e da aceleração de hardware da GPU. Vamos analisar um de cada vez. Para deixar isso mais concreto, vamos pensar em como cada um deles contribui para o desempenho de uma interação extremamente importante nas páginas da Web: a rolagem.

Armazenamento em cache

Em uma plataforma de IU dinâmica e interativa, como a Web, o armazenamento em cache é a maneira mais importante de melhorar drasticamente o desempenho. O tipo mais conhecido de armazenamento em cache em um navegador é o cache HTTP, mas a renderização também tem muitos caches. O cache mais importante para rolagem são as texturas de GPU e as listas de exibição, que permitem uma rolagem extremamente rápida, minimizam o consumo de bateria e funcionam bem em vários dispositivos.

O armazenamento em cache ajuda a duração da bateria e o frame rate da animação para rolagem, mas o mais importante é que ele desbloqueia o isolamento de desempenho da linha de execução principal.

Isolamento de desempenho

Em computadores desktop modernos, você nunca precisa se preocupar com aplicativos em segundo plano que deixem o aplicativo em que você está trabalhando. Isso ocorre por causa da multitarefa preventiva, que, por sua vez, é uma forma de isolamento de desempenho: garantir que tarefas independentes não atrapalhem umas às outras.

Na Web, o melhor exemplo de isolamento de desempenho é a rolagem. Mesmo em sites com muito JavaScript lento, a rolagem pode ser muito suave, porque é executada em uma linha de execução diferente que não precisa depender da linha de execução de layout e JavaScript. Dedicamos muito esforço ao RenderingNG para garantir que toda rolagem possível seja encadeada, por meio de armazenamento em cache que vai além de apenas uma lista de exibição para situações mais complexas. Os exemplos incluem código para representar elementos fixos e fixos, listeners de eventos passivos e renderização de texto de alta qualidade.

O esboço mostra que, com a RenderizaçãoNG, a performance permanece sólida mesmo quando o JavaScript está muito lento.

Aceleração de GPU

Uma GPU agiliza a geração e o desenho de pixels na tela. Em muitos casos, cada pixel pode ser desenhado em paralelo com cada outro pixel, resultando em um enorme aumento de velocidade. Um componente essencial do RenderingNG é a varredura da GPU e mostrar em todos os lugares. Esse recurso usa a GPU em todas as plataformas e em todos os dispositivos para acelerar a renderização e a animação do conteúdo da Web. Isso é especialmente importante em dispositivos de baixo custo ou muito sofisticados, que geralmente têm uma GPU muito mais potente do que outras partes do dispositivo.

O esboço mostra que o desempenho da RenderizaçãoNG não degrada muito.

Extensibilidade: as ferramentas certas para o trabalho

Assim que tivermos confiabilidade e desempenho escalonável, estamos prontos para criar com base em uma série de ferramentas para ajudar os desenvolvedores a ampliar as partes integradas do HTML, CSS e Canvas, de maneira a não sacrificar a performance e a confiabilidade.

Isso inclui APIs integradas e expostas ao JavaScript para casos de uso avançados de design responsivo, renderização progressiva, suavidade e capacidade de resposta e renderização com linha de execução.

As seguintes APIs OpenAPI, promovidas pelo Chromium, foram possibilitadas pelo RenderingNG e anteriormente eram consideradas inviáveis.

Todos eles foram desenvolvidos com especificações abertas e colaboração com parceiros da Web abertos, engenheiros em outros navegadores, especialistas e desenvolvedores da Web. Nas próximas postagens do blog, vamos nos aprofundar em cada um desses aspectos e explicar como o RenderingNG o torna possível.

  • content-visibilidade: permite que os sites evitem facilmente o trabalho de renderização para conteúdo fora da tela e a renderização em cache para visualizações de aplicativos de página única não mostradas no momento.
  • OffscreenCanvas: permite que a renderização de canvas (tanto a API 2D canvas quanto a WebGL) seja executada na própria linha de execução para um desempenho excelente. Esse projeto também é outro marco importante para a Web. É a primeira API da Web que permite que o JavaScript (ou WebAssembly) renderize um único documento de página da Web usando várias linhas de execução.
  • Consultas de contêiner: permitem que um único componente seja apresentado de forma responsiva, desbloqueando um universo inteiro de componentes prontos para usar (atualmente uma implementação experimental).
  • Isolamento de origem: permite que os sites ativem um maior isolamento de desempenho entre iframes.
  • Worklets de pintura fora da linha de execução fora da linha de execução: oferecem aos desenvolvedores uma maneira de estender como os elementos são pintados, com código executado na linha de execução do compositor.

Além das APIs da Web explícitas, a renderização NG nos permitiu enviar vários "recursos automáticos" muito significativos que beneficiam todos os sites:

  • Isolamento de sites: adiciona iframes de origem cruzada em diferentes processos de CPU para melhorar a segurança e o isolamento de desempenho.
  • Vulkan, D3D12 e Metal: aproveita APIs de nível inferior que usam GPUs com mais eficiência do que o OpenGL.
  • Mais animações compostas: SVG, cor de plano de fundo.

Estamos animados com outros recursos que serão desbloqueados pela renderizaçãoNG:

Principais projetos que compõem a renderizaçãoNG

Veja abaixo uma lista dos principais projetos em RenderingNG. As próximas postagens do blog serão detalhadas sobre cada um deles.

CompositeAfterPaint

Separa a composição de estilo, layout e pintura, permitindo uma maior confiabilidade e desempenho previsível, maior capacidade e uso de menos memória sem sacrificar o desempenho. Ele começou em 2014 e terminará este ano.

Ano Progresso
2015 Enviar listas de exibição.
2017 Enviar nova invalidação.
2018 Árvores de propriedades do navio parte 1.
2019 Árvores de propriedades do navio parte 2.
2021 Concluir o envio do projeto.

LayoutNG

Uma reescrita completa de todos os algoritmos de layout, para maior confiabilidade e desempenho mais previsível. Ele começou em 2016 e está planejado para terminar este ano.

Ano Progresso
2019 Fluxo de blocos de envio.
2020 Versão flexível, editando.
2021 Envie todo o restante.

BlinkNG

Uma limpeza sistemática e uma refatoração do mecanismo de renderização Blink em fases de pipeline claramente separadas. Isso permite melhor armazenamento em cache, maior confiabilidade e recursos de renderização reentrante ou atrasada, como visibilidade de conteúdo e consultas de contêiner. Começou em 2014 e vem trazendo melhorias contínuas desde então. Ele será concluído em 2021.

Aceleração de GPU em qualquer lugar

Um esforço de longo prazo para lançar varredura, desenho e animação de GPU em todas as plataformas, o tempo todo. A aceleração da GPU oferece uma aceleração enorme para a maioria do conteúdo, porque cada pixel pode ser processado em paralelo. Ele também é um método eficaz para melhorar o desempenho em dispositivos mais simples, que tendem a ter ainda uma GPU. Começou em 2014 e foi concluído em 2020.

Ano Progresso
2014 Suporte a Canvas. Enviado em conteúdo opcional no Android.
2016 Enviar no Mac.
2017 A GPU é usada em mais de 60% das visualizações de página no Android.
2018 Compatível com Windows, ChromeOS e Android Go.
2019 Varredura da GPU em sequência.
2020 Enviar o conteúdo restante do Android.

Rolagem encadeada, animações e decodificação

Um esforço de longo prazo para remover da linha de execução principal toda a rolagem, animações que não induzem layout e decodificação de imagem. Começou em 2011 e continua em andamento.

Ano Progresso
2011 Suporte inicial para rolagem e animação em linhas de execução.
2015 Compressão de camadas.
2016 Rolagem flutuante universal.
2017 Decodificações de imagem na linha de execução do compositor.
2018 Animações de imagens na linha de execução do compositor.
2020 Sempre compor a posição fixa.
2021 Animações de transformação de porcentagem, animações SVG.

Visualização

Um processo centralizado de varredura e desenho para o Chromium que aumenta a capacidade, otimiza a memória e permite o uso ideal dos recursos de hardware. Ele também tem outros benefícios menos visíveis para desenvolvedores da Web, mas muito visíveis para os usuários, como desbloquear o isolamento de sites e desacoplar o pipeline de renderização da renderização da interface do navegador. Começou em 2016 e será concluído em 2021.

Ano Progresso
2018 OOP-R fornecido no Android, Mac e Windows.
2019 OOP-D enviado. OOP-R enviado para qualquer lugar (exceto o Canvas). O SkiaRenderer foi fornecido no Linux.
2020 SkiaRenderer fornecido no Windows e no Android. O Vulkan é fornecido no Android.
2021 O SkiaRenderer será lançado no Mac (e em breve no ChromeOS).

Definições dos termos do gráfico acima:

OOP-D
Compositor de exibição fora do processo. A composição de exibição é o mesmo tipo de atividade que um compositor do SO. Fora do processo significa fazê-lo no processo de visualização em vez de no processo de renderização da página da Web ou no processo da interface do navegador.
OOP-R
Varredura fora do processo. O raster está convertendo listas de exibição em pixels. Fora do processo significa fazer isso no processo de visualização em vez de no processo de renderização da página da Web.
SkiaRenderer
Uma nova implementação do compositor de exibição que oferece suporte à execução em várias APIs de GPU subjacentes, como Vulkan, D3D12 ou Metal.

Renderização de tela em sequência e aceleração

Este é o projeto que colocou as peças arquitetônicas que tornaram o OffscreenCanvas possível. Começou em 2015 e termina em 2021.

Ano Progresso
2018 Enviar OffscreenCanvas.
2019 ImageBitmapRenderingContext.
2021 Enviar OOP-R.

VideoNG

Um esforço a longo prazo para proporcionar uma reprodução de vídeo eficiente, confiável e de alta qualidade na Web.

Ano Progresso
2014 Introdução de um framework de renderização baseado em Mojo.
2015 Envio do Project Butter e sobreposições de vídeo para uma renderização de vídeo mais suave.
2016 Pipeline unificado de decodificação e renderização para Android e computadores.
2017 Envio de HDR e renderização de vídeo com correção de cor.
2018 Pipeline de decodificação de vídeo baseado no Mojo enviado.
2019 Pipeline de renderização de vídeo baseado na superfície enviada.
2021 Compatibilidade com a renderização de conteúdo protegido em 4K no ChromeOS.

Definições dos termos do gráfico acima:

Mojo
Um subsistema IPC de última geração para o Chromium.
Superfície
Um conceito que faz parte do design do projeto viz.

Conclusão

Não há como me empolgar com a taxa de melhoria da renderização na Web e no Chromium. Espero que o ritmo continue a acelerar nos próximos anos, porque conseguimos criar com base na base sólida da RenderingNG.

Não perca as próximas postagens com muito mais detalhes sobre a nova arquitetura, como ela surgiu e como funciona.

Foto de dispositivos por Eirik Solheim no Unsplash (em inglês)

Ilustrações por Una Kravets.