--- title: Mobile Performance Patterns created: 2026-07-03 updated: 2026-07-03 type: system tags: [mobile, performance, core-web-vitals, lcp, inp, cls, optimization] sources: - https://developers.google.com/search/docs/appearance/core-web-vitals - https://rankture.com/blog/core-web-vitals-optimization-guide - https://eastondev.com/blog/en/posts/dev/20251124-core-web-vitals-optimization/ - https://ubmetrics.com/blog/core-web-vitals-complete-guide-2025 - https://www.airankaudit.com/core-web-vitals-guide-2025-lcp-inp-cls-explained-with-fixes/ confidence: high --- # Mobile Performance Patterns — Производительность для мобильных ## 1. Core Web Vitals: Мобильные Стандарты 2025/2026 ### 1.1 Thresholds | Метрика | Good | Needs Improvement | Poor | |---------|------|-------------------|------| | **LCP** | ≤ 2.5s | 2.5s - 4.0s | > 4.0s | | **INP** | ≤ 200ms | 200ms - 500ms | > 500ms | | **CLS** | ≤ 0.1 | 0.1 - 0.25 | > 0.25 | ### 1.2 Mobile-First Importance На мобильных: - LCP **критичнее** из-за медленных сетей (3G/4G) - INP **критичнее** из-за более слабых CPU - CLS **критичнее** из-за smaller viewport и layout shifts ### 1.3 Measurement Tools | Tool | Purpose | Best For | |------|---------|----------| | PageSpeed Insights | Lab + Field Data | Quick audit | | Chrome UX Report | Real user data | Production monitoring | | Web Vitals JS Library | Runtime measurement | Dev instrumentation | | Lighthouse | Lab testing | Development | | DevTools Network Throttling | Simulated 3G | Testing | ## 2. Largest Contentful Paint (LCP) ### 2.1 What is LCP? Время, когда **крупнейший элемент контента** (hero image, H1, section) становится видимым. ### 2.2 LCP Optimization Checklist ``` Priority: 1. Critical image — preload + next-gen format 2. Above-the-fold content — inline critical CSS 3. Server response — reduce TTFB 4. Render-blocking resources — defer/async 5. JS execution — minify + code split ``` ### 2.3 Critical Image Optimization ```html Hero description ``` ```css /* Prevent layout shift for LCP image */ .lcp-hero { width: 100%; aspect-ratio: 16/9; object-fit: cover; background: color-mix(in srgb, var(--surface-2) 50%, transparent); } ``` ### 2.4 Critical CSS Inlining ```html ``` ### 2.5 Reduce TTFB (Time to First Byte) ``` Optimization: 1. Use CDN (Cloudflare, Fastly, AWS CloudFront) 2. Edge caching (Vercel, Netlify Edge, Cloudflare Workers) 3. HTTP/2 or HTTP/3 4. Database query optimization 5. Server-side rendering (SSR) or static generation 6. Connection pooling ``` ## 3. Interaction to Next Paint (INP) ### 3.1 What is INP? Время между **пользовательским взаимодействием** и следующей отрисовкой. Заменяет FID (First Input Delay). ### 3.2 INP Optimization Strategies ```javascript // 1. Use passive event listeners document.addEventListener('scroll', handler, { passive: true }); document.addEventListener('touchstart', handler, { passive: true }); // 2. Debounce expensive operations function debounce(fn, delay = 16) { let ticking = false; return () => { if (!ticking) { requestAnimationFrame(() => { fn(); ticking = false; }); ticking = true; } }; } // 3. Offload heavy work to Web Workers // worker.js self.onmessage = (e) => { const result = heavyComputation(e.data); self.postMessage(result); }; ``` ```css /* 4. GPU-accelerated animations */ .animated-element { will-change: transform, opacity; transform: translateZ(0); } /* 5. Avoid layout thrashing */ // Bad: forces layout recalculation element.style.width = '100px'; console.log(element.offsetWidth); // Good: batch reads const width = element.offsetWidth; // read element.style.width = '100px'; // write ``` ### 3.3 INP Debugging Checklist | Category | Check | Tool | |----------|-------|------| | **Event handlers** | Passive listeners where possible | DevTools | | **Long tasks** | < 50ms per task | DevTools Long Tasks | | **JS execution** | Code splitting, tree shaking | Lighthouse | | **Layout thrashing** | Batch reads/writes | DevTools | | **Main thread** | No blocking scripts | Performance panel | ## 4. Cumulative Layout Shift (CLS) ### 4.1 What is CLS? Суммарный сдвиг **всех визуальных элементов** за время загрузки страницы. ### 4.2 CLS Prevention Patterns ```css /* 1. Always set dimensions on images/videos */ img, video, iframe { width: 100%; height: auto; object-fit: cover; } /* 2. Reserve space for dynamic content */ .ad-container { min-height: 200px; background: var(--surface-2); } /* 3. Font loading — prevent FOIT/FOUT */ @font-face { font-family: 'MyFont'; src: url('/fonts/myfont.woff2') format('woff2'); font-display: swap; } /* 4. Sticky ads — fixed position */ .ad-sticky { position: fixed; bottom: 0; left: 0; right: 0; } /* 5. Skeleton loaders */ .skeleton { background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 4px; } @keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } ``` ### 4.3 CLS Measurement ```javascript // Web Vitals library for CLS import { getCLS } from 'web-vitals'; getCLS((value) => { console.log('CLS:', value); // Report to analytics if (value > 0.25) { sendToAnalytics('cls_threshold_exceeded', { value }); } }); ``` ## 5. Image Optimization ### 5.1 Image Strategy for Mobile ``` Priority: 1. Use next-gen formats (WebP, AVIF) 2. Responsive images with srcset 3. Lazy loading for below-fold images 4. Proper dimensions (width/height) 5. Compress images (Squoosh, TinyPNG) 6. CDN for image delivery ``` ### 5.2 Responsive Images Pattern ```html Description ``` ### 5.3 Lazy Loading with Intersection Observer ```javascript class LazyLoader { constructor(options = {}) { this.threshold = options.threshold || 0.1; this.rootMargin = options.rootMargin || '200px 0px'; this.observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const el = entry.target; if (el.tagName === 'IMG') { if (el.dataset.src) el.src = el.dataset.src; if (el.dataset.srcset) el.srcset = el.dataset.srcset; } if (el.tagName === 'VIDEO') { if (el.dataset.src) el.src = el.dataset.src; } el.classList.add('loaded'); this.observer.unobserve(el); } }); }, { threshold: this.threshold, rootMargin: this.rootMargin }); } observe(elements) { elements.forEach(el => this.observer.observe(el)); } } // Usage const lazyLoader = new LazyLoader({ rootMargin: '200px 0px' }); document.querySelectorAll('.lazy').forEach(el => lazyLoader.observe(el)); ``` ## 6. CSS & JS Optimization ### 6.1 CSS Optimization ```css /* 1. Use CSS containment */ .contained { contain: layout style paint; } /* 2. Minimize reflows */ .element { will-change: transform; transform: translateZ(0); } /* 3. Use CSS variables for theming (avoids JS) */ :root { --primary: #0070f3; --text-primary: #111; } ``` ### 6.2 JavaScript Optimization ```javascript // 1. Code splitting const lazyModule = import('./heavy-module.js'); // 2. Debounce user input function debounce(fn, delay = 16) { let ticking = false; return () => { if (!ticking) { requestAnimationFrame(() => { fn(); ticking = false; }); ticking = true; } }; } // 3. Virtual scroll for long lists function virtualScroll(container, items, itemHeight) { const visibleCount = Math.ceil(container.clientHeight / itemHeight); const scrollTop = container.scrollTop; const startIndex = Math.floor(scrollTop / itemHeight); const endIndex = Math.min(startIndex + visibleCount + 10, items.length); // Only render visible items for (let i = startIndex; i < endIndex; i++) { renderItem(items[i]); } } // 4. Use requestAnimationFrame for animations function animateElement(element, keyframes, options) { element.animate(keyframes, { ...options, fill: 'forwards' }); } ``` ## 7. Network Optimization ### 7.1 Service Worker Caching ```javascript // sw.js const CACHE_NAME = 'mobile-app-v1'; const ASSETS_TO_CACHE = [ '/', '/styles.css', '/app.js', '/fonts/*' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => cache.addAll(ASSETS_TO_CACHE)) ); }); self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request).then((response) => { return response || fetch(event.request); }) ); }); ``` ### 7.2 Prefetch & Preconnect ```html ``` ## 8. Mobile Performance Checklist | Metric | Target | Tool | |--------|--------|------| | **LCP** | ≤ 2.5s | PageSpeed Insights | | **INP** | ≤ 200ms | Web Vitals JS | | **CLS** | ≤ 0.1 | PageSpeed Insights | | **FCP** | ≤ 1.8s | DevTools | | **TTFB** | ≤ 600ms | Network panel | | **Total JS** | ≤ 200KB | Lighthouse | | **Total CSS** | ≤ 50KB (critical) | Lighthouse | | **Images** | Next-gen + responsive | PageSpeed Insights | ## 9. Mobile Performance Anti-Patterns | ❌ Плохо | ✅ Хорошо | |----------|-----------| | 100vh для полноэкранных секций | 100dvh | | Полноэкранные изображения | Responsive images + lazy loading | | Тяжелые JS-библиотеки | Vanilla JS / lightweight alternatives | | Автоплей видео | Play/pause по тапу | | Шрифты без font-display | font-display: swap | | Без сжатия изображений | WebP/AVIF + compression | | Синхронный JS в | Async/defer |