O que é TTI e por que importa no Magento
TTI (Time to Interactive) mede quando a página se torna completamente interativa — ou seja, quando o usuário pode clicar em botões, usar formulários e navegar sem atrasos. Tecnicamente, é o momento em que a thread principal do navegador fica livre de Long Tasks (blocos de execução acima de 50ms) por pelo menos 5 segundos.
O Magento 2 é notoriamente desafiador em termos de TTI por uma razão estrutural: o framework usa RequireJS para carregamento de módulos JavaScript, e a configuração padrão carrega e executa um volume considerável de JS logo após o DOMContentLoaded — mesmo em páginas que não precisam de todos esses módulos.
Referência real: uma loja Magento 2 sem otimização de JS típica apresenta TTI entre 8s e 18s em mobile com conexão 4G. Com otimização de bundling e defer, esse valor cai para 3s a 5s — suficiente para sair da zona vermelha.
Diagnóstico com Chrome DevTools
Antes de qualquer mudança, você precisa medir e entender o que está bloqueando a interatividade. O Chrome DevTools é a ferramenta mais precisa para isso.
Passo 1 — Gravar o profile de performance
Abra a loja em modo de navegação anônima (para evitar cache local), vá em DevTools → aba Performance, clique em "Record" e atualize a página. Grave por 10-15 segundos enquanto a página carrega completamente. Clique em "Stop".
Passo 2 — Identificar Long Tasks
No timeline, role para a seção "Main" (thread principal). Long Tasks aparecem como blocos vermelhos acima de 50ms. Clique em um Long Task para ver qual script é responsável. No Magento, os culpados mais frequentes são:
- requirejs/require.js — o próprio carregador de módulos ResolvingDependencies
- Magento_Ui/js/lib/ko/initialize.js — inicialização do KnockoutJS antes de qualquer componente precisar dele
- mage/bootstrap.js — bootstrap do framework que inicializa handlers globais
- Scripts de módulos third-party adicionados sem defer
Passo 3 — Verificar o bundle gerado
# Verificar tamanho dos bundles JS em produção
ls -lah pub/static/frontend/VENDOR/TEMA/pt_BR/requirejs-bundle-includes.json
ls -lah pub/static/frontend/VENDOR/TEMA/pt_BR/default.js
# Verificar se bundling está ativo
php bin/magento config:show dev/js/enable_js_bundling
php bin/magento config:show dev/js/merge_files
As principais causas de TTI alto no Magento
1. RequireJS sem bundling otimizado
O Magento usa RequireJS por padrão, que carrega módulos JavaScript sob demanda. O problema: cada módulo gera uma requisição HTTP separada. Uma página de produto típica pode gerar 60-120 requisições JS adicionais, cada uma bloqueando ou atrasando a thread principal.
A solução oficial do Magento é o JavaScript bundling, que agrupa módulos em bundles menores. Porém, o bundling padrão do Magento é conhecido por ser ineficiente — frequentemente gera um bundle gigante com código de todas as páginas, quando o correto seria ter bundles por tipo de página.
# Ativar bundling (Admin → Stores → Config → Advanced → Developer → JavaScript Settings)
php bin/magento config:set dev/js/enable_js_bundling 1
php bin/magento config:set dev/js/minify_files 1
php bin/magento cache:flush
php bin/magento setup:static-content:deploy pt_BR -f
2. KnockoutJS inicializando desnecessariamente
O KnockoutJS é o framework de view model usado pelo Magento para componentes reativos (mini-cart, formulários de checkout, etc.). O problema é que a inicialização do KO e todos os seus bindings acontece em toda página — mesmo em páginas simples como listagem de categorias que não usam componentes reativos complexos.
Atenção: desabilitar KO globalmente quebra funcionalidades críticas. A abordagem correta é usar Magento_PageCache + Full Page Cache para servir HTML pré-renderizado, reduzindo a quantidade de componentes que precisam de hydration client-side.
3. JavaScript de módulos third-party sem defer
Módulos Magento de terceiros frequentemente adicionam scripts ao <head> ou ao rodapé sem o atributo defer ou async. Cada script síncrono no head bloqueia o parser HTML e aumenta o TTI.
<!-- ❌ Bloqueante — script síncrono no head -->
<script src="https://cdn.analytics-tool.com/track.js"></script>
<!-- ✅ Correto — defer garante execução após parse do HTML -->
<script src="https://cdn.analytics-tool.com/track.js" defer></script>
Para adicionar defer a scripts de módulos específicos via layout XML do Magento:
<!-- app/code/Vendor/Module/view/frontend/layout/default_head_blocks.xml -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<script src="Vendor_Module::js/analytics.js" defer="true"/>
</head>
</page>
4. Magento_PageBuilder e CMS blocks pesados
O Page Builder do Magento (Adobe Commerce) carrega um volume significativo de JS para rendering de seus blocos. Se você usa Page Builder apenas no CMS e não em produtos/categorias, desabilite os scripts do Page Builder nessas páginas via layout handle específico.
<!-- Para desabilitar Page Builder JS em páginas de produto -->
<!-- app/design/frontend/VENDOR/TEMA/Magento_PageBuilder/layout/catalog_product_view.xml -->
<page>
<head>
<remove src="Magento_PageBuilder::js/page-builder.js"/>
<remove src="Magento_PageBuilder::js/content-type/slider.js"/>
</head>
</page>
Otimização avançada de bundling
O bundling nativo do Magento (configurável no Admin) frequentemente não é suficiente para TTI satisfatório. A solução mais eficaz é usar o Baler ou implementar bundling por página usando a ferramenta de análise de dependências do próprio RequireJS.
Abordagem com bundling por página
A ideia é criar bundles diferentes para homepage, PDP (página de produto), PLP (listagem) e checkout — cada bundle contendo apenas os módulos necessários para aquele contexto.
# Gerar o arquivo de trace de dependências
# Navegar pelas páginas com Network throttling 4G e coletar quais módulos são carregados
# Depois configurar grupos de bundle no env.php:
# app/etc/env.php — adicionar configuração de bundling
'system' => [
'default' => [
'dev' => [
'js' => [
'enable_js_bundling' => '1',
'minify_files' => '1',
]
]
]
],
Full Page Cache e Varnish
A redução mais significativa de TTI em Magento não vem de otimizações de JS — vem de garantir que o TTFB (Time to First Byte) seja baixo o suficiente para que o browser receba o HTML rápido e comece o parse e execução de JS mais cedo.
O Full Page Cache (FPC) do Magento com Varnish reduz o TTFB de 800ms-2s para 30ms-80ms. Com TTFB baixo, mesmo que o JS demore 4s para executar completamente, o TTI final pode ser 4s ao invés de 12s.
# Verificar se FPC está ativo e qual backend está usando
php bin/magento cache:status | grep full_page
php bin/magento config:show system/full_page_cache/caching_application
# 1 = PHP Cache (padrão, lento)
# 2 = Varnish (ideal)
# Para Varnish, verificar se está respondendo corretamente:
curl -I https://sua-loja.com.br | grep -i "x-magento-cache-debug\|age\|x-cache"
Prioridade correta: implemente FPC + Varnish antes de otimizar o bundling JS. O ganho de TTFB tem efeito multiplicador sobre TTI — reduzir 800ms de TTFB frequentemente reduz o TTI percebido em mais de 2s.
Plano de correção em ordem de impacto
| Ação | Impacto TTI | Complexidade | Risco |
|---|---|---|---|
| Ativar Full Page Cache + Varnish | Alto (−3s a −8s) | Média | Baixo |
| Minificação JS/CSS (dev/js/minify_files) | Médio (−500ms a −1.5s) | Baixa | Baixo |
| Ativar JS bundling nativo | Médio (−1s a −3s) | Baixa | Médio |
| Adicionar defer a scripts third-party | Médio (−500ms a −2s) | Média | Médio |
| Remover scripts Page Builder em páginas não-CMS | Médio (−800ms a −1.5s) | Média | Baixo |
| Bundling por página (Baler ou custom) | Alto (−2s a −5s) | Alta | Alto |
TTI alto impactando a conversão da sua loja Magento?
Fazemos diagnóstico completo de performance incluindo TTI, LCP e INP para lojas Magento 2 e Adobe Commerce, com plano de ação priorizado e estimativas de impacto.