O Contexto
O Bloom é utilizado por grandes corporações para alinhar suas operações aos 17 Objetivos de Desenvolvimento Sustentável da ONU. Isso envolve cruzar dados financeiros, logísticos e humanos.
Como Engenheiro Frontend, meu papel principal foi garantir que dashboards analíticos conseguissem renderizar e filtrar dezenas de milhares de registros em tempo real no navegador, mantendo a taxa de atualização em 60 FPS, independentemente da máquina do usuário.
Arquitetura & Tecnologias
Frontend Core
- • React
- • TypeScript
- • Styled Components
- • Material UI (MUI)
Backend
- • Node.js
- • REST API
- • Middleware Auth
- • Integração JSON
Qualidade
- • Jest (Unit Test)
- • SOLID Principles
- • Clean Code
- • Componentização
DevOps/Agile
- • CI/CD Pipelines
- • GIT / Gitflow
- • SCRUM / JIRA
- • Code Review
O Gargalo de Performance
A renderização inicial dos relatórios carregava mais de
25.000 nós no DOM simultaneamente. Isso causava o
congelamento da Main Thread (block time > 4s) em laptops
corporativos padrão.
O desafio era manter a funcionalidade de "Busca Global" e
"Ordenação" no Front-end (para evitar round-trips ao servidor) sem
travar a interface do usuário.
A Solução Técnica
Implementei uma estratégia de
Virtualização (Windowing) customizada. Em vez de
renderizar a lista inteira, o React mantém no DOM apenas os itens
visíveis no viewport (+ um pequeno buffer).
Além disso, utilizei princípios **SOLID** para desacoplar a lógica
de negócio da camada de visualização com **Styled Components**,
garantindo manutenibilidade.
// Hook customizado para gerenciar renderização virtual de 10k+ itens
export const useVirtualization = <T>(
items: T[],
height: number
) => {
const [scrollTop, setScrollTop] = useState(0);
const visibleCount = Math.ceil(window.innerHeight / height);
const startNode = Math.floor(scrollTop / height);
// Renderiza apenas o necessário + buffer de segurança
const visibleItems = useMemo(() => {
return items.slice(
startNode,
startNode + visibleCount + 5 // +5 Buffer items
);
}, [items, startNode, visibleCount]);
return { visibleItems, startNode, totalHeight: items.length * height };
};