Introducere Vezi și: Ghid complet Web Design, Technical SEO, Web Accessibility, Ghid complet E-Commerce.
53% din utilizatori abandonează un site dacă încarcă mai mult de 3 secunde. Viteza nu e doar despre UX - e despre bani.
Impact Business:
- Amazon: +1s delay = -1% vânzări ($1.6B/an pierdere potențială)
- Google: +500ms = -20% search traffic
- Walmart: +1s improvement = +2% conversii
În acest ghid, vei învăța să optimizezi fiecare aspect al performanței web.
1. Măsurare și Benchmarking
Core Web Vitals (Google Ranking Factor)
LCP - Largest Contentful Paint:
- Target: < 2.5 secunde
- Ce măsoară: Timpul până elementul principal devine vizibil
- Element principal: Imaginea hero, heading principal, primul paragraph
FID - First Input Delay:
- Target: < 100 milisecunde
- Ce măsoară: Timpul până pagina răspunde la prima interacțiune
- Afectat de: JavaScript care blochează main thread
CLS - Cumulative Layout Shift:
- Target: < 0.1
- Ce măsoară: Stabilitatea vizuală (nu "sare" conținutul)
- Cauzat de: Imagini fără dimensiuni, fonturi care se încarcă târziu, ads
Tools de Măsurare:
Lighthouse (Chrome DevTools):
# Run Lighthouse CLI
npm install -g lighthouse
lighthouse https://yoursite.com --view
WebPageTest.org:
- Testare din multiple locații geografice
- Connection throttling (3G, 4G, Cable)
- Film strip view pentru debugging
PageSpeed Insights:
- Field data (utilizatori reali) + Lab data
- Recomandări specifice
- Mobile + Desktop scoring
Chrome User Experience Report (CrUX):
- Date reale de la utilizatori Chrome
- Agregat pe 28 zile
- Breakdown pe device type
2. Optimizare Imagini (Cel Mai Mare Impact)
Imaginile reprezintă 50-70% din payload-ul unei pagini web.
Format Selection:
WebP:
- 30% mai mic decât JPEG la aceeași calitate
- Suportat de 95%+ browsere
- Fallback la JPEG pentru browsere vechi
AVIF:
- 50% mai mic decât JPEG
- Suport browser: 75% (în creștere)
- Ideal pentru imagini de înaltă calitate
SVG:
- Vector format pentru logo-uri, iconițe
- Infinit scalabil
- Optimizează cu SVGO
Responsive Images:
<img
src="image-800w.webp"
srcset="
image-400w.webp 400w,
image-800w.webp 800w,
image-1200w.webp 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
alt="Descriptive alt text"
width="1200"
height="800"
loading="lazy"
/>
Key Points:
srcset: Multiple variante de rezoluțiesizes: Browser-ul alege imaginea optimăwidth/height: Previne CLSloading="lazy": Încarcă la scroll
Image Optimization Tools:
Automated (Build Time):
- Sharp (Node.js)
- Squoosh CLI
- Next.js Image Component (auto-optimization)
Manual:
CDN pentru Imagini:
- Cloudinary - Transformări on-the-fly
- ImageKit - Free tier generos
- Cloudflare Images - Integrat cu CDN
3. Code Splitting și Lazy Loading
JavaScript Bundle Optimization:
Problema:
// ❌ Import tot React Icons (950KB)
import { FaUser, FaHome } from 'react-icons/fa';
// ✅ Import doar ce folosești
import FaUser from 'react-icons/fa/FaUser';
import FaHome from 'react-icons/fa/FaHome';
Bundle Analysis:
# Next.js
ANALYZE=true npm run build
# Create React App
npm install -D webpack-bundle-analyzer
Dynamic Imports:
// ❌ Import static (încarcă imediat)
import HeavyComponent from './HeavyComponent';
// ✅ Dynamic import (încarcă la nevoie)
const HeavyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
<Suspense fallback={<LoadingSpinner />}>
{showHeavy && <HeavyComponent />}
</Suspense>
);
}
Route-based Code Splitting:
// Next.js - automatic code splitting per route
pages/
index.js // Doar code pentru homepage
about.js // Doar code pentru about
contact.js // Doar code pentru contact
4. Caching Strategies
Browser Caching (Cache-Control Headers):
# Imagini - cache 1 an
location ~* .(jpg|jpeg|png|gif|webp|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# JavaScript/CSS - cache cu hash în nume fișier
location ~* .(js|css)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# HTML - no cache (actualizări frecvente)
location ~* .(html)$ {
expires -1;
add_header Cache-Control "no-store, must-revalidate";
}
Service Workers (PWA):
// Cache assets esențiale la install
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/',
'/styles.css',
'/script.js',
'/logo.png',
]);
})
);
});
// Serve from cache, fallback la network
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
CDN (Content Delivery Network):
Beneficii:
- Servește assets din locația geografică apropiată
- Reduce latență cu 50-80%
- Protecție DDoS inclusă
Providers Recomandați:
- Cloudflare - Free tier excelent
- BunnyCDN - Cel mai ieftin, performanță bună
- AWS CloudFront - Pentru enterprise
5. Critical CSS și Font Optimization
Inline Critical CSS:
<!-- Critical CSS inline pentru above-the-fold -->
<head>
<style>
/* Doar stiluri pentru conținutul vizibil initial */
.hero { background: #000; color: #fff; }
.nav { display: flex; }
</style>
<!-- Restul CSS-ului load async -->
<link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>
Tools:
Font Optimization:
Self-host Fonts:
/* ❌ Google Fonts (1 network request extra) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
/* ✅ Self-hosted cu font-display: swap */
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-weight: 100 900;
font-display: swap; /* Prevent FOIT */
}
Variable Fonts:
- 1 fișier pentru toate weights
- ~30% mai mic decât multiple font files
- Smooth weight transitions
Preload Critical Fonts:
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
6. Database și API Optimization
Database Query Optimization:
-- ❌ N+1 Query Problem
SELECT * FROM posts;
-- Pentru fiecare post:
SELECT * FROM authors WHERE id = post.author_id;
-- ✅ JOIN (1 query)
SELECT posts.*, authors.name
FROM posts
LEFT JOIN authors ON posts.author_id = authors.id;
API Caching cu Redis:
// Express + Redis caching
const redis = require('redis');
const client = redis.createClient();
app.get('/api/posts', async (req, res) => {
// Check cache
const cached = await client.get('posts');
if (cached) {
return res.json(JSON.parse(cached));
}
// Fetch from DB
const posts = await db.getPosts();
// Cache for 5 minutes
await client.setEx('posts', 300, JSON.stringify(posts));
res.json(posts);
});
GraphQL DataLoader:
Previne N+1 queries în GraphQL prin batching și caching.
const DataLoader = require('dataloader');
const authorLoader = new DataLoader(async (authorIds) => {
const authors = await db.getAuthorsByIds(authorIds);
return authorIds.map(id => authors.find(a => a.id === id));
});
// În resolver
author: (post) => authorLoader.load(post.authorId)
7. Third-Party Scripts Optimization
Defer Non-Critical Scripts:
<!-- ❌ Blocking script -->
<script src="analytics.js"></script>
<!-- ✅ Defer (execută după page load) -->
<script src="analytics.js" defer></script>
<!-- ✅ Async (încarcă în paralel, execută când e gata) -->
<script src="analytics.js" async></script>
Regula:
deferpentru scripts care depind de DOMasyncpentru scripts independente (analytics, ads)
Façade Pattern pentru Embeds:
// Nu încarca YouTube player până la click
<div
onclick="loadYouTube()"
style="background: url('thumbnail.jpg')"
>
<button>▶ Play Video</button>
</div>
<script>
function loadYouTube() {
const iframe = document.createElement('iframe');
iframe.src = 'https://youtube.com/embed/VIDEO_ID';
this.replaceWith(iframe);
}
</script>
Economie: ~500KB JavaScript + 3 network requests economisiti!
8. Server-Side Optimizations
Enable Compression (Gzip/Brotli):
# nginx.conf
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
# Brotli (mai bun decât Gzip)
brotli on;
brotli_types text/plain text/css application/json application/javascript;
Savings: 70-80% reducere dimensiune text assets.
HTTP/2 Push:
# Push CSS critical înainte să fie cerut
http2_push /critical.css;
Server-Side Rendering (SSR):
Beneficii:
- Time to First Byte îmbunătățit
- SEO-friendly (conținut indexabil imediat)
- Perceived performance mai bună
Frameworks:
- Next.js (React)
- Nuxt.js (Vue)
- SvelteKit (Svelte)
9. Monitoring Continuous
Real User Monitoring (RUM):
// Web Vitals library de la Google
import {getCLS, getFID, getLCP} from 'web-vitals';
function sendToAnalytics(metric) {
fetch('/analytics', {
method: 'POST',
body: JSON.stringify(metric),
});
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);
Tools:
- SpeedCurve - Enterprise RUM
- Calibre - Automated performance budgets
- New Relic Browser - Full-stack monitoring
Performance Budgets:
Set limits și alertează când sunt depășite:
{
"budgets": [
{
"path": "/*",
"timings": [
{ "metric": "fcp", "budget": 2000 },
{ "metric": "lcp", "budget": 2500 }
],
"resourceSizes": [
{ "resourceType": "script", "budget": 200 },
{ "resourceType": "image", "budget": 300 }
]
}
]
}
10. Advanced Techniques
Prefetching și Preloading:
<!-- Preload: încarcă imediat (high priority) -->
<link rel="preload" href="/hero.jpg" as="image">
<!-- Prefetch: încarcă când browserul e idle -->
<link rel="prefetch" href="/next-page.html">
<!-- DNS Prefetch: rezolvă DNS înainte de request -->
<link rel="dns-prefetch" href="https://api.example.com">
<!-- Preconnect: DNS + TCP + TLS handshake -->
<link rel="preconnect" href="https://fonts.google.com">
Resource Hints cu Intersection Observer:
// Prefetch pagina când link-ul devine vizibil
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = entry.target.href;
document.head.appendChild(link);
}
});
});
document.querySelectorAll('a').forEach(link => observer.observe(link));
Adaptive Loading:
Servește experiențe diferite bazat pe capabilități device:
import { useNetworkStatus, useMemoryStatus } from 'react-adaptive-hooks';
function VideoComponent() {
const { effectiveConnectionType } = useNetworkStatus();
const { deviceMemory } = useMemoryStatus();
// 4G + 4GB+ RAM = HD video
if (effectiveConnectionType === '4g' && deviceMemory >= 4) {
return <video src="hd-video.mp4" />;
}
// 3G sau low memory = SD video
return <video src="sd-video.mp4" />;
}
Checklist Final Optimizare
Images:
- Converted to WebP/AVIF
- Responsive images (srcset)
- Lazy loading pentru below-fold
- Width/height specificate
- Compressed (TinyPNG/Squoosh)
JavaScript:
- Code splitting implementat
- Bundle size < 200KB inițial
- Defer/async pentru third-party
- Tree shaking activat
- Unused code eliminat
CSS:
- Critical CSS inline
- Unused CSS purged
- CSS minified
- Load non-critical async
Fonts:
- Self-hosted (nu Google Fonts)
- font-display: swap
- WOFF2 format
- Preload critical fonts
Caching:
- Browser caching (1 year pentru assets)
- CDN configurat
- Service Worker (PWA)
- API caching (Redis)
Server:
- Gzip/Brotli compression
- HTTP/2 enabled
- Database indexes optimizate
- Query pooling activat
Monitoring:
- Core Web Vitals tracking
- RUM implementat
- Performance budgets set
- Alerting configurat
Concluzie
Optimizarea performanței nu e un proiect one-time - e un proces continuu. Fiecare secundă economisită = mai mulți clienți și vânzări.
Priorități:
-
Quick Wins (2-4 ore):
- Image optimization
- Enable caching
- Gzip compression
- Lazy loading
-
Medium Term (1-2 săptămâni):
- Code splitting
- CDN implementation
- Critical CSS
- Font optimization
-
Long Term (ongoing):
- Performance monitoring
- RUM implementation
- Continuous optimization
- Performance culture
Vrei un audit complet de performanță pentru website-ul tău? Contactează-ne pentru o analiză gratuită.
Resurse Utile:
- Web.dev - Ghiduri Google
- ImageOptim - Mac image optimizer
- Lighthouse CI - Automated testing
