Files
wow-design-wiki/mobile/mobile-performance-patterns.md
neo 083f6ba783 feat(mobile): comprehensive mobile web design patterns — 6 new articles
- mobile-patterns.md: Mobile layout & pattern systems (18.5KB)
  Fluid typography, container queries, safe-area, CSS architecture,
  touch-optimized components, iOS/Android specifics, testing checklist

- mobile-layout-patterns.md: Mobile layout systems (11.5KB)
  CSS grid, single-column stack, full-bleed hero, card stack,
  swipeable carousel, split-screen, off-canvas nav, bottom sheet,
  FAB, component patterns

- mobile-navigation-patterns.md: Mobile navigation (9.8KB)
  Bottom tab bar, top nav, hamburger menu, bottom sheet nav,
  pill nav, comparison matrix, navigation rules, swipe navigation,
  breadcrumbs, tab content

- mobile-form-patterns.md: Mobile form patterns (10.3KB)
  Input types, keyboards, floating labels, validation patterns,
  progressive disclosure, autocomplete, masked inputs, toggle/radio,
  form anti-patterns

- mobile-interaction-patterns.md: Touch & gestures (16.7KB)
  Swipe detection, long press, pull-to-refresh, touch feedback,
  scroll-reveal, parallax, sticky scroll, CSS scroll animations,
  touch carousel, haptic feedback, passive listeners

- mobile-performance-patterns.md: Performance optimization (12.3KB)
  Core Web Vitals (LCP/INP/CLS), LCP optimization, INP debugging,
  CLS prevention, image optimization, lazy loading, service workers,
  CSS/JS optimization, network optimization

- mobile-landing-patterns.md: Landing page patterns (21.3KB)
  Section sequencing, hero, social proof, feature cards,
  CTA patterns (inline/sticky/full-bleed), testimonials, pricing,
  FAQ accordion, footer, mobile checklist
2026-07-03 20:15:10 +05:00

475 lines
12 KiB
Markdown

---
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 image: preload as resource -->
<link rel="preload" as="image" href="/hero-large.webp" fetchpriority="high">
<!-- Responsive hero with next-gen formats -->
<picture>
<source srcset="hero-480.webp 480w, hero-800.webp 800w, hero-1200.webp 1200w"
media="(min-width: 768px)">
<img
src="hero-480.webp"
loading="eager"
fetchpriority="high"
decoding="async"
width="800"
height="600"
alt="Hero description"
class="lcp-hero"
>
</picture>
```
```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
<head>
<!-- Inline critical CSS (above-the-fold) -->
<style>
/* Critical path CSS — target < 14KB gzipped */
.hero {
min-height: 60vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 24px 16px;
}
.hero__title {
font-size: clamp(2rem, 8vw, 4rem);
line-height: 1.1;
margin-bottom: 16px;
}
/* ... more critical styles ... */
</style>
<!-- Defer non-critical CSS -->
<link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>
```
### 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
<picture>
<source srcset="image-small.webp 400w, image-medium.webp 800w, image-large.webp 1200w"
media="(min-width: 768px)">
<source srcset="image-small.avif 400w, image-medium.avif 800w, image-large.avif 1200w"
media="(min-width: 768px)">
<img
src="image-small.webp"
srcset="image-small.webp 400w, image-medium.webp 800w, image-large.webp 1200w"
sizes="(max-width: 767px) 100vw, 50vw"
loading="lazy"
decoding="async"
width="800"
height="600"
alt="Description"
class="lazy-image"
>
</picture>
```
### 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
<!-- Preconnect to critical origins -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://api.example.com">
<!-- Prefetch critical resources -->
<link rel="prefetch" href="/next-page.js">
<link rel="prefetch" href="/critical-image.webp">
<!-- Preload critical resources -->
<link rel="preload" href="/hero-large.webp" as="image" fetchpriority="high">
```
## 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 в <head> | Async/defer |