惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
博客园 - 司徒正美
V
Visual Studio Blog
博客园 - 【当耐特】
T
Tailwind CSS Blog
美团技术团队
博客园 - 叶小钗
Jina AI
Jina AI
宝玉的分享
宝玉的分享
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
人人都是产品经理
人人都是产品经理
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Guia Definitivo para Otimizar Aplicações FastAPI: 5 Estra...
Gustavo Garc · 2026-04-25 · via DEV Community

Gustavo Garcia Pereira

Aprenda 5 técnicas práticas para melhorar o desempenho de apps FastAPI com Python e Vue.js. Exemplos de código, erros comuns e um caso real incluídos!


Você já colocou uma aplicação FastAPI + Vue.js em produção e percebeu que a performance não era bem o que os benchmarks prometiam?

Calma, não é culpa do framework. O FastAPI é rápido por construção, mas a velocidade some quando fazemos escolhas síncronas, esquecemos o cache ou deixamos o front-end carregar tudo de uma vez. Este guia é para quem quer ir além do básico e aplicar otimizações que realmente fazem diferença, sem rodeios. Vou te mostrar 5 estratégias — do event loop ao lazy loading — com código na mão e aquele “porquê” que ajuda a fixar o conceito.


1. Async/Await: Domine a Execução Não-Bloqueante (Python)

O problema que quase todo mundo enfrenta

Rotas definidas com def (síncronas) são executadas em uma thread pool externa no FastAPI, mas, mesmo assim, para operações I/O puras (chamadas HTTP, leitura em disco, queries simples) elas acabam concorrendo de forma ineficiente. O resultado? Throughput menor e latência maior sob carga.

A solução na prática

Use async def sempre que a rota fizer operações de entrada/saída que possam ser aguardadas. O segredo está em todas as camadas serem assíncronas: biblioteca HTTP, driver do banco, cliente de cache.

from fastapi import FastAPI
import httpx

app = FastAPI()

@app.get("/dados-externos")
async def fetch_data():
    async with httpx.AsyncClient() as client:
        resposta = await client.get("https://api.externa.com/dados")
    return resposta.json()

Enter fullscreen mode Exit fullscreen mode

Por que isso faz tanta diferença?

Enquanto a versão síncrona com requests bloqueia a thread inteira até a resposta chegar, a versão assíncrona libera o loop de eventos para processar outras requisições. Em um teste caseiro com 10 workers e chamadas a uma API externa (latência de ~200ms), observei um salto típico de 100 req/s para mais de 1500 req/s. O ganho é brutal em cenários I/O-bound.

Fique de olho:

Se dentro de uma rota async def você usar time.sleep() ou uma biblioteca bloqueante (ex.: requests.get), você anula todo o benefício. Mantenha o ecossistema async — e monitore com ferramentas como py-spy para achar gargalos silenciosos.


2. Cache de Dados com Redis (Python + Docker)

O cenário clássico

Consultas repetidas ao banco para dados que mudam pouco (catálogo de produtos, configurações, resultados de análises) geram latência desnecessária e pressionam o banco de dados. A resposta é tão simples quanto poderosa: uma camada de cache.

Implementação direto ao ponto

Aqui usamos o Redis com o cliente redis-py (modo async). A ideia é verificar o cache antes de bater no banco e, se não existir, popular o cache após a consulta.

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from redis import asyncio as aioredis
import json

app = FastAPI()
redis = aioredis.from_url("redis://localhost")

@app.get("/produto/{id}")
async def get_produto(id: int):
    cache_key = f"produto:{id}"
    cached = await redis.get(cache_key)
    if cached:
        return JSONResponse(content=json.loads(cached))

    # Simula consulta ao banco (substitua aqui pela sua query real)
    produto = {"id": id, "nome": "Produto X", "preço": 99.90}

    # Cache com TTL de 60 segundos
    await redis.setex(cache_key, 60, json.dumps(produto))
    return produto

Enter fullscreen mode Exit fullscreen mode

Ambiente rápido com Docker

Se ainda não tem o Redis rodando, um docker-compose resolve em segundos:

services:
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"

Enter fullscreen mode Exit fullscreen mode

Quando usar (e quando não usar)

Cache é perfeito para leituras frequentes e tolerância a staleness controlada. Já para dados que mudam a todo instante (ex.: saldo financeiro em tempo real), o custo de invalidação pode superar o benefício. E não esqueça: defina TTLs realistas e instrumente a taxa de cache hit.


3. Otimização de Consultas no Banco de Dados (SQLAlchemy)

O erro que consome recursos sem você notar

SELECT * é o vilão silencioso. Trazer todas as colunas — inclusive aquelas com textos longos ou BLOBs — quando a rota só precisa de nome e preço desperta duas dores: tráfego de rede maior e mais memória ocupada no lado da aplicação.

A abordagem cirúrgica com load_only

No SQLAlchemy (modo async), você pode limitar as colunas carregadas diretamente na query:

from sqlalchemy.orm import load_only
from sqlalchemy import select

stmt = select(Produto).options(load_only(Produto.nome, Produto.preço))
result = await db.execute(stmt)
produtos = result.scalars().all()

Enter fullscreen mode Exit fullscreen mode

Não pare por aí

Combine isso com índices nas colunas usadas nos filtros (WHERE) e nos JOIN. Para tabelas grandes, uma indexação bem pensada reduz o tempo de query de segundos para milissegundos. Ferramentas como pg_stat_statements (PostgreSQL) ou o EXPLAIN do MySQL são suas aliadas para caçar full table scans.


4. Compressão de Respostas HTTP (FastAPI Middleware)

Por que isso importa?

APIs que retornam payloads JSON extensos ou listas grandes desperdiçam banda e aumentam o tempo de transferência, especialmente em redes móveis. A compressão GZip ataca exatamente isso.

Ativação em uma linha (bom, duas)

O FastAPI já tem middleware nativo:

from fastapi.middleware.gzip import GZipMiddleware

app.add_middleware(GZipMiddleware, minimum_size=500)

Enter fullscreen mode Exit fullscreen mode

Ajustes finos

  • minimum_size=500 evita comprimir respostas pequenas, onde o custo da compressão seria maior que o ganho.
  • Se você usa proxy reverso (Nginx, Traefik), considere aplicar compressão lá também, mas ter no FastAPI ajuda em dev e em setups mais simples.
  • Teste com e sem compressão usando curl -H "Accept-Encoding: gzip" e compare os tamanhos. Reduções de 70% em JSON não são raras.

5. Lazy Loading no Vue.js (Frontend)

O gargalo invisível do front-end

SPA com muitos componentes, bibliotecas de gráficos e modais pode resultar em um bundle inicial gigante. O usuário espera segundos olhando para uma tela em branco — e isso anula todo o esforço feito no back-end.

A solução: carregue sob demanda

Com Vue 3, componentes assíncronos são declarados assim:

import { defineAsyncComponent } from 'vue';

const ModalLogin = defineAsyncComponent(() => import('@/components/ModalLogin.vue'));

Enter fullscreen mode Exit fullscreen mode

Para rotas, ainda mais elegante

Se você usa Vue Router, o lazy loading das páginas já é o padrão recomendado:

const routes = [
  { path: '/dashboard', component: () => import('@/views/Dashboard.vue') }
];

Enter fullscreen mode Exit fullscreen mode

Automatizando com Vite

O plugin vite-plugin-pages cria rotas automáticas baseadas na estrutura de arquivos e já aplica code splitting. Combine isso com vite-plugin-vue-layouts e você terá uma base de projeto enxuta e rápida por padrão.

O que você ganha?

Menor tempo até a primeira renderização (FCP) e melhor pontuação no Lighthouse. O código do modal de login, por exemplo, só é baixado quando alguém clica em “Entrar”.


Caso Real: E-commerce com 10k Requisições/Minuto

O desafio

Uma loja online usando FastAPI + Vue.js começou a travar nos picos de acesso. A página de listagem de produtos levava 2 segundos para carregar, e o banco de dados chegava a 80% de CPU.

As intervenções (todas desse guia)

  1. Cache de catálogo com Redis — TTL de 10 minutos para a lista de produtos, já que o estoque era atualizado em intervalos conhecidos.
  2. Async endpoints para o motor de tracking de usuários (eventos de clique, visualizações). Essas rotas deixaram de bloquear o event loop.
  3. Compressão GZip na API + otimização de imagens com CDN (as imagens nem tocavam mais no servidor de origem).
  4. Lazy loading no painel administrativo Vue.js, separando gráficos e relatórios em chunks carregados sob demanda.

Resultado

Latência média da página de produtos caiu de 2000ms para 400ms. O uso de CPU do servidor foi reduzido em 40%, e o banco de dados passou a operar com folga. Detalhe: o Redis introduziu uma latência extra de apenas 2ms no cache hit, totalmente aceitável.


Erros Fatais a Evitar

Misturar código síncrono em rotas assíncronas: usar requests.get dentro de async def é pedir para degradar performance.

Esquecer o pool de conexões do banco: criar uma nova conexão a cada requisição derruba qualquer aplicação sob carga. Configure o pool adequadamente.

Não monitorar: sem Prometheus + Grafana (ou pelo menos logs estruturados) você está voando às cegas. Erros de performance aparecem quando o cliente já foi embora.


Conclusão

Otimizar FastAPI com Vue.js é menos sobre truques milagrosos e mais sobre entender o fluxo dos dados: do event loop assíncrono ao bundle JavaScript. As cinco estratégias que eu mostrei aqui são pragmáticas e já foram validadas em produção. Comece aplicando uma de cada vez, meça os resultados com testes de carga (o Locust é um excelente ponto de partida) e ajuste.

Agora é a sua vez: qual dessas técnicas você já usa? Tem alguma abordagem diferente que funcionou bem no seu projeto? Troca uma ideia comigo nos comentários — vou adorar saber como você está levando performance a sério. 🚀