stamatios
← Voltar ao feed
Polaris Signals turbina dashboard de profiler trocando SVG por Canvas
Dev & Engenharia · Produto & Design

Polaris Signals turbina dashboard de profiler trocando SVG por Canvas

resumo de ~3 min

Do SVG ao Canvas: o problema dos nós DOM

A Polar Signals reconstruiu o dashboard de profiling trocando SVG por Canvas. O renderer antigo usava SVG, onde cada frame do flame graph era um <rect> e um <text> - dezenas de milhares de nós DOM que o navegador precisava estilizar, calcular layout, pintar e depois coletar via garbage collector. Para evitar travar a aba, o renderer antigo desenhava em lotes de ~500 nós por frame, mas isso apenas tratava o sintoma. O problema fundamental era pedir ao browser para gerenciar uma quantidade enorme de estrutura.

Retained-mode vs. immediate-mode

SVG e DOM são APIs retained-mode: o browser mantém uma árvore de elementos e re-renderiza quando algo muda. Canvas é immediate-mode: você emite comandos de desenho (fillRect, fillText), o browser converte em pixels e esquece. Sem nós para estilizar ou caixas para calcular layout, o custo de renderização passa a escalar com o número de frames efetivamente desenhados, não com o total que o browser precisa "lembrar".

O flame graph como query SQL e dados colunares

Com a reescrita do querier em Rust, o flame graph virou saída de uma função SQL. O querier constrói a árvore, calcula posição e largura de cada frame e envia os dados em formato Arrow colunar (cada campo - x, width, depth - em seu próprio array). Os dados chegam via Arrow Flight em formato IPC, e como o layout na rede é idêntico ao layout em memória, a conversão é zero-copy: sem parsing nem cópia para novos objetos JavaScript.

Números: 3,6x mais rápido isolado, até 14x na página real

No teste isolado (fixture replay, mesmo perfil de ~17.000 frames), o SVG levou mediana de 164 ms e o Canvas 46 ms - 3,6x mais rápido, com custo por frame caindo de 9,2 µs para 2,8 µs. Na página real, onde o renderer antigo compete pela main thread com o resto da aplicação, a diferença é ainda maior: first-render caiu de 448 ms para 42 ms (10,7x), zoom de 121 ms para 29 ms (4,2x), reset de 528 ms para 47 ms (11,3x) e scroll de ~30 ms para ~6 ms. Em interações de hover com CPU throttled 15x, o Canvas manteve 118,5 fps com apenas 1 frame perdido, contra 60,6 fps e 58 frames perdidos do SVG.

Trade-offs e o que fica pendente

Canvas elimina tudo que o DOM fazia de graça: hit-testing agora é matemática invertida (y do mouse dividido pela altura da linha, scan horizontal para achar o frame), tooltips são renderizados por React sobre o canvas, truncamento de texto é manual, e telas high-DPI exigem escalar o backing store por devicePixelRatio. A maior perda é acessibilidade: o canvas é opaco para screen readers e não permite seleção de texto - problema ainda sem solução completa.