Engenheiros das empresas Cloudflare, Mozilla, Facebook e Bloomberg um novo formato para acelerar a entrega e o processamento de código JavaScript ao abrir sites no navegador. O BinaryAST transfere a fase de análise sintática para o servidor e entrega uma árvore sintática abstrata já formada (). Ao receber o BinaryAST, o navegador pode imediatamente passar para a fase de compilação, pulando a análise do código fonte JavaScript.
Para testes uma implementação de referência, disponibilizada sob a licença MIT. Para a análise, são utilizados componentes do Node.js, e o código para otimização e geração de AST é escrito na linguagem Rust. Do lado dos navegadores, o suporte ao
BinaryAST já está disponível em do Firefox. O codificador do BinaryAST pode ser aplicado tanto no nível das ferramentas do site final quanto para empacotar scripts de sites externos do lado do proxy ou da rede de entrega de conteúdo. Atualmente, o processo de padronização do BinaryAST já foi iniciado pelo grupo de trabalho , após a conclusão do qual o formato poderá coexistir com os métodos existentes de compressão de conteúdo entregues, como gzip e brotli.
Um tempo significativo no processamento de JavaScript é gasto na fase de carregamento e análise do código. Considerando que o volume de JavaScript carregado em muitos sites populares se aproxima de 10 MB (por exemplo, para LinkedIn — 7,2 MB, Facebook — 7,1 MB, Gmail — 3,9 MB), o processamento inicial de JavaScript gera um atraso considerável. A fase de análise no lado do navegador também é retardada pela impossibilidade de construir uma AST completa em tempo real, à medida que o código é carregado (o navegador precisa esperar a conclusão do carregamento de blocos de código, como o fim de funções, para obter as informações ausentes necessárias para a análise dos elementos atuais).
Parcialmente, o problema tenta ser resolvido pela disseminação do código em formato minimizado e compactado, bem como pelo cache do bytecode gerado pelo navegador. Em sites modernos, o código é atualizado com bastante frequência, por isso o cache apenas resolve parcialmente o problema. Uma saída poderia ser o WebAssembly, mas ele exige o uso de tipagem explícita no código e não se adequa bem para acelerar o processamento de código JavaScript já existente.
Outra opção é entregar bytecode compilado em vez de scripts JavaScript, mas os desenvolvedores de motores de navegador se opõem, pois o bytecode de terceiros é difícil de verificar, seu processamento direto pode levar à fragmentação da Web, surgem ameaças adicionais à segurança e é necessário desenvolver um formato de bytecode universal.
BinaryAST permite se encaixar no modelo atual de desenvolvimento e entrega de código sem criar um novo bytecode e sem modificar a linguagem JavaScript. O tamanho dos dados no formato BinaryAST é comparável ao JavaScript comprimido e minificado, e a velocidade de processamento aumenta consideravelmente com a exclusão da fase de parsing de textos fonte. Além disso, o formato permite a compilação em bytecode à medida que o BinaryAST é carregado, sem esperar pela conclusão do recebimento de todos os dados. A análise do lado do servidor também permite excluir funções não utilizadas e código desnecessário na representação fornecida do BinaryAST, economizando tempo tanto na análise quanto na transferência de tráfego desnecessário.
Uma característica do BinaryAST é a capacidade de restaurar JavaScript legível que não é idêntico ao original, mas semanticamente equivalente e inclui os mesmos nomes de variáveis e funções (o BinaryAST mantém os nomes, mas não preserva informações sobre posições no código, formatação e comentários). O lado negativo é o surgimento de novos vetores de ataque, mas de acordo com os desenvolvedores, eles são significativamente menores e mais controláveis do que ao aplicar alternativas, como a distribuição de bytecode.
Os testes de código do facebook.com mostraram que 10-15% dos recursos da CPU são gastos na análise do JavaScript, e a análise consome mais tempo do que a geração de bytecode e a formação inicial de código para JIT. No mecanismo SpiderMonkey, o tempo total para construir o AST leva de 500 a 800 ms, e a aplicação do BinaryAST permitiu reduzir esse tempo em 70-90%.
No geral, para a maioria dos frameworks web, o uso do BinaryAST reduz o tempo de análise do JavaScript em 3-10% no modo sem otimização e em 90-97% ao ativar o modo de ignorar funções não usadas.
Ao executar um conjunto de testes JavaScript de 1,2 MB, a aplicação do BinaryAST permitiu reduzir o tempo de inicialização de 338 ms para 314 ms em um sistema de desktop (Intel i7) e de 2019 ms para 1455 ms em um dispositivo móvel (HTC One M8).
Fonte: opennet.ru
