TuBrief
구독 채널
비디오
커뮤니티

Como reduzir o tamanho de pacotes de painéis pesados do Recharts usando o TanStack Charts

TuBrief 편집팀
2026년 8월 12일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

Português한국어EnglishEspañol中文العربيةहिन्दीDeutschFrançaisРусскийBahasa Indonesia日本語

관련 영상

A TanStack Fez de Novo... Eles Consertaram os Gráficos8:14

A TanStack Fez de Novo... Eles Consertaram os Gráficos

Better Stack

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

Como reduzir o tamanho de pacotes de painéis pesados do Recharts usando o TanStack Charts

Se você entra em uma página de painel e a ampulheta fica girando só para carregar os gráficos, é quase certeza que o problema é o Recharts. Fica difícil não suspirar ao ver o tamanho do pacote inchar em centenas de quilobytes só por adicionar alguns gráficos. O Recharts fica grudado demais no ciclo de reconciliação do React. A estrutura de UI e o processamento de dados ficam emaranhados, tornando o uso leve algo difícil.

Nesses momentos, o TanStack Charts se torna uma alternativa sólida. Ele separa a lógica de visualização em um núcleo baseado em gramática gráfica. Enquanto o Recharts costuma consumir mais de 150 KiB, o TanStack Charts fica em torno de 40 KiB. O tamanho do pacote diminui em quase 70%.

O desafio é a migração do código em produção. Substituir telas que já funcionam bem sempre gera um frio na barriga. Para convencer a equipe e realizar a transição sem quebras, é preciso seguir uma ordem clara.

Removendo o código do Recharts com segurança

Tentar mudar tudo de uma vez dificulta muito a localização de erros. É preciso isolar um componente e fazer a transição dividindo-a em exatamente 4 etapas:

  1. Separação do pré-processamento de dados: Extraia a lógica de manipulação de dados que estava misturada no JSX do componente Recharts para funções puras externas.
  2. Mapeamento de marcas: Transfira as configurações de eixos e elementos visuais, como linhas e pontos, para o array marks do objeto de declaração defineChart.
  3. Substituição de utilitários: Troque o ResponsiveContainer e o Tooltip pelo dimensionador automático do TanStack e pelo módulo @tanstack/charts/tooltip.
  4. Memoização: Envolva o objeto de definição do gráfico com useMemo e passe-o para o componente raiz Chart.

Apenas seguindo essa ordem, o tempo necessário para substituir o primeiro componente de gráfico é reduzido pela metade.

`typescript
import React, { useMemo } from 'react';
import { defineChart, lineY, dot } from '@tanstack/charts';
import { scaleBand } from '@tanstack/charts/scales/band';
import { scaleLinear } from '@tanstack/charts/scales/linear';
import { tooltip } from '@tanstack/charts/tooltip';
import { Chart } from '@tanstack/charts/react';

interface DataRow {
date: string;
value: number;
}

export function MigratedRevenueChart({ data }: { data: DataRow[] }) {
const definition = useMemo(() => {
return defineChart({
marks: [
lineY(data, {
x: 'date',
y: 'value',
stroke: 'var(--ts-chart-1, #2563eb)',
strokeWidth: 2,
}),
dot(data, {
x: 'date',
y: 'value',
fill: 'var(--ts-chart-1, #2563eb)',
r: 4,
}),
],
x: {
scale: () => scaleBand().padding(0.2),
},
y: {
scale: scaleLinear,
nice: true,
grid: true,
},
tooltip: {
use: tooltip,
className: 'custom-tooltip',
},
});
}, [data]);

return (
<div style={{ width: '100%', height: 300 }}>


);
}

`

Evitando re-renderizações em JavaScript ao lidar com o modo escuro

Fazer com que o componente de gráfico inteiro seja redesenhado toda vez que o modo escuro for alternado é deselegante. O TanStack Charts suporta nativamente propriedades customizadas de CSS e currentColor em vez de valores de cores hardcoded.

Em vez de gerenciar as cores dos gráficos no estado do JavaScript, passe-as por variáveis CSS. Basta fazer com que a paleta padrão do gráfico faça referência de --ts-chart-1 até --ts-chart-6.

  1. Defina antecipadamente as variáveis para gráficos na raiz do CSS e em [data-theme='dark'].
  2. Insira strings no formato var(--ts-chart-1) em stroke ou fill nas opções do defineChart.
  3. Gerencie também os estilos de dica de ferramenta (tooltip) por meio de classes CSS e trate a cor de fundo com variáveis.

Ao estruturar dessa forma, quando o designer pedir para alterar a cor do gráfico, não será necessário mexer nos arquivos TSX. Basta ajustar o CSS.

`css
:root {
--bg-chart-card: #ffffff;
--text-chart-main: #172033;
--border-chart-grid: #e2e8f0;
--ts-chart-1: #2563eb;
--ts-chart-2: #f97316;
}

[data-theme='dark'] {
--bg-chart-card: #0f172a;
--text-chart-main: #f8fafc;
--border-chart-grid: #334155;
--ts-chart-1: #60a5fa;
--ts-chart-2: #fb923c;
}

.custom-tooltip {
background-color: var(--bg-chart-card);
color: var(--text-chart-main);
border: 1px solid var(--border-chart-grid);
padding: 8px 12px;
border-radius: 6px;
}

`

Como garantir que o sistema não trave mesmo com 100 mil dados

Renderizar 100 mil pontos em SVG gera 100 mil nós no DOM. A thread do navegador simplesmente não aguenta. A lentidão fica perceptível.

A solução consiste em combinar duas abordagens: alternar para o renderizador de Canvas para eliminar o custo de criação do DOM e comprimir dados desnecessariamente densos em relação à largura em pixels da tela usando o algoritmo LTTB (Largest Triangle Three Buckets). O LTTB reduz a quantidade de pontos preservando as características marcantes dos dados (valores máximos e mínimos).

`typescript
export function lttbDownsample(
data: T[],
xAccessor: (d: T) => number,
yAccessor: (d: T) => number,
threshold: number
): T[] {
const dataLength = data.length;
if (threshold >= dataLength || threshold === 0) return data;

const sampled: T[] = [];
let sampledIndex = 0;
const bucketSize = (dataLength - 2) / (threshold - 2);

sampled[sampledIndex++] = data[0];

for (let i = 0; i < threshold - 2; i++) {
let avgX = 0;
let avgY = 0;
const avgRangeStart = Math.floor((i + 1) * bucketSize) + 1;
const avgRangeEnd = Math.floor((i + 2) * bucketSize) + 1;
const currentAvgRangeEnd = avgRangeEnd < dataLength ? avgRangeEnd : dataLength;

for (let j = avgRangeStart; j < currentAvgRangeEnd; j++) {
  avgX += xAccessor(data[j]);
  avgY += yAccessor(data[j]);
}
avgX /= (currentAvgRangeEnd - avgRangeStart);
avgY /= (currentAvgRangeEnd - avgRangeStart);

const rangeOffs = Math.floor((i + 0) * bucketSize) + 1;
const rangeTo = Math.floor((i + 1) * bucketSize) + 1;
const pointAX = xAccessor(sampled[sampledIndex - 1]);
const pointAY = yAccessor(sampled[sampledIndex - 1]);

let maxArea = -1;
let maxAreaPointIndex = rangeOffs;

for (let j = rangeOffs; j < rangeTo; j++) {
  const area = Math.abs(
    (pointAX - avgX) * (yAccessor(data[j]) - pointAY) -
    (pointAX - xAccessor(data[j])) * (avgY - pointAY)
  ) * 0.5;

  if (area > maxArea) {
    maxArea = area;
    maxAreaPointIndex = j;
  }
}
sampled[sampledIndex++] = data[maxAreaPointIndex];

}

sampled[sampledIndex++] = data[dataLength - 1];
return sampled;
}

`

Ao lidar com séries temporais de grande volume, reduza os dados para cerca de 1000 itens usando o LTTB antes de repassá-los. Em seguida, ative a opção spatialIndex: true para diminuir a complexidade de detecção do ponteiro do mouse. Por fim, adicione o renderizador de Canvas do pacote @tanstack/charts/react/canvas para garantir uma taxa fluida de 60 fps.

Como delegar a criação de código de gráficos para o Cursor ou Copilot

Bibliotecas com tags JSX profundamente aninhadas, como o Recharts, costumam fazer com que assistentes de IA gerem alucinações facilmente. Eles inventam propriedades estranhas ou deixam tags abertas.

Bibliotecas baseadas em declaração de objetos, como o TanStack Charts, geram códigos limpos pela IA desde que se forneça o esquema de tipos adequado. Defina um tipo de esquema como o abaixo em seu projeto e inclua-o nas instruções de prompt da IA ou no arquivo de regras (.cursorrules).

`typescript
export type ScaleType = 'linear' | 'band' | 'utc' | 'point';
export type MarkType = 'lineY' | 'barY' | 'dot' | 'areaY';

export interface AIScaleConfig {
type: ScaleType;
nice?: boolean;
grid?: boolean;
padding?: number;
}

export interface AIMarkConfig {
type: MarkType;
xKey: string;
yKey: string;
color?: string;
strokeWidth?: number;
}

export interface AIChartGenerationSchema {
data: Record<string, unknown>[];
scales: {
x: AIScaleConfig;
y: AIScaleConfig;
};
marks: AIMarkConfig[];
tooltip?: {
enabled: boolean;
className?: string;
};
}

`

Se você adicionar regras ao prompt — como instruir a IA a importar a partir de subcaminhos precisos (ex: @tanstack/charts/scales/linear) e a utilizar o useMemo —, poderá utilizar o código gerado pela IA imediatamente, sem necessidade de correções.