System Design para Frontend
Como estruturar uma entrevista de system design focada em frontend: componentes, estado, performance.
Definição
System design frontend avalia como você pensa em escala: componentes reutilizáveis, gerenciamento de estado global, comunicação com APIs, caching, performance, acessibilidade e deploy. Diferente do backend, o foco é em UX e responsividade. As perguntas típicas: "Como você construiria o Feed do Twitter?", "Projete um autocomplete", "Como você faria uma grid de imagens infinita?".
Problema → Solução
Problema
Candidatos focam demais em código e esquecem de discutir trade-offs, escalabilidade e decisões de arquitetura. Ou o oposto: ficam muito abstratos sem demonstrar conhecimento técnico concreto.Solução
Framework para responder: 1) Clarificar requisitos (funcional e não-funcional), 2) Estimativas (usuários, requests, tamanho de dados), 3) High-level design (componentes principais), 4) Deep dive (o que o entrevistador pedir), 5) Trade-offs e melhorias.Dica de entrevista
Tip
Em frontend system design, sempre mencione: renderização (CSR/SSR/SSG), estado (local vs global vs server state), performance (lazy loading, code splitting, caching), acessibilidade e testes. Demonstra que você pensa além do código feliz.Código
// Autocomplete com debounce + cache + cancelamento
function useAutocomplete(query: string) {
return useQuery({
queryKey: ['autocomplete', query],
queryFn: async ({ signal }) => {
const res = await fetch(`/api/search?q=${query}`, { signal })
return res.json()
},
enabled: query.length > 1,
staleTime: 5 * 60 * 1000, // cache por 5min
})
}
// Infinite scroll com IntersectionObserver
function useInfiniteScroll(callback: () => void) {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) callback() },
{ threshold: 0.1 }
)
if (ref.current) observer.observe(ref.current)
return () => observer.disconnect()
}, [callback])
return ref
}
// Uso com React Query infinite
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
queryKey: ['images'],
queryFn: ({ pageParam = 1 }) => fetchImages(pageParam),
getNextPageParam: (last) => last.nextPage,
})
const loaderRef = useInfiniteScroll(() => {
if (hasNextPage) fetchNextPage()
})Perguntas de entrevista
Q.Como projetaria um autocomplete escalável?▾
A.Debounce de 200-300ms para reduzir requests. Cache de resultados anteriores (Map ou React Query cache). Cancelamento de request anterior com AbortController. Virtualização da lista se muitos resultados. Acessibilidade: aria-combobox, aria-listbox, navegação com setas. Highlight do match no texto.
Q.Como projetaria um infinite scroll de imagens?▾
A.IntersectionObserver para detectar quando o usuário chega ao fim. React Query com useInfiniteQuery para gerenciar paginação e cache. Virtualização (react-virtual ou react-window) para não manter todos os itens no DOM. Skeleton loading por placeholder. Otimização de imagens: lazy loading nativo, WebP, tamanhos responsivos.
Q.Qual a diferença entre CSR, SSR e SSG?▾
A.CSR: renderiza no browser, TTI alto, ruim para SEO. SSR: renderiza no servidor por request, TTFB maior mas TTI menor, bom para SEO e dados dinâmicos. SSG: renderiza no build, TTFB mínimo, ótimo para conteúdo estático ou com revalidação (ISR). Escolha: SEO crítico + dados dinâmicos = SSR; SEO + dados estáticos = SSG; app autenticado sem SEO = CSR.
Termos relacionados
78/122← →