Skip to content

perf: deep performance optimizations across catalog, rendering, and build#597

Merged
adm01-debug merged 1 commit into
mainfrom
claude/pensive-ptolemy-TWFEW
Jun 2, 2026
Merged

perf: deep performance optimizations across catalog, rendering, and build#597
adm01-debug merged 1 commit into
mainfrom
claude/pensive-ptolemy-TWFEW

Conversation

@adm01-debug
Copy link
Copy Markdown
Owner

@adm01-debug adm01-debug commented Jun 1, 2026

Summary

  • GPU scroll performance: Remove backdrop-blur and semi-transparent gradients from all scrolling containers (VirtualizedProductGrid, ProductTableView, FiltersPage) — the single biggest win; eliminates per-frame GPU blur recalculation on every scroll event. Add translateZ(0) + will-change: scroll-position to .scrollbar-products.
  • React rendering: Move static helpers (Intl.NumberFormat, formatPrice, lookup tables) to module level in ProductCard; switch full Zustand store subscriptions to fine-grained selectors so unrelated store updates don't re-render all visible cards; remove unused useQueryClient hook call; memoize colGapPx; remove staggered Framer Motion animations on virtual rows that were firing on every scroll virtualisation cycle; increase virtualizer overscan.
  • Filter hot-path: Pre-process all filter arrays to lowercase Sets/Arrays once outside the per-product predicate (suppliers, publicoAlvo, datasComemorativas, endomarketing, ramosAtividade, segmentosAtividade, materiais, tags) — eliminates N×M toLowerCase() calls per filter pass; switch Array.includes() O(n) → Set.has() O(1) for supplier ID lookups; stabilise resize listener with ref pattern.
  • Data fetching: Module-level singleton Promise for category map in useProductsLightweight to prevent N+1 category fetches across paginated loads; add networkMode: offlineFirst to React Query for cache-first serving; expand optimizeDeps.include from 5 to 15 packages.
  • Build & routing: More routes in RoutePrefetcher with reduced secondary delay (2500ms → 1800ms); DNS prefetch for secondary Supabase host; tune TooltipProvider delays.

Test plan

  • Browse the catalog page (/filtros) — scroll should feel noticeably smoother, especially on mid-range devices
  • Apply supplier, category, color, publicoAlvo, and tag filters — results should be identical to before
  • Toggle favorites and compare on product cards — no unintended re-renders of other cards
  • Switch between grid / list / table view modes — layouts render correctly
  • Navigate between routes — prefetch still works, no flicker
  • Reload while offline — React Query serves cached data (offlineFirst)
  • Run tsc --noEmit — zero new type errors introduced

https://claude.ai/code/session_011LmF185piJUGvBHb4cy5U4


Generated by Claude Code


Summary by cubic

Deep performance pass across catalog and product pages to make scrolling smoother and filtering faster. Removes GPU-heavy effects, reduces re-renders, optimizes filter loops, and improves prefetch and offline behavior.

  • Refactors

    • Removed backdrop-blur and gradient backgrounds from all scroll containers; added translateZ(0) and will-change: scroll-position to .scrollbar-products.
    • ProductCard: hoisted Intl.NumberFormat and lookup tables; switched zustand subscriptions to selectors; removed unused useQueryClient.
    • Virtualized grid: memoized column gap, removed staggered framer-motion animations, and increased @tanstack/react-virtual overscan (list 10, grid 5).
    • Filters: preprocessed arrays to lowercase Sets/Arrays; supplier lookup now Set.has(); stable resize listener via ref.
    • Data/routing/build: module-level singleton for category map; @tanstack/react-query networkMode: 'offlineFirst'; expanded RoutePrefetcher coverage and reduced secondary delay; added DNS prefetch; tuned TooltipProvider delays; expanded Vite optimizeDeps.include.
  • Bug Fixes

    • Combined ramosAtividade and segmentosAtividade filters now use AND logic, yielding correct results.

Written for commit 7e035fd. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Notas de Lançamento

  • New Features

    • Suporte aprimorado para modo offline com cache automático de dados.
  • Bug Fixes

    • Correções na lógica de filtros de produtos para maior precisão nas buscas.
  • Refactor

    • Otimizações de desempenho em pré-carregamento de rotas e carregamento de categorias.
    • Simplificações visuais nas interfaces de produtos.
  • Chores

    • Otimizações de build e pré-bundling de dependências para melhor velocidade de carregamento.

…uild

GPU scroll performance:
- Remove backdrop-blur-sm/md and semi-transparent gradients from all
  scrolling containers (VirtualizedProductGrid, ProductTableView,
  FiltersPage list/table views) — eliminates per-frame GPU blur on scroll
- Add translateZ(0) + will-change:scroll-position to .scrollbar-products

React rendering:
- Move Intl.NumberFormat, formatPrice, and static lookup tables to
  module level in ProductCard (no re-creation per render)
- Switch full Zustand store subscriptions to fine-grained selectors in
  ProductCard to prevent all-cards re-render on unrelated store changes
- Remove unused useQueryClient hook call in ProductCard
- Memoize colGapPx computation in VirtualizedProductGrid
- Remove staggered framer-motion animations on virtual rows (triggered
  on every scroll virtualisation cycle)
- Increase overscan: list 8→10, grid 3→5

Filter loop hot-path:
- Pre-process all filter arrays to lowercase Sets/Arrays outside the
  per-product predicate (suppliers, publicoAlvo, datasComemorativas,
  endomarketing, ramosAtividade, segmentosAtividade, materiais, tags)
  — eliminates N×M toLowerCase() calls per filter pass
- Switch suppliers.includes() O(n) → Set.has() O(1)
- Stabilise resize listener with ref pattern (no re-register on column change)

Data fetching:
- Module-level singleton Promise for category map in useProductsLightweight
  — prevents N+1 category fetches across paginated loads
- Add networkMode: offlineFirst to React Query for cache-first serving
- Expand Vite optimizeDeps.include from 5 to 15 packages

Build & routing:
- Expand RoutePrefetcher with more routes and reduce secondary delay
  2500ms → 1800ms
- Add dns-prefetch for secondary Supabase host
- Tune TooltipProvider delayDuration/skipDelayDuration

https://claude.ai/code/session_011LmF185piJUGvBHb4cy5U4
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ea33c6c0-c2f7-4d94-aa34-1fc8355e16ea

📥 Commits

Reviewing files that changed from the base of the PR and between 6a7a0f8 and 7e035fd.

📒 Files selected for processing (12)
  • index.html
  • src/App.tsx
  • src/components/products/ProductCard.tsx
  • src/components/products/ProductTableView.tsx
  • src/components/products/VirtualizedProductGrid.tsx
  • src/hooks/products/useProductsLightweight.ts
  • src/index.css
  • src/lib/query-config.ts
  • src/pages/filters/useFiltersPageState.ts
  • src/pages/products/FiltersPage.tsx
  • src/routes/RoutePrefetcher.tsx
  • vite.config.ts

Walkthrough

PR refatora infraestrutura de performance: otimiza styles removendo gradientes/blur, substitui animações por divs simples, implementa cache via singleton Promise, normaliza filtradores com lowercase, adiciona stratégia offline-first em queries e expande route prefetching. Sem quebras de API pública.

Changes

Performance, UX e Otimizações

Layer / File(s) Summary
Estilo Visual, DNS e Configuração Global
index.html, src/App.tsx, src/components/products/ProductTableView.tsx, src/pages/products/FiltersPage.tsx, src/index.css, vite.config.ts
Containers de scroll migram de bg-gradient-to-b com backdrop-blur-md para bg-background sólido com shadow-sm, reduzindo complexidade visual. Tooltip delay ajustado para delayDuration={400} e skipDelayDuration={200}. DNS prefetch adicionado para doufsxqlfjyuvxuezpln.supabase.co. CSS utility .scrollbar-products otimiza performance com transform: translateZ(0) e will-change: scroll-position. Vite optimizeDeps.include expandido com 10 dependências principais para bundle mais otimizado.
ProductCard: Refatoração de Selectors e Helpers
src/components/products/ProductCard.tsx
Remove useQueryClient (dependência desnecessária), centraliza formatPrice() e mapeamentos de status (cor/rótulo) em constantes de módulo com Intl.NumberFormat. Integra stores de favoritos/comparação via selectors diretos (addFavorite, addToCompare) chamados em handleVariantComplete, simplificando fluxo modal. Deps de useCallback atualizadas. Hover style simplificado removendo backdrop-blur-md.
VirtualizedProductGrid: Memoização e Desanimação
src/components/products/VirtualizedProductGrid.tsx
colGapPx calculado via useMemo evitando recálculos em cada render. overscan aumentado em virtualizer para renderização mais fluida. Containers de scroll simplificados: remove gradientes, WebkitOverflowScrolling e shadow-inner, mantendo apenas contain: 'strict'. Remoção crítica: motion.div animado substituído por div simples no grid mode, eliminando dependência de animations baseadas em índice. Seleção mantida via selectedIds condicional.
Filtragem Avançada: Normalização e Lógica Corrigida
src/pages/filters/useFiltersPageState.ts
Responsividade de grid columns refatorada usando useRef + efeito único, eliminando re-triggers por state. Filtros client-side completamente reescritos: suppliers, publicoAlvo, datasComemorativas, endomarketing, ramo/segmento, materiais agora pré-computam sets/arrays em lowercase e aplicam comparações consistentes (substring-matching onde apropriado). Correção lógica: regra AND entre ramo + segmento quando ambos ativos. Tags filter consolida valores estruturados (publicoAlvo/datasComemorativas/endomarketing/ramo/nicho) em lowercase. Dead code appliedFilters removido.
Cache em Singleton e React Query Offline-First
src/hooks/products/useProductsLightweight.ts, src/lib/query-config.ts
loadCategoriesMap migra para singleton categoriesMapPromise garantindo fetch único por sessão com compartilhamento entre chamadas. Em falha, Promise resetada para retry na próxima chamada. React Query configurado globalmente com networkMode: 'offlineFirst' para priorizar cache em modo offline.
Route Prefetcher: Estratégia de Pré-carregamento Expandida
src/routes/RoutePrefetcher.tsx
Prefetch dinâmico ampliado: /auth//login carregam Index + FiltersPage; /produtos e /filtros tratados conjuntamente carregando ProductDetail + PriceSimulatorPage; novos casos por prefixo /produto/ (QuoteBuilderPage + FiltersPage) e /orcamentos (QuoteBuilderPage + ClientsPage). Timeout secundário reduzido 2500ms → 1800ms. MockupGenerator e CollectionsPage agora disparados para /produtos e /filtros simultaneamente.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • adm01-debug/promo-gifts-v4#40: Refatoração de loadCategoriesMap em useProductsLightweight.ts para singleton Promise conecta-se diretamente com a busca e mapeamento de categorias naquele PR.
  • adm01-debug/promo-gifts-v4#487: Ambos alteram useFiltersPageState.ts com mudanças na lógica de filtragem client-side e verificações de nulidade.
  • adm01-debug/promo-gifts-v4#36: DNS prefetch para doufsxqlfjyuvxuezpln.supabase.co em index.html correlaciona com otimizações do Supabase daquele PR.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/pensive-ptolemy-TWFEW

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
we-dream-big Error Error Jun 1, 2026 10:24pm

@supabase
Copy link
Copy Markdown

supabase Bot commented Jun 1, 2026

This pull request has been ignored for the connected project doufsxqlfjyuvxuezpln because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@adm01-debug adm01-debug marked this pull request as ready for review June 2, 2026 10:13
Copilot AI review requested due to automatic review settings June 2, 2026 10:13
@adm01-debug adm01-debug merged commit 28dafae into main Jun 2, 2026
29 of 40 checks passed
@adm01-debug adm01-debug deleted the claude/pensive-ptolemy-TWFEW branch June 2, 2026 10:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs a broad performance pass across the product catalog experience and supporting infrastructure to improve scroll smoothness, reduce React re-renders, speed up filter evaluation, and make route/data prefetching more effective.

Changes:

  • Removes GPU-expensive blur/gradient styling from major scroll containers and adds a shared .scrollbar-products compositor hint for smoother scrolling.
  • Optimizes catalog filtering and rendering hot paths (pre-lowercasing filter inputs, using Set lookups, memoizing layout values, removing per-row motion animations, and using fine-grained Zustand selectors).
  • Improves prefetch/caching/build behavior (expanded RoutePrefetcher coverage, React Query networkMode: 'offlineFirst', and expanded Vite optimizeDeps.include).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vite.config.ts Expands optimizeDeps.include to prebundle more frequently-used deps for faster dev startup/runtime.
src/routes/RoutePrefetcher.tsx Prefetches additional likely-next routes and adjusts secondary prefetch timing/coverage.
src/pages/products/FiltersPage.tsx Removes blur/gradient styling from list/table scroll containers.
src/pages/filters/useFiltersPageState.ts Optimizes filter hot paths (preprocessing to lowercase/sets; ref-based resize handler).
src/lib/query-config.ts Sets React Query default networkMode: 'offlineFirst' for better offline cache behavior.
src/index.css Adds shared compositor hints to .scrollbar-products for scrolling performance.
src/hooks/products/useProductsLightweight.ts Adds a module-level singleton promise to avoid repeated category-map fetches across pages.
src/components/products/VirtualizedProductGrid.tsx Removes per-row staggered animations, memoizes column gap, increases overscan, and simplifies scroll container styling.
src/components/products/ProductTableView.tsx Updates scroll container styling to remove blur/gradient and align with new scroll perf approach.
src/components/products/ProductCard.tsx Hoists static helpers/constants and switches Zustand subscriptions to selector-based usage to reduce re-renders.
src/App.tsx Tunes TooltipProvider delay props.
index.html Adds DNS prefetch for an additional Supabase host.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/index.css
Comment on lines +86 to +92
/* GPU-composited scroll containers — promotes to own layer to avoid repaints on scroll */
@layer utilities {
.scrollbar-products {
transform: translateZ(0);
will-change: scroll-position;
}
}
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 12 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/routes/RoutePrefetcher.tsx">

<violation number="1" location="src/routes/RoutePrefetcher.tsx:73">
P2: New fire-and-forget `import()` prefetches can raise unhandled promise rejections on chunk-load failures.</violation>
</file>

<file name="src/pages/filters/useFiltersPageState.ts">

<violation number="1" location="src/pages/filters/useFiltersPageState.ts:211">
P2: Responsive column clamp no longer re-applies when `gridColumns` changes, allowing >3 columns on small screens until a resize occurs.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

}, 2500);
if (pathname === '/produtos' || pathname === '/filtros') {
import('@/pages/mockups/MockupGenerator');
import('@/pages/collections/CollectionsPage');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: New fire-and-forget import() prefetches can raise unhandled promise rejections on chunk-load failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/routes/RoutePrefetcher.tsx, line 73:

<comment>New fire-and-forget `import()` prefetches can raise unhandled promise rejections on chunk-load failures.</comment>

<file context>
@@ -47,25 +47,32 @@ export function RoutePrefetcher() {
-    }, 2500);
+      if (pathname === '/produtos' || pathname === '/filtros') {
+        import('@/pages/mockups/MockupGenerator');
+        import('@/pages/collections/CollectionsPage');
+      }
+    }, 1800);
</file context>
Suggested change
import('@/pages/collections/CollectionsPage');
import('@/pages/collections/CollectionsPage').catch(() => {});

window.addEventListener('resize', handleResize, { passive: true });
return () => window.removeEventListener('resize', handleResize);
}, [gridColumns]);
}, []); // empty deps — handler uses ref to avoid stale closure
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Responsive column clamp no longer re-applies when gridColumns changes, allowing >3 columns on small screens until a resize occurs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/pages/filters/useFiltersPageState.ts, line 211:

<comment>Responsive column clamp no longer re-applies when `gridColumns` changes, allowing >3 columns on small screens until a resize occurs.</comment>

<file context>
@@ -198,18 +198,17 @@ export function useFiltersPageState() {
+    window.addEventListener('resize', handleResize, { passive: true });
     return () => window.removeEventListener('resize', handleResize);
-  }, [gridColumns]);
+  }, []); // empty deps — handler uses ref to avoid stale closure
   const [voiceOverlayOpen, setVoiceOverlayOpen] = useState(false);
   const [commandAction, setCommandAction] = useState<string | null>(null);
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants