O inchaço do JavaScript em 2024
(tonsky.me)- À medida que se tornam comuns casos em que páginas web baixam JavaScript não compactado muito maior que o conteúdo real, o peso sobre o navegador cresce — de landing pages simples a apps corporativos
- A medição foi feita no Firefox no macOS, com extensões e cache desativados, contabilizando apenas JavaScript, com foco no custo de execução do código e excluindo imagens, vídeos e estilos
- A Wikipedia ficou em 0,2 MB, mas até páginas simples chegaram de alguns MB a dezenas de MB, como Linear com 3 MB, Zoom e Vercel com 6 MB, e GitLab com 13 MB
- Na área de apps, Gmail com 20 MB e FastMail com 2 MB mostraram uma diferença de 10 vezes, enquanto o volume de código de ferramentas de chat e trabalho é particularmente grande, como Jira com cerca de 50 MB e Slack com 55 MB
- Mesmo depois do download, JavaScript gera custos de parsing, manutenção em memória e execução, portanto uma estrutura que exige enormes bundles de código para renderizar conteúdo pequeno pesa diretamente sobre desempenho e bateria
Método de medição e critérios de comparação
- O ambiente de medição foi Firefox no macOS, partindo do pressuposto de que os resultados seriam em geral semelhantes em outros navegadores
- As condições foram as seguintes
- Modo normal, não modo anônimo
- Todas as extensões desativadas
- Medição de apenas JavaScript
- Tamanho sem compactação
- Service Worker ativado
- Carregamento frio com cache desativado
- O conteúdo foi excluído da comparação porque varia muito entre sites
- Um vídeo do YouTube e mensagens de texto no Slack têm tamanhos essencialmente diferentes
- JavaScript foi usado como métrica comum para comparar a complexidade de interação
- O ponto central é a quantidade de trabalho que o navegador precisa assumir para fazer parsing e executar o código
- Como referência, o próprio blog tonsky.me foi medido em 0,004 MB
Landing pages e conteúdo estático
- Em um exemplo de página comum com alguma interação, a Wikipedia fica na faixa de 0,2 MB
- Landing pages mais pesadas são as seguintes
- Linear: 3 MB
- Zoom: 6 MB
- Vercel: 6 MB
- GitLab: 13 MB
- Os números acima representam o tamanho de apenas o código JavaScript, excluindo imagens, vídeos e estilos
- Mesmo sites que exibem texto estático baixam vários MB de JavaScript
- Medium: 3 MB
- Substack: 4 MB
- Quora: 4,5 MB
- Pinterest: 10 MB
- Patreon: 11 MB
- Há casos em que grandes bundles de JavaScript são usados para uma tarefa de exibição de conteúdo que pareceria possível como página estática
Busca e apps de interação simples
- Apps centrados em busca se concentram em entrada de consulta e exibição de uma lista de resultados, mas o tamanho do JavaScript não é pequeno
- StackOverflow: 3,5 MB
- NPM: 4 MB
- Airbnb: 7 MB
- Booking.com: 12 MB
- A busca do Google foi medida em 9 MB, embora a tela seja centrada em um campo de texto e uma lista de links
- Serviços com UI de entrada simples também usam vários MB de JavaScript
- Google Translate: 2,5 MB
- ChatGPT: 7 MB
- Independentemente de a complexidade do ChatGPT estar no lado do servidor, 7 MB de JavaScript chegam ao navegador
Serviços de mídia e e-mail
- O tamanho de JavaScript de serviços de vídeo é o seguinte
- Loom: 7 MB
- YouTube: 12 MB
- Pornhub: 1,4 MB
- Em serviços de áudio, SoundCloud e Spotify foram medidos em cerca de 12 MB cada
- Em serviços de e-mail, a diferença é grande
- Google Mail: 20 MB
- FastMail: 2 MB
- O FastMail usa 10 vezes menos JavaScript que o Google Mail dentro da mesma categoria de serviços de e-mail
- Os 20 MB do Google Mail são um número grande o bastante para ser comparado a apps que incluem renderização customizada em C++/OpenGL, como o Figma
Ferramentas de produtividade e edição de documentos
- Apps de produtividade também têm muito JavaScript em relação a tarefas simples
- Todoist: 9 MB
- Dropbox: 10 MB
- 1Password: 13 MB
- Trello: 13,5 MB
- Discord: 21 MB
- Dropbox usa mais de 10 MB para tarefas como listar arquivos em uma pasta; 1Password, para listar senhas; e Trello, para exibir cartões
- Serviços de edição de documentos ficam na casa de dezenas de MB
- Google Docs: 13,5 MB
- Notion: 16 MB
- Edição de documentos inclui recursos difíceis, como movimentação do cursor e sincronização, mas o tamanho de JavaScript dos serviços comparados ainda é grande
Redes sociais e casos gigantes
- Redes sociais geralmente usam por volta de 12 MB de JavaScript para curtidas, feeds, mensagens etc.
- Twitter: 11 MB
- Facebook: 12 MB
- TikTok: 12,5 MB
- Instagram: 16 MB
- LinkedIn: 31 MB
- O LinkedIn inclui blog, plataforma, busca, mensagens e recursos sociais, e foi medido em 31 MB
- Casos de webapps muito grandes ficam quase em uma categoria à parte
- Jira: quase 50 MB
- Slack: 55 MB
- O Slack é um app de chat que lida com lista de usuários, mensagens e reações, mas baixa 55 MB de JavaScript
- react.dev começa inicialmente com 2 MB, mas foi observado que o JavaScript continua aumentando com rolagens repetidas
- No exemplo, foi possível fazê-lo crescer até 100 MB
- Segundo a atualização, na experiência de usuários comuns o editor de código embutido é salvo em cache após o primeiro carregamento, então tráfego de rede posterior não aparece
- Ainda assim, ao rolar a página, 100 MB de JavaScript podem continuar sendo parseados, avaliados e inicializados
O que 10 MB de código significam
- Em 2015, o tamanho médio de uma página web estava se aproximando dos 2,5 MB da versão shareware de Doom 1
- Em 2024, o Slack chega, apenas com JavaScript, aos 55 MB do tamanho total dos recursos do Quake 1 original
- 10 MB de código podem parecer algo normal, mas, supondo uma média de 65 caracteres por linha, isso equivale a cerca de 150 mil linhas
- Como esse código já está minificado, no código-fonte original pode corresponder a mais de 300 mil linhas
- O Google Maps é citado como um exemplo representativo de SPA, mas foi medido em 4,5 MB, o que o torna comparativamente pequeno pelos padrões de webapps modernos
- O Figma é um app de frontend complexo, então é natural que seu tamanho de download de JavaScript seja grande, mas o Gmail é semelhante ao Figma, o LinkedIn tem 1,5 vez esse volume, e o Slack, 2,5 vezes
O custo pago pelo navegador
- O problema não termina no tamanho do download
- JavaScript cria um custo contínuo porque o navegador precisa fazer parsing, mantê-lo na memória e executá-lo
- Pelo critério de que o tamanho do conteúdo deveria ser maior que o tamanho do código, uma estrutura que exige JavaScript 1000 vezes maior para renderizar um post de blog de 10 mil caracteres é excessiva
- O site mencionado como bom exemplo funciona suficientemente bem com apenas 0,1 MB de JavaScript
- No mesmo ambiente web, o GitLab é comparado como um caso que exige 13 MB, ou mais de cerca de 500 mil linhas de JavaScript, para exibir uma landing page estática
1 comentários
Opiniões no Hacker News
Basta comparar coisas de 10 MB, 12 MB, etc. com o Pornhub, de 1,4 MB, que realmente se preocupa com desempenho
Sites pornô sempre foram alta tecnologia de verdade na web e também tinham boa engenharia, ao contrário das grandes empresas de “tech” que parecem piada
Quase não me lembro de terem estragado a UI/UX básica, a entrega de conteúdo ou um design de bom senso
Parece que, só porque em aplicações web reais recarregar a página era um comportamento indesejado, de repente todo mundo passou a ter medo de recarregar páginas em sites
Trabalhei com aplicações corporativas por 20 anos e vi até sistemas criados antes de eu nascer; acho que, nesses sistemas, o React foi o melhor frontend para substituir as antigas e terríveis UIs cliente/servidor
Angular/Vue etc. entram no mesmo contexto. Mas para páginas web comuns isso quase nunca é necessário, a menos que a interação e as atualizações em tempo real sejam o núcleo do produto, como no Gmail ou Facebook
Para algo como o Pornhub, PHP já é suficiente, e o mesmo vale para a maioria dos sites. Basta ver quantas pessoas ainda preferem HN ou old.reddit.com; acho que muita gente também preferiria o old.Facebook ao novo Facebook, que ficou mais lento
Pop-ups, pop-unders, mandar para agregadores parecidos com conteúdo falso, abrir sites afiliados em vez do conteúdo, poluir resultados de busca e coisas do tipo
Pornografia não é uma indústria que impulsiona a tecnologia tanto quanto dizem; a lenda urbana sobre Betamax vs. VHS também não é verdadeira, e a ideia de que ela liderou a inovação na internet é exagerada
Existem alguns players que fazem produtos de alta qualidade, mas eles não representam o setor como um todo. Há muitas fazendas de links, conteúdo de fachada, sites clonados, publicidade enganosa e manipulação de resultados de busca
A rapidez dos principais sites hoje parece ser resultado da concorrência. Se a UX é ruim, há pornografia gratuita em abundância e o usuário vai direto para outro lugar, então eles precisam otimizar para retenção
Outros sites têm incentivos diferentes, como acionistas, provedores de conteúdo, contratos exclusivos e posições monopolistas, então não precisam otimizar tanto a experiência do usuário
Gastam incontáveis horas otimizando todo tipo de coisa: entrega de vídeo, transmissões ao vivo (antes em Flash, agora em WebRTC), tamanho das páginas etc.
Fico me perguntando por que estão olhando para os dados antes da compressão. Mesmo alguns sites citados como exemplos ruins ficam facilmente menores que os 1,5 MB do GMaps depois de comprimidos
Acho que aplicações dinâmicas como Spotify ou GMail são aceitáveis se a navegação depois do carregamento da página for rápida
Algo como o Discord, que leva alguns segundos para atualizar na inicialização, é melhor do que o GitLab, que faz você esperar até 2 segundos a cada clique
Acho que, em alguns sites, a prioridade atual dada a cold start e renderização estática acaba piorando a experiência
Como experimento, tente navegar pela árvore de arquivos no GitHub; no meu dispositivo, ela parece muito mais ágil do que outras partes do GitHub. Por coincidência, essa é uma das poucas partes que não usa renderização estática
Clico em centenas de páginas do GitHub todos os dias, e eu preferiria que enviassem uma quantidade enorme de JavaScript uma vez e cacheassem o máximo possível, em vez de baixar o rodapé inteiro de novo toda vez que quero ver um pipeline
[1]: GMail e Spotify são só exemplos; na prática, não uso nenhum dos dois
Esse problema aparece com frequência em discussões sobre alcance: há uma grande diferença de desempenho de CPU entre iOS e Android e, olhando para aparelhos baratos muito usados pelo público geral, há casos em que um Android novo vendido hoje é mais lento que um iPhone de 2014
Se os desenvolvedores usam apenas o iPhone mais recente ou Androids topo de linha, é fácil deixar passar o quanto o inchaço do código afeta o usuário mediano
https://infrequently.org/2024/01/performance-inequality-gap-...
O cache reduz o custo de energia e tempo de download e descompressão, mas não elimina o custo do uso real
Pela minha regra prática pessoal, quanto maior o JavaScript antes da compressão, mais código a CPU continua executando quando você move o mouse, pressiona uma tecla ou rola a página
É melhor abrir mão de um pouco de eficiência de tempo e ganhar eficiência energética; onde for possível substituir por CSS, prefiro algo estático a animações bonitas
Ou talvez o problema realmente maior sejam sites que baixam mais arquivos em várias ações além de um clique que leva a URL para outra página. Isso é inchaço oculto e também é péssimo para arquivamento
Eu preferiria que não usassem JavaScript para mostrar outra “página” mantendo a URL da barra de endereços igual. Isso também é muito ruim para arquivamento
Outra regra prática é que, quanto maior o JavaScript antes da compressão, menor a chance de a versão arquivada do site funcionar corretamente
Na semana passada minha internet estava lenta e, quando eu clicava em um arquivo no site do GitHub, ele tentava carregar via script e falhava; a árvore de arquivos literalmente não funcionava
Em vez disso, se eu copiava a URL do arquivo e colava na barra de endereços do navegador, carregava corretamente
O Spotify tem grandes problemas de conectividade de rede. Mesmo se você baixar um álbum, ele entra em pânico total quando a rede muda. Um modo offline simples é melhor do que continuar tentando ficar online
É difícil julgar toda essa arquitetura por ele; é parecido com apontar para uma SPA muito ruim e dizer que todas as SPAs são ruins
Todo software reflete a cara da organização que o criou
A maior parte dos dados transmitidos provavelmente não é o JavaScript realmente necessário para o funcionamento da página, mas ferramentas de análise e diversos scripts de terceiros
Só a categoria “elephant” corresponde a módulos carregados sob demanda, como React
Boa parte disso é conduzida por equipes de marketing que não conhecem ou não se importam com esse problema
Muitas vezes, os desenvolvedores só anexaram à página o Google Tag Manager ou algum outro serviço de injeção de scripts. Em alguns casos, o desenvolvedor nem fez isso; um proxy na infraestrutura de operação modifica a página
Uma preocupação mais significativa talvez seja o fato de o marketing ter mais controle sobre o resultado do que as pessoas que fazem o trabalho de fato
No caso das páginas “elephant”, o inchaço está na própria organização. Não é problema de alguns idiotas, mas de idiotas em escala
No meu emprego anterior, um departamento não técnico controlava o Google Tag Manager, e precisávamos ficar monitorando constantemente o lixo injetado nas páginas de produção
Lutamos muito para tentar removê-lo
O Google Search era assim em comparação com o Yahoo, e o Chrome também era assim em relação ao IE/Firefox quando foi lançado
O próprio Chrome quase não tinha interface, e isso era um recurso
Voltei recentemente de uma road trip pela Nova Zelândia, e em boa parte das áreas rurais há pouquíssimo ou nenhum sinal de celular
Com roaming por cima, parecia haver mais uma camada de lentidão, então usar boa parte da web foi realmente difícil
Se houver algum PM do Spotify por aqui, gostaria que revisassem a UX offline. O offline é um dos recursos centrais do Premium, mas, na prática, tentar usar o app offline é péssimo em vários aspectos
Quando o Spotify decide que há internet, ele consulta o servidor para todo o conteúdo dos menus de contexto, espera alguns segundos por uma resposta e, às vezes, desiste de mostrar o menu; outras vezes, volta para uma ação que teria sido imediata se estivesse em modo offline
Eu detesto esse player
Em estados intermediários com latência muito alta ou muita perda, ele deveria se comportar como offline, mas o Spotify acha que está online
Dito isso, esse problema é muito comum, não é só o Spotify que falha nisso, e definir o limiar correto deve ser difícil mesmo
Não entendo por que o Spotify me faz esperar 30 segundos para o app carregar alguma coisa quando não há sinal. Eu só quero continuar ouvindo um podcast que já baixei
Fico curioso sobre qual decisão de engenharia tornou tão complicado ponderar esse cenário
O texto erra completamente, em especial por não decompor por que os arquivos JavaScript são tão grandes em aplicações web reais
Por exemplo, se você olhar de perto, o Google Tradutor não é um app de uma única interação e pronto. Ele tem dicionário, sugestões alternativas, transliteração, pronúncia, vários métodos de entrada etc.
Mesmo levando isso em conta, 2,5 MB é grande demais, e acho que alguns recursos opcionais podem e devem ser carregados sob demanda, mas o texto atual é preguiçoso demais para ajudar muito em uma discussão mais profunda
Quanto JavaScript seria necessário para
if data.transliteration show icon with audio embed?Entendo que as imagens podiam ser grandes e numerosas, mas foi um pouco irônico
Sei que a implicação aqui é “há JavaScript demais”, mas também é preciso falar sobre quanto disso é puro lixo de rastreamento
O pior é que algumas delas não ficam vinculadas ao código hospedado, sendo buscadas externamente, o que aumenta a latência e os riscos potenciais de segurança
Era uma ferramenta que permitia a profissionais de marketing injetar qualquer lixo na aplicação web sem intervenção de desenvolvedores
As relações ficaram meio desgastadas, não vencemos, e a performance continua péssima
Depois disso, o que causa problemas de performance são bibliotecas pesadas, como mapas e gráficos, e normalmente isso se resolve com carregamento sob demanda inteligente
Entre coisas que vivi: carregar, na inicialização, uma biblioteca de leitura de QR code e uma biblioteca de mapas por causa de um recurso minúsculo; buscar todas as strings de internacionalização na inicialização em requisições em cascata, bloqueando antes que qualquer JS pudesse rodar; e o Zendesk arruinar completamente a performance da página, mas, por ordem de cima, só podíamos colocá-lo em carregamento sob demanda
Em seguida vem código mal projetado que causa elementos DOM demais, rerenderizações demais ou requisições em cascata demais
Por fim vem o tamanho do código no nível da aplicação, que também pode ser corrigido com carregamento sob demanda, mas normalmente não é necessário antes de a aplicação ficar muito grande
Por exemplo, a landing page do GitLab caiu de 13 MB para “apenas” 6 MB ao bloquear scripts de rastreamento
O departamento de marketing sempre vai dobrar o inchaço do software
Um comparativo de quanto JavaScript sites populares carregam em um cold load. Os principais pontos são os seguintes
O PornHub carrega cerca de 10 vezes menos JS que o YouTube (1,4 MB contra 12 MB)
O Gmail tem um footprint grande a ponto de ser difícil de entender (20 MB). O Fastmail é 10 vezes mais leve, com 2 MB, e o Figma tem cerca dos mesmos 20 MB mesmo sendo um app mais complexo
O Jira ter 58 MB é absurdo
O Jira provavelmente será carregado localmente como um app offline depois de baixado uma vez, até a próxima atualização
O Pornhub tem alta chance de ser executado no modo anônimo, então o cache não ajuda
O Jira também é horrível e lento
Todas as páginas de https://wordsandbuttons.online/ continuam com menos de 64 KB, mesmo tendo animações e interações
Por exemplo, esta página https://wordsandbuttons.online/trippy_polynomials_in_arctang... tem 51 KB
O código também não é nada econômico. Uns 80% são copiados e colados com pequenas variações, sem nenhuma tentativa esperta de reduzir. É tudo vanilla JS antigo, sem compressão nem remoção de espaços em branco
Se abrir em “View page source”, o código fica totalmente legível
O segredo é uma política de zero dependências. Não há dependências de terceiros nem internas. Todo o código necessário vem junto com o arquivo HTML
Paradoxalmente, no longo prazo, copiar e colar não é a causa do inchaço, mas uma prevenção contra ele
No celular, as bordas literalmente não aparecem
Dependências em si não são a causa, mas um sintoma. Como sites e empresas já não têm incentivo para reduzir o inchaço, dependências duplicadas quase nunca são limpas
Isso me lembra o artigo The Website Obesity Crisis de 2015 [1]. Desde então [2], a situação piorou, e já se passaram quase 10 anos
Seria tolice dizer que daqui a 10 anos navegar na web em um PC de por volta de 2015 será impossível? Se nada mudar, parece que sim
Mesmo com o Firefox mais recente em um MacBook antigo de 2013, ele não aguenta os 23,98 MB de JavaScript da página https://civitai.com e trava por uns 30 segundos tentando renderizar esse front-end web desastroso
Não é um problema só da web. Apps móveis tudo-em-um também ficaram grandes demais, a ponto de igualmente não carregarem em um celular de 2013, e metade deles é escrita sobre uma stack de tecnologias web
Não sei por que empresas com grandes orçamentos não têm condições de usar aplicações nativas
[1] https://idlewords.com/talks/website_obesity.htm
[2] https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
O estado da web é muito triste
A maioria das pessoas com conexão de fibra nem percebe o quanto a web ficou lenta
Mas, se você ainda está em uma conexão de 2 Mbps, é realmente terrível. Eu estou nessa situação, e é sofrido
Por isso, não usar bloqueador de anúncios/rastreamento está totalmente fora de questão
Queria ver esse teste com o Ublock Origin ativado
Imagino que boa parte desse código seja para rastrear usuários e gerenciar anúncios
Não entendo se a ideia é que, mesmo com computadores melhores e mais rápidos e velocidades de rede maiores, ainda deveríamos continuar focando em tornar apps e sites cada vez menores
Graças à lei de Moore, desenvolvedores puderam sacrificar otimização, forçar mais a barra e avançar rápido, e isso acontece com frequência