KHUYẾN MÃI MÙA HÈ: GIẢM 20% TẤT CẢ DỊCH VỤ - HẠN CHÓT 30/6GIỚI THIỆU KHÁCH HÀNG MỚI: NHẬN 15% HOA HỒNG TRÊN HÓA ĐƠN ĐẦU TIÊNKHUYẾN MÃI MÙA HÈ: GIẢM 20% TẤT CẢ DỊCH VỤ - HẠN CHÓT 30/6GIỚI THIỆU KHÁCH HÀNG MỚI: NHẬN 15% HOA HỒNG TRÊN HÓA ĐƠN ĐẦU TIÊN
Tan Phat Media

Core Web Vitals Là Gì? Cách Cải Thiện Điểm Website Theo Google

29 tháng 5, 2026
500
Seo Marketing
Core Web Vitals Là Gì? Cách Cải Thiện Điểm Website Theo Google - Tấn Phát Digital

Tấn Phát Digital — Bài viết được biên dịch và phân tích chuyên sâu từ tài liệu chính thức "Understanding Core Web Vitals and Google search results" của Google Search Central. Đây là bài kỹ thuật quan trọng nhất dành cho developer, designer và chủ website muốn tối ưu performance theo tiêu chuẩn của Google.

1 giây chậm = $1.6 triệu doanh thu mất đi

Năm 2017, Amazon công bố một con số gây sốc: Mỗi 1 giây chậm = giảm $1.6 tỷ doanh thu hàng năm.

Walmart tìm thấy: Mỗi 1 giây cải thiện = +2% conversion.

Google nghiên cứu: Trang load >3 giây = 53% người rời bỏ.

Tại Việt Nam, 60% website chạy chậm hơn 3 giây. Điều này có nghĩa là:

  • Mất 50%+ traffic tiềm năng

  • Conversion thấp hơn 20-40%

  • Bounce rate cao

  • Ranking SEO bị ảnh hưởng

Google nhận ra performance là yếu tố quyết định trải nghiệm user, nên đã giới thiệu Core Web Vitals — bộ 3 metrics đo lường trải nghiệm web thực tế.

Năm 2024, Google chính thức đổi từ FID sang INP — một thay đổi quan trọng nhiều site VN chưa cập nhật.

Bài viết này, Tấn Phát Digital sẽ giải mã toàn bộ Core Web Vitals 2026 — từ định nghĩa đến optimization techniques.

Bài viết này dành cho:

  • Frontend Developer tối ưu performance

  • Backend Developer cần hiểu performance impact

  • DevOps quản lý infrastructure

  • Chủ website muốn hiểu performance tác động SEO

  • Marketing manager cần justify performance investment


Phần 1: Core Web Vitals — Tổng quan

1.1. Định nghĩa từ Google

Google nói:

"Core Web Vitals là một bộ metrics đo lường REAL-WORLD USER EXPERIENCE cho LOADING PERFORMANCE, INTERACTIVITY, và VISUAL STABILITY của page."

3 trụ cột:

┌─────────────────────────────────────────────────┐
│  ⚡ LOADING (Tốc độ tải)                         │
│  Metric: LCP                                     │
│  Target: < 2.5 giây                              │
├─────────────────────────────────────────────────┤
│  🖱️ INTERACTIVITY (Phản hồi)                     │
│  Metric: INP                                     │
│  Target: < 200 milliseconds                      │
├─────────────────────────────────────────────────┤
│  🎯 VISUAL STABILITY (Ổn định)                   │
│  Metric: CLS                                     │
│  Target: < 0.1                                   │
└─────────────────────────────────────────────────┘

1.2. Tầm quan trọng cho SEO

Google nhấn mạnh:

"We HIGHLY RECOMMEND site owners achieve good Core Web Vitals for SUCCESS WITH SEARCH và để ensure a GREAT USER EXPERIENCE generally."

"This, along with other page experience aspects, ALIGNS WITH WHAT OUR CORE RANKING SYSTEMS SEEK TO REWARD."

🎯 Translation:

  • Core Web Vitals là ranking factor thực sự

  • Site có CWV tốt được Google thưởng

  • Không có CWV tốt = bất lợi cạnh tranh

1.3. "Real-world" data nghĩa là gì?

⚠️ Quan trọng: Google dùng real user data, không phải synthetic tests.

2 loại data:

Lab Data (Synthetic)

  • Đo trong môi trường controlled

  • Tools: Lighthouse, PageSpeed Insights

  • Hữu ích cho debugging

  • KHÔNG dùng cho ranking

Field Data (Real-world)

  • Đo từ người dùng thực tế

  • Source: Chrome User Experience Report (CrUX)

  • DÙNG cho ranking

  • Có thể khác xa lab data

Insight quan trọng: Site có thể Lighthouse 100/100 nhưng field data tệ → vẫn xếp hạng kém.


Phần 2: LCP — Largest Contentful Paint (Tải)

2.1. Định nghĩa

LCP = Thời gian để element lớn nhất trong viewport xuất hiện.

Element được tính:

  • Hình ảnh (<img>)

  • Hình ảnh background (CSS)

  • Video poster

  • Block-level text (paragraph, heading)

  • SVG

KHÔNG tính:

  • Hidden elements

  • Elements ngoài viewport

  • Decorative elements (border, gradient...)

2.2. Thresholds

✅ GOOD:           < 2.5 giây
🟡 NEEDS WORK:     2.5 - 4.0 giây
❌ POOR:           > 4.0 giây

2.3. Các yếu tố ảnh hưởng LCP

4 yếu tố chính:

1. Server response time

Slow server = LCP cao.

Cách đo: TTFB (Time To First Byte)

  • ✅ Good: < 800ms

  • 🟡 OK: 800ms - 1.8s

  • ❌ Poor: > 1.8s

Optimization:

# Nginx caching
location ~* \.(jpg|jpeg|png|gif|webp|css|js)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}
# Apache .htaccess
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
</IfModule>

2. Render-blocking resources

CSS/JS chặn render = LCP chậm.

Optimization:

<!-- ❌ Render-blocking -->
<link rel="stylesheet" href="styles.css">

<!-- ✅ Async CSS -->
<link rel="preload" href="critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="critical.css"></noscript>

<!-- ✅ Defer JS -->
<script src="app.js" defer></script>

<!-- ✅ Async JS (không phụ thuộc DOM) -->
<script src="analytics.js" async></script>

3. Resource load time

Images/videos lớn = LCP chậm.

Optimization images:

<!-- Modern format + responsive -->
<picture>
  <source 
    srcset="hero.avif" 
    type="image/avif">
  <source 
    srcset="hero.webp" 
    type="image/webp">
  <img 
    src="hero.jpg" 
    alt="Hero image"
    width="1200"
    height="600"
    fetchpriority="high">
</picture>

Critical:

  • fetchpriority="high" cho LCP image

  • ✅ AVIF (modern) > WebP > JPEG

  • ✅ Responsive với srcset

  • ✅ Specify width/height (avoid CLS too)

4. Client-side rendering

JS render content = LCP chậm.

Optimization:

// ❌ Tránh: Render tất cả từ JS
const App = () => {
  const [content, setContent] = useState('');
  useEffect(() => {
    fetch('/api/content').then(r => r.json()).then(setContent);
  }, []);
  return <div>{content}</div>; // LCP very late
};

// ✅ Đúng: SSR/SSG với placeholder
// Next.js example
export async function getStaticProps() {
  const content = await fetchContent();
  return { props: { content }, revalidate: 60 };
}

export default function Page({ content }) {
  return <div>{content}</div>; // LCP fast
}

2.4. Top 7 optimization techniques cho LCP

Technique 1: Preload critical resources

<head>
  <!-- Preload LCP image -->
  <link rel="preload" 
        as="image" 
        href="/hero.webp" 
        fetchpriority="high">
  
  <!-- Preload fonts -->
  <link rel="preload" 
        as="font" 
        type="font/woff2" 
        href="/font.woff2" 
        crossorigin>
  
  <!-- Preconnect to external domains -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://cdn.example.com" crossorigin>
</head>

Technique 2: Image optimization

# Convert to WebP với Sharp (Node.js)
npm install sharp

# Script
const sharp = require('sharp');

sharp('input.jpg')
  .webp({ quality: 80 })
  .toFile('output.webp');

# AVIF (better)
sharp('input.jpg')
  .avif({ quality: 70 })
  .toFile('output.avif');

Size guidelines:

Hero images:     < 200KB (WebP), < 100KB (AVIF)
Content images:  < 100KB
Thumbnails:      < 30KB
Icons:           < 5KB (SVG ideal)

Technique 3: CDN usage

Static assets serve qua CDN:

<!-- Trước: -->
<img src="/images/hero.jpg">

<!-- Sau: -->
<img src="https://cdn.example.com/images/hero.jpg">

Vietnam-friendly CDNs:

  • Cloudflare (free tier tốt)

  • Bunny CDN ($1/month)

  • Amazon CloudFront

  • KeyCDN

Technique 4: Critical CSS inline

<head>
  <style>
    /* Critical CSS for above-the-fold */
    body { margin: 0; font-family: sans-serif; }
    .hero { padding: 2rem; background: #fff; }
    .hero h1 { font-size: 3rem; }
    /* ... only above-the-fold styles */
  </style>
  
  <!-- Defer non-critical CSS -->
  <link rel="preload" 
        href="/full-styles.css" 
        as="style" 
        onload="this.onload=null;this.rel='stylesheet'">
</head>

Technique 5: Compress text

# Nginx gzip
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript 
           application/javascript application/json;
gzip_comp_level 6;

# Brotli (better than gzip)
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json 
             application/javascript text/xml;

Technique 6: HTTP/2 hoặc HTTP/3

server {
    listen 443 ssl http2;  # HTTP/2
    # listen 443 ssl http3;  # HTTP/3 (newer)
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
}

Technique 7: Database query optimization

Slow DB query → slow TTFB → slow LCP.

-- Add indexes cho frequent queries
CREATE INDEX idx_status_created 
ON products(status, created_at);

-- Use EXPLAIN để analyze
EXPLAIN SELECT * FROM products 
WHERE status = 'active' 
ORDER BY created_at DESC LIMIT 10;

Phần 3: INP — Interaction to Next Paint (Phản hồi)

3.1. INP là gì?

INP = Đo thời gian phản hồi của trang với user interactions.

⚠️ Thay đổi quan trọng 2024:

  • INP thay thế FID (First Input Delay)

  • Tính từ tháng 3/2024 chính thức

Tại sao đổi?

  • FID chỉ đo first interaction

  • INP đo TẤT CẢ interactions trong session

  • Phản ánh chính xác hơn UX thực tế

3.2. INP đo gì?

INP đo độ trễ giữa:

  • Click button

  • Tap link

  • Type input

  • Scroll touch

  • ... và phản hồi visual của trang

3.3. Thresholds

✅ GOOD:           < 200ms
🟡 NEEDS WORK:     200ms - 500ms
❌ POOR:           > 500ms

3.4. Nguyên nhân INP kém

Top 5 culprits:

1. Heavy JavaScript execution

// ❌ BAD: Block main thread
function processData(items) {
  return items.map(item => {
    // Heavy computation
    return expensiveOperation(item);
  });
}

button.addEventListener('click', () => {
  const result = processData(largeArray); // Blocks 500ms+
  updateUI(result);
});

// ✅ GOOD: Use Web Workers
button.addEventListener('click', () => {
  const worker = new Worker('processor.js');
  worker.postMessage(largeArray);
  worker.onmessage = (e) => updateUI(e.data);
});

2. Synchronous third-party scripts

<!-- ❌ BAD: Blocks main thread -->
<script src="https://analytics.example.com/track.js"></script>

<!-- ✅ GOOD: Async/defer -->
<script src="https://analytics.example.com/track.js" async></script>

3. Long-running event handlers

// ❌ BAD
button.onclick = () => {
  for (let i = 0; i < 100000; i++) {
    doSomething(i); // Block UI
  }
};

// ✅ GOOD: Use scheduler
button.onclick = async () => {
  for (let i = 0; i < 100000; i++) {
    if (i % 100 === 0) {
      // Yield to main thread every 100 iterations
      await new Promise(r => setTimeout(r, 0));
    }
    doSomething(i);
  }
};

// ✅ BEST: Use scheduler.yield() (modern API)
button.onclick = async () => {
  for (let i = 0; i < 100000; i++) {
    if (i % 100 === 0 && 'yield' in scheduler) {
      await scheduler.yield();
    }
    doSomething(i);
  }
};

4. Large DOM size

DOM lớn = updates chậm.

Solution: Virtual scrolling cho long lists

// React with react-window
import { FixedSizeList } from 'react-window';

function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={50}
      width="100%"
    >
      {({ index, style }) => (
        <div style={style}>{items[index].name}</div>
      )}
    </FixedSizeList>
  );
}

5. CSS animations heavy

/* ❌ BAD: Animate layout properties */
.element {
  transition: width 0.3s, height 0.3s, top 0.3s, left 0.3s;
}

/* ✅ GOOD: Animate transform/opacity (GPU) */
.element {
  transition: transform 0.3s, opacity 0.3s;
  will-change: transform; /* hint to browser */
}

.element:hover {
  transform: translate(10px, 10px) scale(1.1);
}

3.5. 5 techniques tối ưu INP

Technique 1: Code splitting

// Next.js dynamic imports
import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(
  () => import('../components/HeavyComponent'),
  { 
    loading: () => <p>Loading...</p>,
    ssr: false 
  }
);

// React.lazy
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <HeavyComponent />
    </Suspense>
  );
}

Technique 2: Debounce/Throttle

// Debounce search input
function debounce(fn, delay) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  };
}

const handleSearch = debounce((query) => {
  fetchResults(query);
}, 300);

searchInput.addEventListener('input', (e) => {
  handleSearch(e.target.value);
});

Technique 3: requestIdleCallback

// Schedule non-urgent tasks
function processNonUrgent() {
  if ('requestIdleCallback' in window) {
    requestIdleCallback(() => {
      // Do non-critical work
      sendAnalytics();
      updateCache();
    });
  } else {
    setTimeout(() => {
      sendAnalytics();
      updateCache();
    }, 0);
  }
}

Technique 4: Optimize React renders

// ❌ BAD: Re-render on every parent update
function Child({ data }) {
  return <div>{expensiveCalculation(data)}</div>;
}

// ✅ GOOD: Memoize
const Child = React.memo(({ data }) => {
  return <div>{expensiveCalculation(data)}</div>;
});

// ✅ BETTER: useMemo for calculations
function Child({ data }) {
  const result = useMemo(
    () => expensiveCalculation(data),
    [data]
  );
  return <div>{result}</div>;
}

// useCallback for functions
function Parent() {
  const handleClick = useCallback(() => {
    // ...
  }, []);
  
  return <Child onClick={handleClick} />;
}

Technique 5: Use CSS containment

/* Isolate rendering for components */
.card {
  contain: layout style paint;
}

/* Strict containment */
.modal {
  contain: strict;
}

Phần 4: CLS — Cumulative Layout Shift (Ổn định)

4.1. CLS là gì?

CLS = Đo lường độ ổn định visual của trang.

Layout shift xảy ra khi:

  • Element xuất hiện và push content xuống

  • Image load và đẩy text

  • Font load và reflow text

  • Ads/embeds load chậm

  • Animations thay đổi layout

4.2. Thresholds

✅ GOOD:           < 0.1
🟡 NEEDS WORK:     0.1 - 0.25
❌ POOR:           > 0.25

4.3. Tính CLS như thế nào?

CLS Score = Impact Fraction × Distance Fraction

Impact Fraction: % viewport bị ảnh hưởng Distance Fraction: Khoảng cách dịch chuyển / viewport height

Ví dụ:

  • 50% viewport bị shift

  • Element dịch 25% chiều cao viewport

  • CLS = 0.5 × 0.25 = 0.125 (Poor)

4.4. Top 6 nguyên nhân CLS

1. Images không có dimensions

Sai:

<img src="photo.jpg" alt="Photo">

Đúng:

<!-- Specify width/height -->
<img src="photo.jpg" 
     width="800" 
     height="600" 
     alt="Photo">

<!-- HOẶC dùng aspect-ratio CSS -->
<img src="photo.jpg" 
     style="aspect-ratio: 4/3; width: 100%;"
     alt="Photo">

2. Ads không có placeholder

Sai:

<div id="ad-container">
  <!-- Ad loaded dynamically, pushes content -->
</div>

Đúng:

<div id="ad-container" 
     style="min-height: 250px;">
  <!-- Reserved space -->
</div>

3. Web fonts gây FOUT/FOIT

FOUT = Flash of Unstyled Text FOIT = Flash of Invisible Text

Solution: font-display: optional

@font-face {
  font-family: 'CustomFont';
  src: url('/fonts/custom.woff2') format('woff2');
  font-display: optional; /* Best for CLS */
  /* hoặc: font-display: swap; (better UX) */
}

Preload critical fonts:

<link rel="preload" 
      href="/fonts/main.woff2" 
      as="font" 
      type="font/woff2" 
      crossorigin>

4. Dynamic content injection

Sai:

// Inject banner at top
const banner = document.createElement('div');
banner.innerHTML = 'Sale!';
document.body.insertBefore(banner, document.body.firstChild);
// Pushes content down

Đúng:

// Show banner without shifting layout
const banner = document.createElement('div');
banner.style.position = 'fixed';
banner.style.top = '0';
banner.style.zIndex = '9999';
banner.innerHTML = 'Sale!';
document.body.appendChild(banner);

5. Embedded videos/iframes

Sai:

<iframe src="https://youtube.com/embed/xyz"></iframe>

Đúng:

<div style="aspect-ratio: 16/9; position: relative;">
  <iframe 
    src="https://youtube.com/embed/xyz"
    style="position: absolute; width: 100%; height: 100%;"
    width="560"
    height="315">
  </iframe>
</div>

6. CSS animations với layout properties

Sai:

.menu {
  height: 0;
  transition: height 0.3s;
}
.menu.open {
  height: auto; /* Causes layout shift */
}

Đúng:

.menu {
  transform: translateY(-100%);
  transition: transform 0.3s;
}
.menu.open {
  transform: translateY(0);
}

Phần 5: Tools đo lường Core Web Vitals

5.1. PageSpeed Insights (Khuyến nghị #1)

URL: https://pagespeed.web.dev

Features:

  • Lab + Field data

  • Mobile + Desktop

  • Specific recommendations

  • Diagnostics đầy đủ

Cách dùng:

1. Paste URL
2. Click Analyze
3. Xem 2 tab: Mobile + Desktop
4. Field Data (real users) - QUAN TRỌNG NHẤT
5. Lab Data (Lighthouse)
6. Opportunities + Diagnostics

5.2. Chrome DevTools

Lighthouse panel:

1. Open DevTools (F12)
2. Tab "Lighthouse"
3. Categories: Performance
4. Device: Mobile (default cho ranking)
5. Click "Analyze"

Performance tab:

1. Tab "Performance"
2. Click record
3. Refresh page
4. Stop recording
5. Analyze flame chart

5.3. Search Console Core Web Vitals Report

Vị trí: Search Console → Experience → Core Web Vitals

Features:

  • Real field data từ users của bạn

  • Mobile + Desktop breakdown

  • Good / Needs Improvement / Poor counts

  • Trend over time

Đây là data Google dùng cho ranking.

5.4. CrUX API (Chrome User Experience Report)

# Get CrUX data cho URL
curl -X POST \
  'https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://example.com"
  }'

5.5. Real User Monitoring (RUM)

Tools:

  • web-vitals library (Google official)

  • SpeedCurve

  • DebugBear

  • Cloudflare Analytics

web-vitals library implementation:

import { onCLS, onINP, onLCP } from 'web-vitals';

function sendToAnalytics({ name, value, id }) {
  // Send to your analytics
  fetch('/analytics', {
    method: 'POST',
    body: JSON.stringify({ name, value, id }),
    headers: { 'Content-Type': 'application/json' }
  });
}

onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);

Phần 6: Framework-specific Optimization

6.1. WordPress

Top plugins:

🚀 Caching:
├── WP Rocket (premium, best)
├── W3 Total Cache (free)
└── LiteSpeed Cache (free, nếu dùng LiteSpeed server)

🖼️ Image optimization:
├── ShortPixel (premium)
├── Smush (free)
└── Imagify (mix)

📊 Database:
├── WP-Optimize
└── Advanced Database Cleaner

🎨 CSS/JS:
├── Autoptimize
└── Asset CleanUp

WP best practices:

// functions.php - Defer non-critical scripts
function defer_parsing_of_js($url) {
    if (is_admin()) return $url;
    if (strpos($url, '.js') === false) return $url;
    if (strpos($url, 'jquery.js')) return $url;
    return str_replace(' src', ' defer src', $url);
}
add_filter('script_loader_tag', 'defer_parsing_of_js', 10);

// Preload LCP image
function preload_lcp_image() {
    if (is_front_page()) {
        echo '<link rel="preload" as="image" 
               href="/hero.webp" fetchpriority="high">';
    }
}
add_action('wp_head', 'preload_lcp_image', 1);

6.2. Next.js

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
  experimental: {
    optimizeCss: true,
    optimizePackageImports: ['lodash', 'date-fns'],
  },
  compress: true,
};

// pages/_app.js
import Script from 'next/script';

export default function App({ Component, pageProps }) {
  return (
    <>
      {/* Lazy load analytics */}
      <Script
        src="https://analytics.example.com/track.js"
        strategy="lazyOnload"
      />
      <Component {...pageProps} />
    </>
  );
}

// Component: Optimize image
import Image from 'next/image';

function HeroSection() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero"
      width={1200}
      height={600}
      priority // For LCP
      fetchPriority="high"
      placeholder="blur"
      blurDataURL="data:image/svg+xml;base64,..."
    />
  );
}

6.3. Shopify

Built-in optimizations:

  • Image optimization (WebP auto)

  • CDN global

  • HTTP/2

Custom optimizations:

{% comment %} Preload critical resources {% endcomment %}
<link rel="preload" as="image" 
      href="{{ section.settings.hero | image_url: width: 1200 }}"
      fetchpriority="high">

{% comment %} Lazy load non-critical {% endcomment %}
<img src="{{ image | image_url: width: 600 }}"
     loading="lazy"
     decoding="async"
     width="600"
     height="400"
     alt="{{ image.alt }}">

{% comment %} Critical CSS inline {% endcomment %}
<style>
  {% render 'critical-css' %}
</style>

{% comment %} Defer non-critical CSS {% endcomment %}
<link rel="preload" 
      href="{{ 'main.css' | asset_url }}" 
      as="style"
      onload="this.onload=null;this.rel='stylesheet'">

6.4. Custom React App

// App.jsx - Code splitting
import { lazy, Suspense } from 'react';

const ProductPage = lazy(() => import('./ProductPage'));
const CheckoutPage = lazy(() => import('./CheckoutPage'));

function App() {
  return (
    <Routes>
      <Route path="/" element={<HomePage />} />
      <Route 
        path="/product/:id" 
        element={
          <Suspense fallback={<Loading />}>
            <ProductPage />
          </Suspense>
        } 
      />
      <Route 
        path="/checkout" 
        element={
          <Suspense fallback={<Loading />}>
            <CheckoutPage />
          </Suspense>
        } 
      />
    </Routes>
  );
}

// Optimize images component
function OptimizedImage({ src, alt, priority = false }) {
  const [loaded, setLoaded] = useState(false);
  
  return (
    <div style={{ aspectRatio: '16/9', position: 'relative' }}>
      <img
        src={src}
        alt={alt}
        loading={priority ? 'eager' : 'lazy'}
        fetchPriority={priority ? 'high' : 'auto'}
        decoding="async"
        onLoad={() => setLoaded(true)}
        style={{
          width: '100%',
          height: '100%',
          objectFit: 'cover',
          opacity: loaded ? 1 : 0,
          transition: 'opacity 0.3s'
        }}
      />
    </div>
  );
}

Phần 7: Case Study - Tối ưu thực tế

7.1. Trước optimization

Website ecommerce VN:

📊 BEFORE Optimization:

┌────────────────────────────────────┐
│ Metric    │ Value    │ Status      │
├────────────────────────────────────┤
│ LCP       │ 4.8s     │ ❌ Poor    │
│ INP       │ 620ms    │ ❌ Poor    │
│ CLS       │ 0.34     │ ❌ Poor    │
└────────────────────────────────────┘

Symptoms:
- Bounce rate: 68%
- Conversion: 1.2%
- Mobile speed score: 23

7.2. Optimization steps

Week 1-2: LCP fixes

✅ Compress all images (WebP, -70% size)
✅ Setup Cloudflare CDN
✅ Implement critical CSS inline
✅ Preload hero image
✅ Lazy load below-fold images
✅ Defer non-critical JS

→ LCP: 4.8s → 2.1s

Week 3: INP fixes

✅ Code splitting cho main bundle
✅ Defer analytics scripts
✅ Optimize event handlers
✅ Virtual scrolling cho long lists
✅ Web Worker cho heavy calculations

→ INP: 620ms → 180ms

Week 4: CLS fixes

✅ Add width/height cho tất cả images
✅ Reserve space cho ads
✅ font-display: optional cho web fonts
✅ Fix banner injection method
✅ Aspect-ratio cho iframes

→ CLS: 0.34 → 0.08

7.3. After optimization

📊 AFTER Optimization:

┌────────────────────────────────────┐
│ Metric    │ Value    │ Status      │
├────────────────────────────────────┤
│ LCP       │ 2.1s     │ ✅ Good    │
│ INP       │ 180ms    │ ✅ Good    │
│ CLS       │ 0.08     │ ✅ Good    │
└────────────────────────────────────┘

Results sau 3 tháng:
- Bounce rate: 68% → 42% (-26%)
- Conversion: 1.2% → 2.8% (+133%)
- Mobile speed score: 23 → 89
- Organic traffic: +47%
- Revenue: +180%

Phần 8: 10 lỗi phổ biến và cách fix

❌ Lỗi 1: Optimize chỉ với Lighthouse

Vấn đề: Lab data ≠ Field data

Fix: Track field data với Search Console + RUM

❌ Lỗi 2: Quên optimize mobile

Vấn đề: Google dùng mobile data cho ranking

Fix: Test mobile-first, ưu tiên mobile experience

❌ Lỗi 3: Web fonts quá nhiều

Vấn đề: Mỗi font weight = 1 file load

Fix: Tối đa 2-3 font weights, subset characters

❌ Lỗi 4: Images không có dimensions

Vấn đề: CLS cao

Fix: Always specify width/height hoặc aspect-ratio

❌ Lỗi 5: Block third-party scripts

Vấn đề: INP cao

Fix: Async/defer hoặc lazy load

❌ Lỗi 6: Không có caching

Vấn đề: LCP cao cho repeat visits

Fix: Cache static assets 1 year, HTML 1 hour

❌ Lỗi 7: Quá nhiều plugins (WordPress)

Vấn đề: Slow performance

Fix: Audit plugins, remove unused

❌ Lỗi 8: Không dùng CDN

Vấn đề: Slow cho users xa server

Fix: Cloudflare/Bunny CDN cho static assets

❌ Lỗi 9: Database queries không optimized

Vấn đề: Slow TTFB

Fix: Add indexes, query optimization

❌ Lỗi 10: Test chỉ với fast connection

Vấn đề: Không phản ánh user thực tế

Fix: Test với throttling (Slow 3G, mid-tier device)


Phần 9: Monitoring & Maintenance

9.1. Weekly checks

Every Monday (15 phút):

□ Search Console Core Web Vitals report
  └── Check trend last 7 days
  
□ PageSpeed Insights top 5 pages
  └── Mobile + Desktop
  
□ Any new "Poor" URLs?
  └── Priority fix list

9.2. Monthly deep dive

First Monday each month (2 hours):

□ Full audit top 20 pages
□ Review RUM data
□ Identify regressions
□ Plan optimizations
□ Update team on metrics

9.3. Quarterly review

Every quarter:

□ Compare quarter-over-quarter trends
□ ROI analysis (revenue, conversion correlations)
□ Tool/infrastructure review
□ Update optimization roadmap
□ Train team on new techniques

Kết luận: Performance là Business Investment

Core Web Vitals không chỉ là "technical SEO" — đó là business investment với ROI rất cao:

  • Conversion +20-40%

  • Bounce rate -25-35%

  • Organic traffic +30-50%

  • Revenue +50-200%

5 thông điệp cuối

1. Field data > Lab data. Lighthouse 100/100 không đảm bảo gì.

2. Mobile-first optimization. Google dùng mobile data cho ranking.

3. LCP quan trọng nhất. Tối ưu LCP đầu tiên.

4. INP thay thế FID từ 2024. Đảm bảo dùng INP.

5. Continuous monitoring. Performance dễ regress, monitor weekly.


Tài liệu tham khảo


Về Tấn Phát Digital

Tấn Phát Digital chuyên Core Web Vitals optimization:

  • CWV Audit - Phân tích toàn diện

  • Performance Optimization - LCP, INP, CLS fixes

  • WordPress Speed Optimization

  • Custom App Performance

  • Continuous Monitoring Setup

Liên hệ Tấn Phát Digital để tăng tốc website và boost SEO performance.


Biên soạn từ tài liệu Google Search Central, cập nhật 10/12/2025. Code samples và optimization techniques thuộc về Tấn Phát Digital.

Core Web Vitals không chỉ là bộ chỉ số kỹ thuật mà còn phản ánh trải nghiệm thực tế của khách hàng trên website.

Nếu bạn muốn tối ưu tốc độ website, cải thiện Core Web Vitals và nâng cao hiệu suất SEO, hãy liên hệ Tấn Phát Digital để được tư vấn giải pháp phù hợp.

Mục lục

Câu hỏi thường gặp

Core Web Vitals là gì?

Core Web Vitals là nhóm chỉ số của Google dùng để đo trải nghiệm người dùng thực tế trên website. Chúng tập trung vào tốc độ hiển thị, độ ổn định giao diện và khả năng phản hồi khi người dùng tương tác với trang.

Core Web Vitals gồm những chỉ số nào?

Hiện nay, bộ chỉ số chính gồm Largest Contentful Paint (LCP), Interaction to Next Paint (INP) và Cumulative Layout Shift (CLS). Ba chỉ số này lần lượt phản ánh tốc độ tải nội dung chính, độ trễ tương tác và mức độ xê dịch bố cục.

Vì sao Core Web Vitals quan trọng với SEO?

Core Web Vitals không phải yếu tố duy nhất quyết định thứ hạng, nhưng nó ảnh hưởng đến Page Experience. Website có trải nghiệm tốt thường giữ chân người dùng lâu hơn, giảm bounce rate và hỗ trợ hiệu quả SEO tổng thể.

Điểm Core Web Vitals tốt là bao nhiêu?

Một trang được xem là đạt nếu LCP dưới 2,5 giây, INP dưới 200 mili giây và CLS dưới 0,1. Google đánh giá dựa trên dữ liệu người dùng thực tế, nên cần theo dõi cả trên desktop lẫn mobile.

Làm sao kiểm tra Core Web Vitals của website?

Bạn có thể kiểm tra bằng Google PageSpeed Insights, Search Console, Lighthouse hoặc Chrome DevTools. Search Console phù hợp để theo dõi toàn site, còn PageSpeed Insights giúp xem chi tiết từng trang và gợi ý hướng tối ưu.

Nguyên nhân nào khiến LCP chậm?

LCP thường chậm do ảnh lớn, server phản hồi chậm, CSS hoặc JavaScript chặn hiển thị, và chưa tối ưu cache. Muốn cải thiện, nên nén ảnh, dùng định dạng phù hợp, giảm tài nguyên chặn render và nâng hiệu suất hosting.

INP kém thường do đâu?

INP kém chủ yếu do JavaScript nặng, xử lý tác vụ dài trên trình duyệt hoặc quá nhiều script bên thứ ba. Để cải thiện, hãy giảm tác vụ không cần thiết, chia nhỏ JavaScript và ưu tiên tải các phần phục vụ tương tác chính.

CLS cao là gì và khắc phục thế nào?

CLS cao nghĩa là bố cục trang bị nhảy khi đang tải, gây khó chịu cho người dùng. Cách khắc phục là khai báo kích thước rõ ràng cho ảnh, video, banner, iframe và tránh chèn nội dung mới phía trên nội dung đang hiển thị.

Core Web Vitals trên mobile và desktop có khác nhau không?

Có. Điểm trên mobile thường thấp hơn vì mạng chậm hơn, cấu hình thiết bị yếu hơn và màn hình nhỏ hơn. Khi tối ưu, nên ưu tiên trải nghiệm mobile trước vì đây thường là nguồn truy cập chính của nhiều website.

Sau khi tối ưu, bao lâu thì điểm Core Web Vitals cải thiện?

Nếu xem bằng Lighthouse hoặc PageSpeed Insights, bạn có thể thấy thay đổi ngay sau khi tối ưu. Nhưng với dữ liệu thực tế trong Search Console, Google thường cần thêm thời gian để thu thập đủ dữ liệu trước khi cập nhật trạng thái.

Bài viết liên quan

Hình ảnh đại diện của bài viết: 05 Công Cụ Nắm Bắt Xu Hướng Chuyên Sâu: Chìa Khóa Tối Ưu Chiến Dịch Quảng Cáo Mạng Xã Hội

05 Công Cụ Nắm Bắt Xu Hướng Chuyên Sâu: Chìa Khóa Tối Ưu Chiến Dịch Quảng Cáo Mạng Xã Hội

Khám phá 5 công cụ phân tích xu hướng chuyên sâu, từ TikTok Trends đến AI nhắm mục tiêu, cùng 10 lời khuyên chiến lược và các Case Study thực tế giúp thương hiệu tối ưu chiến dịch quảng cáo, tăng ROI và bứt phá doanh số trong mùa lễ hội sắp tới. Được cung cấp bởi Tấn Phát Digital.

Hình ảnh đại diện của bài viết: 10 Chiến Dịch Social Media Thành Công

10 Chiến Dịch Social Media Thành Công

Các chiến dịch social media thành công không chỉ giúp thương hiệu tăng độ nhận diện mà còn tạo ra sự kết nối mạnh mẽ với khách hàng. Bài viết này phân tích 10 chiến dịch social media truyền cảm hứng cùng những bài học chiến lược đáng giá.

Hình ảnh đại diện của bài viết: Chiến Lược Tăng Traffic Website Hiệu Quả & Bền Vững 2026 | Tấn Phát Digital

Chiến Lược Tăng Traffic Website Hiệu Quả & Bền Vững 2026 | Tấn Phát Digital

Báo cáo chuyên sâu về lộ trình tăng trưởng lưu lượng truy cập website tại thị trường Việt Nam, tập trung vào hiệu suất kỹ thuật, chiều sâu nội dung và xây dựng uy tín thực thể trong kỷ nguyên AI.

Hình ảnh đại diện của bài viết: 10 Sai lầm Từ khóa Volume Search & Chiến lược SEO

10 Sai lầm Từ khóa Volume Search & Chiến lược SEO

Đừng để con số Volume đánh lừa. Tấn Phát Digital phân tích sâu về Search Intent, độ khó và giá trị thương mại để xây dựng bộ từ khóa mang lại doanh thu bền vững thay vì chỉ là traffic ảo.

Hình ảnh đại diện của bài viết: 10 Xu hướng AI Marketing Cần Nắm Bắt Để Bứt Phá Trong Năm 2026

10 Xu hướng AI Marketing Cần Nắm Bắt Để Bứt Phá Trong Năm 2026

Năm 2026, AI không chỉ là công cụ mà là năng lực cạnh tranh cốt lõi. Khám phá 10 xu hướng đột phá: APM, Hyper-Orchestration, và Content Hybrid để làm chủ cuộc chơi Digital Marketing.

Hình ảnh đại diện của bài viết: 11 Bài Học Marketing Triệu View Từ Kênh Nông Sản | Ứng Dụng Mọi Lĩnh Vực

11 Bài Học Marketing Triệu View Từ Kênh Nông Sản | Ứng Dụng Mọi Lĩnh Vực

Khám phá 11 bài học marketing cảm xúc từ các kênh nông sản triệu view và cách ứng dụng vào mọi doanh nghiệp. Tấn Phát Digital giúp bạn xây dựng chiến lược nội dung doanh nghiệp có sức lan tỏa.

Hình ảnh đại diện của bài viết: 11 Dấu Hiệu Bạn Đang Thuê Nhầm Dịch Vụ SEO Năm 2026 | Tấn Phát Digital

11 Dấu Hiệu Bạn Đang Thuê Nhầm Dịch Vụ SEO Năm 2026 | Tấn Phát Digital

Nhận diện ngay 11 sai lầm chết người khi thuê SEO năm 2026 để bảo vệ doanh nghiệp trước các đợt cập nhật thuật toán AI khắt khe của Google thông qua phân tích chuyên sâu từ Tấn Phát Digital.

Hình ảnh đại diện của bài viết: 13 Tuyệt Chiêu Hook Video Triệu View Chạm Cảm Xúc 2026

13 Tuyệt Chiêu Hook Video Triệu View Chạm Cảm Xúc 2026

Chỉ cần 3 giây để thay đổi số phận một video. Tấn Phát Digital chia sẻ 13 công thức hook "thần thánh" giúp nội dung của bạn không thể bị lướt qua trong kỷ nguyên AI Search.

Zalo
Facebook
Tấn Phát Digital
Zalo
Facebook