---
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
```
```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
```
### 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 |