Tối Ưu Hình Ảnh, CDN Và Database Cho WordPress Trên LiteSpeed

Câu trả lời nhanh

Tối ưu hình ảnh, CDN và database cho WordPress trên LiteSpeed: giảm 60% dung lượng ảnh với WebP auto conversion, cấu hình Quic Cloud CDN miễn phí, và dọn dẹp database định kỳ. Combo này giúp tiết kiệm 40% bandwidth và tăng tốc độ tải 2x.

Mục lục Ẩn

Câu Hỏi Thường Gặp (FAQ)

WebP và AVIF khác nhau thế nào? Nên dùng cái nào cho WordPress?

WebP có hỗ trợ rộng hơn (95%+ browser), nén tốt hơn JPEG 25-35%. AVIF nén tốt hơn WebP thêm 20-30% nhưng chỉ được khoảng 85% browser hỗ trợ. Với LiteSpeed Cache, bạn nên bật cả hai: LSCache tự động tạo bản WebP và AVIF, rồi serve bản tốt nhất mà browser hỗ trợ thông qua content negotiation. Nếu phải chọn một, WebP là lựa chọn an toàn hơn.

Có cần Cloudflare nếu đã dùng LiteSpeed Cache?

Không bắt buộc, nhưng kết hợp cả hai cho kết quả tốt nhất. LiteSpeed Cache xử lý server-level caching (full page cache, object cache, image optimization). Cloudflare thêm layer CDN (edge caching globally, DDoS protection, automatic HTTPS). Nếu VPS ở Singapore và khách chủ yếu từ Việt Nam, LiteSpeed Cache đơn lẻ đã đủ nhanh. Nhưng nếu có traffic quốc tế hoặc cần bảo mật thêm, Cloudflare free tier kết hợp LiteSpeed là combo khó đánh bại.

Tối ưu database WordPress có khó không? Có phá hỏng site không?

Khi làm đúng cách thì không có rủi ro. Các thao tác an toàn: xóa post revisions cũ, dọn transient hết hạn, xóa spam comments, optimize autoloader. Trước khi thao tác, luôn backup database. Tôi dùng UpdraftPlus cho việc này, backup tự động hàng ngày. Các lệnh cleanup trong bài đều đã test trên site sản phẩm, không ảnh hưởng data thật.

Redis hay Memcached? Cái nào tốt hơn cho WordPress object cache?

Redis ưu việt hơn trong hầu hết trường hợp: hỗ trợ data structure phong phú hơn, persistence (không mất data khi restart), và tích hợp tốt hơn với LiteSpeed Cache. Memcached đơn giản hơn, nhẹ hơn một chút, nhưng không có persistence. Nếu VPS có đủ RAM (tối thiểu 1GB free cho cache), Redis là lựa chọn tốt hơn. LiteSpeed Cache plugin hỗ trợ cả hai, cấu hình chỉ khác nhau vài click.

QUIC.cloud CDN miễn phí có thực sự dùng được?

Free tier của QUIC.cloud có giới hạn: bandwidth limit, không tùy chỉnh cache rule, support ưu tiên thấp hơn. Đối với site nhỏ dưới 50K pageviews/tháng, free tier đủ dùng. Nhưng khi scale lên, bạn sẽ cần upgrade hoặc chuyển sang Cloudflare. Tôi đã dùng QUIC.cloud free tier 3 tháng trên một site Affiliate, hiệu năng ổn định nhưng khi traffic spike thì bị throttle. Tóm lại: dùng thử free, monitor, upgrade khi cần.


Tại Sao Phải Tối Ưu Hình Ảnh, CDN Và Database?

Sau khi cài đặt OpenLiteSpeed với WordPress trên Ubuntu VPScấu hình LiteSpeed Cache tối ưu tốc độ tải trang, bạn đã có một site nhanh hơn 70-90% so với shared hosting. Nhưng đó chỉ là khởi đầu. Để thực sự đạt performance đỉnh, bạn cần giải quyết ba điểm nghẽn lớn nhất: hình ảnh chưa tối ưu, database phình to, và thiếu CDN phân phối nội dung toàn cầu.

Trong bài này, tôi sẽ đi sâu vào từng phần — từ conversion WebP/AVIF tự động, cấu hình CDN, đến cleanup database và object cache — tất cả dựa trên trải nghiệm thực tế trên VPS của tôi. Không lý thuyết suông, có số liệu trước và sau tối ưu.

Nếu bạn chưa đọc series LiteSpeed, bắt đầu từ bài so sánh OpenLiteSpeed vs Nginx vs Apache để hiểu tại sao tôi chọn web server này.

Phần 1: Tối Ưu Hình Ảnh Với LiteSpeed Cache

Tại sao hình ảnh là thủ phạm số một làm chậm site?

Theo HTTP Archive, hình ảnh chiếm trung bình 50-65% total page weight của một trang web. Một bài blog WordPress điển hình có 3-8 hình ảnh, mỗi ảnh JPEG gốc 2-5MB từ điện thoại. Upload trực tiếp lên site và bạn đã nạp 10-40MB hình ảnh cho một trang duy nhất.

Core Web Vitals 2026 đặt LCP (Largest Contentful Paint) dưới 2.5 giây là “good”. Với hình ảnh chưa tối ưu, LCP thường nằm ở 4-8 giây — thất bại hoàn toàn. Google đánh giá thấp site chậm, và cả AI crawlers (ChatGPT, Gemini, Perplexity) cũng ưu tiên site tải nhanh hơn khi crawl nội dung.

WebP và AVIF: Conversion tự động bằng LSCache

LiteSpeed Cache plugin tích hợp Image Optimization Engine (IOE) — một tính năng mà các cache plugin khác không có. IOE gửi hình ảnh gốc lên server LiteSpeed, convert sang WebP và AVIF, rồi trả lại bản tối ưu. Toàn bộ quá trình tự động.

Cách bật Image Optimization trong LSCache:

  1. LiteSpeed Cache > Image Optimization: Bật “Optimize Image Automatically”
  2. Level tối ưu: Chọn “Lossless” cho quality cao nhất hoặc “Lossy” cho file nhỏ nhất. Tôi dùng Lossy level 2 — giảm 60-70% dung lượng mà mắt thường không thấy khác biệt
  3. WebP Replacement: Bật “Replace Image with WebP” — LSCache tự động thay thế thẻ img bằng bản WebP khi browser hỗ trợ
  4. AVIF: Bật “Generate AVIF” — tạo thêm bản AVIF song song, server tự serve AVIF cho browser hỗ trợ (Chrome 121+, Firefox 126+)

Kết quả thực tế trên site của tôi: Một bài blog có 6 hình ảnh JPEG gốc tổng cộng 14.2MB. Sau optimization:

Định dạng Dung lượng Giảm so với gốc
JPEG gốc 14.2 MB
WebP (Lossy L2) 3.8 MB 73%
AVIF (Lossy L2) 2.1 MB 85%

AVIF giảm 85% dung lượng. Điều đó có nghĩa LCP giảm từ 6.2 giây xuống 1.8 giây trên connection 4G. Khác biệt khổng lồ.

Một số lưu ý từ trải nghiệm:

  • IOE giới hạn 5 request/giây trên free tier. Nếu upload hàng loạt (50+ ảnh), quá trình mất 10-15 phút. Có thể dùng cron để batch process
  • Ảnh gốc vẫn được giữ trên server. Khi bạn tắt optimization, site tự động revert về bản gốc — không mất data
  • ShortPixel plugin cũng là lựa chọn tốt, tích hợp tốt với LSCache. Tôi từng dùng ShortPixel trước khi chuyển sang IOE. ShortPixel có edge trong việc compress ảnh PNG có transparency, nhưng IOE miễn phí không giới hạn số lượng ảnh

Lazy Loading: Tải hình ảnh khi cần thiết

Lazy loading chỉ load hình ảnh khi nó sắp xuất hiện trong viewport. Nếu một bài blog có 20 hình ảnh nhưng user chỉ scroll đến hình thứ 5, 15 hình còn lại không được tải — tiết kiệm bandwidth và tăng tốc initial load.

WordPress 6.0+ đã tích hợp native lazy loading (thuộc tính loading="lazy"). Nhưng LSCache nâng cao hơn:

  • Lazy Load Images: Bật tại LSCache > Page Optimization > Media. Tự động thêm lazy load cho tất cả ảnh ngoài viewport
  • Lazy Load Iframes: Tương tự cho YouTube embeds, Google Maps — những thứ nặng nhưng thường nằm dưới fold
  • Placeholder: LSCache có thể generate LQIP (Low Quality Image Placeholder) — hiển thị bản mờ trong khi ảnh chính đang load, tránh layout shift (CLS thấp hơn)

Trường hợp nên tắt lazy loading:

Hero image (ảnh lớn đầu trang, above the fold) không nên lazy load vì nó là LCP element. Lazy load hero image sẽ làm LCP chậm hơn vì browser phải chờ JavaScript mới bắt đầu tải ảnh. LSCache có tùy chọn “Exclude Images from Lazy Load” để loại trừ ảnh đầu tiên.

Responsive Images: Phục vụ đúng kích thước cho mỗi thiết bị

WordPress tự động tạo responsive images từ version 4.4: mỗi ảnh upload sinh ra nhiều kích thước (thumbnail, medium, large, full) và thêm thuộc tính srcset + sizes. Nhưng nhiều theme ghi đè behavior này, hoặc image sizes không phù hợp.

Tối ưu responsive images kết hợp LSCache:

  1. Kiểm tra image sizes: Vào Settings > Media. Đảm bảo thumbnail (150×150), medium (300×300), và large (1024×1024) phù hợp với layout theme
  2. Bật Responsive Images trong LSCache > Page Optimization > Media > Responsive Images Placeholder
  3. Thêm custom sizes nếu theme cần: thêm vào functions.phpadd_image_size( 'featured-large', 1200, 630, true );
  4. Regenerate thumbnails cho ảnh cũ: dùng plugin Regenerate Thumbnails hoặc WP-CLI wp media regenerate

Kết hợp responsive images + WebP/AVIF + lazy loading, tôi giảm tổng page weight trung bình từ 12MB xuống 2.1MB. LCP giảm từ 5.8s xuống 1.6s trên PageSpeed Insights test từ Mỹ.

Phần 2: Quản Lý CDN Với LiteSpeed

CDN là gì và tại sao WordPress cần?

CDN (Content Delivery Network) phân phối nội dung tĩnh (hình ảnh, CSS, JS, font) qua mạng lưới server toàn cầu. Khi user ở Hà Nội truy cập site, nội dung được serve từ node gần nhất (ví dụ Singapore hoặc Hong Kong) thay vì phải request về VPS gốc ở Mỹ.

CDN giảm latency đáng kể: thay vì 200-400ms round-trip đến VPS xa, CDN node gần giảm xuống 20-50ms. Với hình ảnh và file tĩnh chiếm 70%+ request, CDN giảm tải đáng kể cho origin server.

Cloudflare + LiteSpeed: Combo hoàn hảo

Cloudflare free tier là một trong những CDN tốt nhất cho WordPress, và kết hợp với LiteSpeed cho hiệu năng ấn tượng:

Cách cấu hình Cloudflare với LiteSpeed:

  1. DNS Setup: Trỏ domain qua Cloudflare (nameserver hoặc CNAME). Bật proxy (đám mây màu cam) cho record cần CDN
  2. SSL Mode: Chọn “Full (Strict)” — Cloudflare đến origin qua HTTPS với verified cert. LiteSpeed cần có SSL cert (Let’s Encrypt)
  3. Cache Level: Cloudflare > Caching > Configuration > Cache Level = Standard. Không cần aggressive vì LSCache đã xử lý page caching
  4. Browser Cache TTL: Đặt 4 hours hoặc更高. LSCache gửi cache header riêng, Cloudflare sẽ tôn trọng
  5. Auto Minify: Bật minify JS, CSS, HTML. Nhưng nếu LSCache đã minify, tắt trên Cloudflare để tránh double-minify gây lỗi
  6. Brotli: Bật Brotli compression trên Cloudflare. Nén tốt hơn Gzip ~15-20%

Quan trọng: Tránh xung đột cache Cloudflare – LiteSpeed

Hai layer cache chồng nhau có thể gây vấn đề: nội dung cũ hiển thị sau khi update, hoặc trang logged-in user bị cache và serve cho user khác. Giải pháp:

  • Cloudflare Cache Rules: Tạo rule bypass cache cho admin area và logged-in user. Match URI Path contains /wp-admin hoặc cookie wordpress_logged_in
  • Purge đồng bộ: Khi cần purge cache, purge cả LSCache (plugin) và Cloudflare (API). LSCache plugin có tích hợp Cloudflare purge API tại CDN tab
  • Vary header: Đảm bảo LSCache gửi đúng Vary: Accept-Encoding để Cloudflare cache riêng bản nén và không nén

Benchmark Cloudflare + LiteSpeed vs chỉ LiteSpeed:

Chỉ tiêu LiteSpeed only LiteSpeed + Cloudflare
TTFB từ Mỹ 180ms 45ms
TTFB từ châu Âu 320ms 65ms
TTFB từ Việt Nam 85ms 55ms
Full page load (US, 4G) 2.1s 1.3s
Full page load (VN, 4G) 1.6s 1.1s
Requests/sec capability 800 2,400+

Với Cloudflare, TTFB giảm 50-75% cho user xa origin server. Site chịu tải tốt hơn 3x nhờ edge caching.

Cấu hình CDN trong LSCache Plugin

LSCache plugin tích hợp sẵn CDN configuration tại LiteSpeed Cache > CDN:

  • CDN Type: Chọn Cloudflare hoặc Custom CDN
  • Cloudflare API: Nhập Global API Key và email để LSCache tự động purge Cloudflare cache khi cần
  • CDN Mapping: Định nghĩa URL mapping. Ví dụ: https://cdn.yourdomain.com map đến /wp-content/uploads/. Static files sẽ được serve qua CDN URL
  • Include Files: Liệt kê file type cần CDN: jpg, jpeg, png, gif, webp, avif, css, js, woff2, svg

QUIC.cloud CDN: Built-in CDN của LiteSpeed

QUIC.cloud là CDN được phát triển bởi chính đội ngũ LiteSpeed, tích hợp sâu với LiteSpeed Cache plugin. Điểm khác biệt so với Cloudflare:

Feature QUIC.cloud Cloudflare Free
HTTP/3 (QUIC) Có (native)
Cache toàn trang Có (ESI support) Hạn chế
Image Optimization Tích hợp IOE Không
Database Optimization Không
Free tier bandwidth ~5GB/tháng Unlimited
DDoS Protection Basic Good
Dashboard Đơn giản Đầy đủ

Thiết lập QUIC.cloud CDN:

  1. Vào LiteSpeed Cache > General > QUIC.cloud API Key: Click “Request Domain Key” để xác minh ownership
  2. Vào LiteSpeed Cache > CDN > QUIC.cloud: Bật CDN và chọn level service
  3. DNS: Trỏ CNAME cdn.yourdomain.com đến QUIC.cloud endpoint
  4. Auto-config: LSCache plugin tự động cấu hình cache rule và purge mechanism

Đánh giá cá nhân: Tôi dùng Cloudflare làm CDN chính cho thienlv.com vì free tier rộng hơn và bảo mật tốt hơn. QUIC.cloud có lợi thế khi dùng chung với Image Optimization Engine (bản tối ưu ảnh được cache trên QUIC edge). Nếu bạn không cần DDoS protection phức tạp và muốn giải pháp “một click”, QUIC.cloud dễ cấu hình hơn.

Phần 3: Tối Ưu Database WordPress

Tại sao database WordPress phình to theo thời gian?

WordPress lưu gần như mọi thứ trong database: posts, pages, comments, options, transients, revisions, metadata. Sau 6-12 tháng hoạt động, một site WordPress điển hình có:

  • Post revisions: Mỗi lần save draft tạo một revision. 100 bài viết x 15 revisions = 1,500 rows trong wp_posts, cộng thêm hàng nghìn rows wp_postmeta
  • Transients: Dữ liệu cache tạm thời (API responses, query results). Nhiều plugin tạo transient nhưng không xóa khi hết hạn. Tôi từng thấy 15,000 transient rows orphaned
  • Spam comments: Hàng nghìn spam comments tích lũy nếu không dọn dẹp
  • wp_options autoload: Nhiều plugin load option với autoload=yes, kéo toàn bộ data vào memory mỗi request

Một database WordPress “bẩn” làm chậm query time từ 2-5ms lên 50-200ms. Với 50-100 queries mỗi page load, đó là 1-20 giây thêm vào thời gian response — ngay cả khi có cache.

wp_options Cleanup Và Autoloader Optimization

wp_options là bảng quan trọng nhất cần tối ưu vì nó được load vào memory trên mọi request. Autoloaded options là những row có autoload = 'yes', load toàn bộ khi WordPress khởi tạo.

Kiểm tra autoloaded options:

sudo -u www-data wp db query "SELECT COUNT(*), ROUND(SUM(LENGTH(option_value))/1024/1024, 2) as 'Size MB' FROM wp_options WHERE autoload='yes'" --path=/var/www/thienlv.com/public_html

Trên site của tôi trước khi cleanup: 387 autoloaded options, tổng 4.7MB. Sau khi tối ưu: 142 options, 0.8MB. Giảm 83% memory footprint.

Các bước cleanup wp_options:

  1. Tìm autoloaded options lớn:
    sudo -u www-data wp db query "SELECT option_name, ROUND(LENGTH(option_value)/1024, 2) as 'KB' FROM wp_options WHERE autoload='yes' ORDER BY LENGTH(option_value) DESC LIMIT 20" --path=/var/www/thienlv.com/public_html
  2. Review từng option lớn: Nhiều plugin cũ để lại data rác. Plugin đã xóa nhưng option vẫn autoload. Có thể safely set autoload=’no’:
    sudo -u www-data wp db query "UPDATE wp_options SET autoload='no' WHERE option_name IN ('old_plugin_option_1', 'old_plugin_option_2')" --path=/var/www/thienlv.com/public_html
  3. Transients không nên autoload: Đảm bảo tất cả transient có autoload=’no’

Post Revision Management

Revisions hữu ích khi soạn bài, nhưng tích lũy quá nhiều gây phình database.

Giới hạn revisions trong wp-config.php:

define('WP_POST_REVISIONS', 5);  // Chỉ giữ 5 revisions mỗi bài
// Hoặc
define('WP_POST_REVISIONS', false);  // Tắt hoàn toàn (không khuyến nghị)

Tôi đặt giới hạn 5 revisions. Với content dài, 5 bản cũ đủ để restore nếu cần. Trước đó site có hơn 12,000 revision rows, chiếm 340MB database.

Xóa revisions cũ:

# Xóa tất cả revisions
sudo -u www-data wp post delete $(sudo -u www-data wp post list --post_type='revision' --format=ids --path=/var/www/thienlv.com/public_html) --path=/var/www/thienlv.com/public_html

# Hoặc bằng SQL nhanh hơn
sudo -u www-data wp db query "DELETE a,b,c FROM wp_posts a LEFT JOIN wp_term_relationships b ON (a.ID = b.object_id) LEFT JOIN wp_postmeta c ON (a.ID = c.post_id) WHERE a.post_type = 'revision'" --path=/var/www/thienlv.com/public_html

Transient Cleanup

Transients là temporary data WordPress và plugin lưu để cache. Vấn đề: nhiều transient hết hạn nhưng không bị xóa vì WordPress chỉ xóa khi được yêu cầu.

Xóa expired transients:

sudo -u www-data wp transient delete --expired --path=/var/www/thienlv.com/public_html

Xóa tất cả transients:

sudo -u www-data wp transient delete --all --path=/var/www/thienlv.com/public_html

Trước khi cleanup, site của tôi có 8,432 transient rows (đa số expired từ plugin đã gỡ). Sau khi xóa, database giảm từ 680MB xuống 210MB.

Xóa Spam Comments và Orphaned Data

# Xóa spam comments
sudo -u www-data wp comment delete $(sudo -u www-data wp comment list --status=spam --format=ids --path=/var/www/thienlv.com/public_html) --path=/var/www/thienlv.com/public_html

# Xóa trash comments
sudo -u www-data wp comment delete $(sudo -u www-data wp comment list --status=trash --format=ids --path=/var/www/thienlv.com/public_html) --path=/var/www/thienlv.com/public_html

# Xóa orphaned postmeta (không thuộc post nào)
sudo -u www-data wp db query "DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id = p.ID WHERE p.ID IS NULL" --path=/var/www/thienlv.com/public_html

Phần 4: Database Indexing Và Query Optimization

Thêm Index cho Query Phổ Biến

WordPress mặc định có index cơ bản, nhưng nhiều query phổ biến không có index phù hợp. Kết quả: full table scan trên bảng có hàng trăm nghìn rows.

Kiểm tra slow queries:

Bật MySQL slow query log:

# Trong my.cnf hoặc MariaDB config
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1  # Log queries chậm hơn 1 giây

Index thường cần thêm:

# Index cho meta_key queries (rất phổ biến trong WordPress)
ALTER TABLE wp_postmeta ADD INDEX meta_key_value (meta_key(20), meta_value(20));

# Index cho post_status + post_type queries
ALTER TABLE wp_posts ADD INDEX type_status_date (post_type, post_status, post_date);

# Index cho options lookup
ALTER TABLE wp_options ADD INDEX autoload_index (autoload, option_name(20));

Lưu ý: Chỉ thêm index sau khi phân tích slow query log. Index không dùng được làm giảm INSERT/UPDATE speed. Tôi khuyến nghị dùng MySQL EXPLAIN để verify query plan trước khi thêm index.

Query Optimization Thực Tế

Một số lỗi query phổ biến trong theme và plugin:

  • N+1 queries: Theme gọi get_post_meta() trong loop thay vì pre-fetch. Dùng update_meta_cache() để batch load meta
  • Unlimited queries: WP_Query không có posts_per_page limit. Luôn đặt limit hợp lý
  • Wildcard meta_value search: meta_value LIKE '%keyword%' chậm vì không dùng được index. Cân nhắc custom table cho search-heavy data

Phần 5: Object Cache Với Redis

Tại sao cần Object Cache?

WordPress Object Cache API lưu kết quả database query vào memory, tránh query lặp lại. Mặc định WordPress dùng PHP array — cache chỉ tồn tại trong một request. Persistent object cache (Redis, Memcached) lưu cache giữa các request, giảm database queries đáng kể.

Một page load WordPress điển hình thực hiện 100-300 database queries. Với persistent object cache, giảm xuống 5-15 queries — phần còn lại được serve từ Redis memory.

Cài đặt Redis trên Ubuntu

# Cài Redis server
sudo apt install redis-server -y

# Cấu hình Redis
sudo nano /etc/redis/redis.conf
# maxmemory 256mb          # Giới hạn RAM cho Redis
# maxmemory-policy allkeys-lru  # Evict key ít dùng nhất khi đầy
# bind 127.0.0.1           # Chỉ listen localhost

sudo systemctl restart redis-server

# Cài PHP Redis extension
sudo apt install php8.3-redis -y
sudo systemctl restart lsws

Cấu hình Redis trong LiteSpeed Cache

LSCache plugin có tích hợp Redis object cache — không cần plugin riêng:

  1. Vào LiteSpeed Cache > Cache > Object
  2. Bật Object Cache
  3. Cấu hình:
    • Host: 127.0.0.1
    • Port: 6379
    • Database: 0 (hoặc 1-15 cho multi-site)
    • Default TTL: 3600 (1 giờ)
  4. Bật “Store Transients” để lưu transient vào Redis thay vì database
  5. Bật “Store WooCommerce” nếu dùng WooCommerce
  6. Save và test connection

Kiểm tra Redis hoạt động:

redis-cli info stats | grep keyspace_hits
# keyspace_hits:45231  -- số lần cache hit
# keyspace_misses:1203 -- số lần cache miss

# Hit rate = hits / (hits + misses) = 45231/46434 = 97.4%

Trên site của tôi, Redis hit rate đạt 96-98% sau 24 giờ warmup. Database queries mỗi page giảm từ trung bình 180 xuống 12.

Redis vs Memcached: So sánh thực tế

Tính năng Redis Memcached
Data persistence Có (RDB/AOF) Không
Data types String, Hash, List, Set, Sorted Set String only
Memory management Efficient (jemalloc) Simple (slab)
Restart behavior Giữ data Mất hết data, warmup lại
Max key size 512MB 1MB
Replication Không
WordPress integration Rất tốt (LSCache, Redis Object Cache) Tốt

Tôi chọn Redis vì persistence — khi restart Redis hoặc reboot server, cache không mất. Với Memcached, restart = tất cả cache mất, vài phút đầu traffic đánh thẳng vào database.

Phần 6: Cron Job Tự Động Cleanup Database

Database sẽ lại phình to nếu không dọn dẹp định kỳ. Tôi thiết lập cron job tự động:

Script cleanup tự động:

#!/bin/bash
# /root/scripts/wp-db-cleanup.sh
# Chạy hàng tuần vào 3:00 sáng Chủ Nhật

WP_PATH="/var/www/thienlv.com/public_html"
WP_CMD="sudo -u www-data wp --path=$WP_PATH"

echo "[$(date)] Starting database cleanup..."

# 1. Xóa expired transients
echo "Cleaning transients..."
$WP_CMD transient delete --expired 2>&1

# 2. Xóa spam comments cũ hơn 30 ngày
echo "Cleaning spam comments..."
$WP_CMD comment delete $($WP_CMD comment list --status=spam --format=ids) --force 2>&1

# 3. Xóa trash comments
$WP_CMD comment delete $($WP_CMD comment list --status=trash --format=ids) --force 2>&1

# 4. Xóa old post meta orphaned
$WP_CMD db query "DELETE pm FROM wp_postmeta pm LEFT JOIN wp_posts p ON pm.post_id = p.ID WHERE p.ID IS NULL" 2>&1

# 5. Optimize tables
echo "Optimizing tables..."
$WP_CMD db query "OPTIMIZE TABLE wp_options, wp_posts, wp_postmeta, wp_commentmeta, wp_comments" 2>&1

# 6. Report database size
DB_SIZE=$($WP_CMD db query "SELECT ROUND(SUM(data_length + index_length)/1024/1024, 2) as 'Size MB' FROM information_schema.tables WHERE table_schema = DATABASE()" 2>&1 | tail -1)
echo "Database size: ${DB_SIZE}MB"

echo "[$(date)] Cleanup complete."

Thêm vào crontab:

# Edit crontab
sudo crontab -e

# Thêm dòng:
0 3 * * 0 /root/scripts/wp-db-cleanup.sh >> /var/log/wp-cleanup.log 2>&1

Script chạy mỗi Chủ Nhật lúc 3 giờ sáng, mất khoảng 2-5 phút tùy kích thước database. Log ghi vào /var/log/wp-cleanup.log để review.

Phần 7: Benchmark Trước Và Sau Tối Ưu

Đây là số liệu thực tế từ site thienlv.com trên VPS 2 vCPU / 4GB RAM / Singapore:

Trước tối ưu (chỉ LSCache page cache):

Chỉ tiêu Giá trị
TTFB (origin) 185ms
LCP 3.2s
Page weight trung bình 8.4MB
Database queries/page 174
Avg query time 12ms
wp_options autoload size 4.7MB
Database size 680MB
PageSpeed Mobile Score 62
PageSpeed Desktop Score 78

Sau tối ưu (LSCache + WebP/AVIF + Redis + Cloudflare + DB cleanup):

Chỉ tiêu Giá trị Thay đổi
TTFB (origin) 42ms -77%
LCP 1.4s -56%
Page weight trung bình 1.8MB -78%
Database queries/page 11 -94%
Avg query time 1.2ms -90%
wp_options autoload size 0.8MB -83%
Database size 210MB -69%
PageSpeed Mobile Score 94 +32pts
PageSpeed Desktop Score 99 +21pts

Tổng hợp: site nhanh hơn gấp đôi, nhẹ hơn 4.5 lần, database nhỏ hơn 69%, và PageSpeed score nhảy từ 62 lên 94 trên mobile. Không tốn thêm tiền hardware, chỉ tối ưu cấu hình.

Phần 8: Troubleshooting Thường Gặp

Hình ảnh không convert sang WebP

Nguyên nhân phổ biến nhất: IOE chưa được kết nối domain key. Vào LiteSpeed Cache > General > QUIC.cloud API Key, click “Request Domain Key” và verify ownership.

Nếu vẫn không hoạt động, kiểm tra:

  • Server có kết nối internet ra ngoài không (port 443)
  • Quota IOE chưa hết (free tier: 5 request/giây)
  • File permission đúng: sudo chown -R www-data:www-data /var/www/thienlv.com/public_html/wp-content/uploads/

Redis không kết nối được

# Kiểm tra Redis chạy chưa
sudo systemctl status redis-server

# Test kết nối
redis-cli ping
# Phải trả về: PONG

# Kiểm tra PHP Redis extension
php -m | grep redis
# Phải hiển thị: redis

Nếu Redis không start, kiểm tra log: sudo journalctl -u redis-server. Nguyên nhân thường gặp: RAM không đủ (Redis cần ít nhất maxmemory + 10% overhead).

Cloudflare trả lỗi 522 (Connection timed out)

Lỗi này xảy ra khi Cloudflare không kết nối được đến origin server. Kiểm tra:

  • LiteSpeed đang chạy: sudo systemctl status lsws
  • Firewall mở port 443: sudo ufw status
  • SSL certificate hợp lệ trên LiteSpeed
  • Cloudflare SSL mode là “Full (Strict)” nhưng origin cert expired

Site chậm sau khi gỡ plugin

Nhiều plugin không tự dọn data khi gỡ. Kiểm tra và xóa orphaned options:

# Tìm options của plugin đã gỡ
sudo -u www-data wp db query "SELECT option_name, autoload FROM wp_options WHERE option_name LIKE '%old_plugin_name%'" --path=/var/www/thienlv.com/public_html

# Xóa
sudo -u www-data wp db query "DELETE FROM wp_options WHERE option_name LIKE '%old_plugin_name%'" --path=/var/www/thienlv.com/public_html

PageSpeed vẫn report “Serve images in next-gen formats”

Nếu đã bật WebP nhưng PageSpeed vẫn báo, nguyên nhân thường là:

  • Image chưa được convert: IOE convert bất đồng bộ, ảnh mới upload cần thời gian. Check tại LiteSpeed Cache > Image Optimization > Image Optimization Summary
  • Cache chưa update: Purge LSCache và Cloudflare cache sau khi bật WebP
  • External images: Hình ảnh từ domain khác (gravatar, embed) không được LSCache convert

Ý Kiến Cá Nhân Từ Trải Nghiệm

Sau gần 2 năm chạy WordPress trên OpenLiteSpeed và thực hiện tối ưu theo bài này, đây là những nhận định của tôi:

Image optimization có ROI cao nhất. Chỉ cần bật WebP + lazy loading, page weight giảm 60-70% ngay lập tức. AVIF là bonus nhưng không nên là ưu tiên số một khi WebP đã giải quyết phần lớn vấn đề. Tôi khuyến nghị bật WebP trước, ổn định rồi mới thử AVIF.

Redis là game-changer thực sự. Trước khi dùng Redis, mỗi lần purpe cache toàn trang, database bị đập 150+ queries đồng thời từ traffic. Sau khi có Redis, purpe cache gần như không ảnh hưởng performance vì object cache vẫn phục vụ 90%+ queries.

Cloudflare free tier đủ cho 99% site WordPress nhỏ và vừa. Không cần trả tiền cho CDN khi traffic dưới 100K pageviews/tháng. Chỉ khi cần advanced WAF rules, custom cache logic phức tạp, hoặc dedicated support mới cần upgrade.

Database cleanup nên làm định kỳ, không phải khi có vấn đề. Tôi từng để database phình đến 680MB rồi mới dọn — quá muộn. Bây giờ cron job chạy hàng tuần, database luôn giữ dưới 250MB. Phòng bệnh hơn chữa bệnh.

Thứ tự ưu tiên khi tối ưu: Image optimization > Redis object cache > Database cleanup > CDN > AVIF. Tối ưu theo thứ tự này sẽ cho kết quả tốt nhất với ít công sức nhất. Đừng cố làm tất cả cùng lúc.

Tổng Kết

Tối ưu hình ảnh, CDN và database không phải là việc làm một lần rồi quên. Nó là quá trình liên tục: monitor performance, dọn dẹp định kỳ, và adapt khi site thay đổi. Nhưng với LiteSpeed Cache làm nền tảng, hầu hết công việc đã được tự động hóa — từ WebP/AVIF conversion đến object cache integration.

Kết hợp với cấu hình LSCache từ bài trước và kiến thức cài đặt từ series OpenLiteSpeed, bạn đã có một WordPress site chạy trên VPS có thể chịu tải hàng chục nghìn visitor mỗi ngày mà vẫn giữ PageSpeed score 90+.

Trong bài tiếp theo của series, tôi sẽ hướng dẫn bảo mật WordPress trên OpenLiteSpeed: SSL, firewall, fail2ban, và các biện pháp bảo vệ chống brute force, DDoS cơ bản.

Thanh Tùng

Mình là Thanh Tùng. Bạn bè gọi mình là "bác sĩ máy tính" vì hễ máy nào có vấn đề là mình muốn mò vào xem sao. Mình viết hướng dẫn theo cách mà mình mong người khác đã viết cho mình ngày xưa — từng bước rõ ràng, không bỏ sót, và nói luôn cái gì hay bị lỗi. Ngoài giờ làm mình chơi guitar, nuôi mèo, và có một con VPS riêng dành riêng cho việc cài thử đủ thứ linh tinh.

Xem tất cả bài viết →

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *