Урок 10

Аналитика и мониторинг

Что отслеживать

  • Краши — исключения и падения
  • Производительность — FPS, время запуска, память
  • Сессии — длительность, частота
  • Экраны — какие открывают
  • События — покупки, регистрации, клики
  • Воронки — путь пользователя
  • Retention — возвращаются ли

Sentry

Для крашей:

npx expo install @sentry/react-native
import * as Sentry from '@sentry/react-native';

Sentry.init({
    dsn: 'YOUR_DSN',
    debug: __DEV__,
    tracesSampleRate: 1.0,
    enableAutoSessionTracking: true,
});

Использование:

try {
    await riskyOperation();
} catch (error) {
    Sentry.captureException(error);
    throw error;
}

Sentry.setUser({ id: user.id, email: user.email });
Sentry.addBreadcrumb({ category: 'ui', message: 'Button clicked' });

Crashlytics

Альтернатива для Firebase:

npx expo install @react-native-firebase/app @react-native-firebase/crashlytics

Amplitude

Продуктовая аналитика:

npm install @amplitude/analytics-react-native
import * as amplitude from '@amplitude/analytics-react-native';

amplitude.init('API_KEY');
amplitude.track('Button Clicked', { button: 'buy' });
amplitude.setUserId(user.id);

PostHog

Open-source альтернатива:

npm install posthog-react-native
import PostHog from 'posthog-react-native';

const posthog = new PostHog('API_KEY');

posthog.capture('purchase', { amount: 99 });
posthog.screen('Profile');

Firebase Analytics

npx expo install @react-native-firebase/analytics
import analytics from '@react-native-firebase/analytics';

await analytics().logEvent('purchase', { value: 99 });
await analytics().setUserId(user.id);
await analytics().logScreenView({ screen_name: 'Profile' });

События

function ProductCard({ product }: { product: Product }) {
    function handleBuy() {
        analytics.track('buy_clicked', {
            productId: product.id,
            price: product.price,
            category: product.category,
        });
        addToCart(product);
    }

    return <Pressable onPress={handleBuy}>Купить</Pressable>;
}

Экраны

Автоматически с React Navigation:

import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';

function App() {
    const navigationRef = useNavigationContainerRef();
    const routeNameRef = useRef<string>();

    return (
        <NavigationContainer
            ref={navigationRef}
            onReady={() => {
                routeNameRef.current = navigationRef.getCurrentRoute()?.name;
            }}
            onStateChange={async () => {
                const previous = routeNameRef.current;
                const current = navigationRef.getCurrentRoute()?.name;

                if (previous !== current) {
                    analytics.track('screen_view', { screen: current });
                }

                routeNameRef.current = current;
            }}
        >
            {/* навигаторы */}
        </NavigationContainer>
    );
}

Производительность

Sentry Performance:

const transaction = Sentry.startTransaction({ name: 'Load Posts' });

const res = await fetch('/posts');

transaction.finish();

React Native Performance Monitor (в меню разработчика):

  • FPS
  • RAM
  • Views

Feature Flags

Включение функций без релиза:

npm install posthog-react-native
const showNewUI = posthog.getFeatureFlag('new-ui');

if (showNewUI) {
    return <NewUI />;
}
return <OldUI />;

A/B тесты

const variant = posthog.getFeatureFlag('checkout-button');

if (variant === 'test') {
    return <Button>Купить сейчас</Button>;
}
return <Button>Купить</Button>;

Приватность аналитики

  • Спрашивай разрешение (iOS ATT)
  • Не отправляй персональные данные
  • Анонимизируй ID
  • Документируй в Privacy Policy

Итоги

  • Sentry для крашей
  • Amplitude/PostHog для продуктовой
  • Firebase Analytics как альтернатива
  • Автоматические screen views
  • Feature flags для гибкости
  • A/B тесты для решений
  • Приватность обязательна