Оптимизация dApp часто упирается в одну проблему: каждый UI-компонент выполняет собственный RPC-запрос, и никакой координации между ними нет. Десять компонентов порождают десять параллельных вызовов к провайдеру (Infura, Alchemy) с latency 100–300 ms. Пользователь наблюдает постепенное появление UI с бесконечными спиннерами. Главная задача — объединить эти запросы и кэшировать ответы. Наш опыт — более 10 проектов по ускорению dApp, мы работаем с Web3 с 2017 года. Практика показывает: без вмешательства типичная DeFi-страница делает 50+ RPC-запросов в минуту, из которых 70% можно объединить в один. В одном из проектов (агрегатор ликвидности) после настройки multicall количество запросов сократилось в 8 раз, а TTI упал с 8 до 3 секунд. Экономия на инфраструктурных расходах превысила $3000 в год.
Проблемы, которые решаем
- Чрезмерное количество RPC-запросов. Каждый вызов — это 100–300 ms задержки. Без батчинга приложение делает в 10 раз больше запросов, чем нужно.
- Неоптимальный bundle size. Случайный импорт всего
ethersвместоviemдобавляет 200 KB gzipped. - Избыточные re-renders React. Компоненты перерендериваются при любом изменении аккаунта, даже если нужен только адрес.
Как multicall решает проблему задержек?
multicall3 — контракт, задеплоенный на большинстве EVM-сетей по адресу 0xcA11bde05977b3631167028862bE2a173976CA11. Он выполняет N view-вызовов в одном RPC-запросе. Multicall улучшает производительность в 10 раз по сравнению с отдельными вызовами, так как latency объединяется. Пример использования с wagmi v2:
import { useReadContracts } from 'wagmi' const { data } = useReadContracts({ contracts: [ { address: tokenA, abi: erc20Abi, functionName: 'balanceOf', args: [userAddress] }, { address: tokenB, abi: erc20Abi, functionName: 'balanceOf', args: [userAddress] }, { address: tokenC, abi: erc20Abi, functionName: 'balanceOf', args: [userAddress] }, ], }) wagmi v2 автоматически батчит вызовы через multicall3, если включена опция batch: { multicall: true }. Проверьте, что она активна — при отладке её часто отключают и забывают вернуть. Настройка занимает минуту, а сокращает количество запросов в 5–10 раз.
Почему code splitting так важен для dApp?
Компоненты работы с кошельком (WalletModal, Web3ReactManager) обращаются к window.ethereum при инициализации — их нельзя грузить на сервере. Dynamic import с ssr: false решает проблему:
const WalletModal = dynamic(() => import('@/components/WalletModal'), { ssr: false, loading: () => <Skeleton className="h-10 w-32" />, }) Это уменьшает первоначальный bundle на 30–50% и улучшает LCP. Для сравнения: code splitting даёт экономию трафика до 40% в крупных dApp.
Кэширование с TanStack Query
wagmi построен поверх TanStack Query. staleTime и gcTime напрямую влияют на количество RPC-запросов. Настройка по умолчанию часто неоптимальна:
const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 12_000, // 12 секунд – для balance данных gcTime: 5 * 60_000, // кэш живёт 5 минут retry: 2, retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30_000), }, }, }) Для статичных метаданных токенов выставляем staleTime: Infinity. Экономия — до 80% запросов без ущерба для актуальности.
Сравнение производительности до и после
| Метрика | До оптимизации | После оптимизации |
|---|---|---|
| RPC-запросов | 50 в минуту | 5–10 в минуту |
| TTI | 6 секунд | 2–3 секунды |
| Bundle size | 400 KB (gzipped) | 200–250 KB (gzipped) |
| Тип данных | Рекомендуемый staleTime | Экономия запросов |
|---|---|---|
| Баланс токена | 12 секунд | 80% |
| Метаданные токена | Infinity | 100% |
| Цена (oracle) | 30 секунд | 90% |
Процесс работы
- Аудит — профилируем React (React DevTools), анализируем bundle (Vite/Next.js analyzer), замеряем RPC-нагрузку через Network tab.
-
Настройка multicall и батчинга — включаем
batch: { multicall: true }, рефакторим вызовы подuseReadContracts. -
Кэширование — подбираем
staleTimeпод каждый тип данных. - Code splitting — заменяем статические импорты на dynamic где нужно.
- Профилирование — проверяем re-render budget, добавляем
useMemoиselect. - Документация и обучение — передаём конфиги и best practices.
Что входит в работу
- Аудит производительности с отчётом.
- Настройка multicall, TanStack Query, code splitting.
- Оптимизация React rendering (selectors, memoization).
- Профилирование и финальные замеры.
- Документация изменений и рекомендации для поддержки.
- Обучение команды (до 2 часов).
Сроки и стоимость
Работа занимает от 3 до 5 дней. Стоимость рассчитывается индивидуально — оценим проект после аудита. Свяжитесь с нами для консультации.
Типичные оптимизации в одном кейсе
Проект A: DeFi-агрегатор с 12 экранами. После настройки multicall количество RPC-запросов снизилось в 8 раз, TTI упал с 8 до 3 секунд, bundle уменьшился на 40%. Команда получила документацию и скрипты для мониторинга. Экономия на инфраструктурных расходах достигла 70% (более $3000 в год).
Получите консультацию по оптимизации вашего dApp. Наши инженеры готовы провести аудит и предложить конкретные улучшения. Оставьте заявку на бесплатный анализ — мы покажем, какие метрики можно улучшить.







