وردپرس

آموزش افزایش سرعت سایت وردپرسی — از هاست تا کش

افزایش سرعت سایت وردپرسی به ترتیب لایه‌ها: اول زیرساخت و نسخه‌ی PHP، بعد کش صفحه و OPcache، سپس تصویر و فایل‌های ایستا، و در پایان اندازه‌گیری دوباره با عدد

افزایش سرعت سایت وردپرسی یک کار نیست، یک ترتیب است: تا وقتی زیرساخت و کش سر جای خودشان نباشند، فشرده‌کردن تصویر و حذف دو افزونه فقط چند صدم ثانیه جابه‌جا می‌کند. کندی چندثانیه‌ای معمولاً از چهار پنج جای مشخص می‌آید، نه از یک راز پنهان. اینجا همان مسیر لایه‌به‌لایه را می‌رویم، با دستورهایی که واقعاً اجرا می‌شوند و اعدادی که منبع دارند.

«سایتم کند است» یعنی چه؟ اول گلوگاه را پیدا کنید

کندی وردپرس تقریباً همیشه یکی از دو خانواده است، با درمان‌های بی‌ربط به هم. زمان سرور از رسیدن درخواست تا اولین بایت HTML است؛ جای اجرای PHP و کوئری MySQL، شاخصش TTFB و درمانش کش و دیتابیس سبک‌تر. زمان مرورگر از رسیدن HTML تا دیده‌شدن صفحه است؛ جای CSS و جاوااسکریپت و فونت و تصویر. یک دستور این دو را جدا می‌کند:

curl -o /dev/null -s -w \
 "dns:%{time_namelookup} tcp:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" \
 https://example.com/

dns:0.028 tcp:0.061 tls:0.134 ttfb:0.812 total:0.874

از ۸۱۲ میلی‌ثانیه TTFB این نمونه، ۱۳۴ میلی‌ثانیه صرف DNS و TCP و TLS شده و ۶۸۰ میلی‌ثانیه‌ی بعدی زمان ساختن صفحه در سرور است؛ پس پرونده روی PHP و دیتابیس باز است، نه شبکه. معیارهای گوگل هم همین تفکیک را دارند: LCP زیر ۲٫۵ ثانیه، INP زیر ۲۰۰ میلی‌ثانیه و CLS زیر ۰٫۱ — روی صدک ۷۵ کاربران واقعی، نه یک تست خوش‌شانس.

لایه‌ی صفر: زیرساختی که وردپرس روی آن نفس می‌کشد

هیچ افزونه‌ی کشی دیسک کُند و سرور آن‌سر دنیا را جبران نمی‌کند. قبل از نصب هر چیزی، سه مشخصه را چک کنید:

  • دیسک NVMe — وردپرس در هر بازدید ده‌ها فایل PHP می‌خواند و چندین کوئری MySQL می‌زند. NVMe گلوگاه گذرگاه SATA را برمی‌دارد و تأخیر هر خواندن را پایین می‌آورد؛ برای یک بازدید تنها تفاوت محدود است و اثر واقعی‌اش وقتی پیداست که چند بازدیدکننده هم‌زمان روی دیسک صف بکشند. تفاوت دقیقشان در راهنمای KVM و NVMe آمده.
  • نسخه‌ی PHP به‌روز — در بنچمارک‌های Kinsta وردپرس استاندارد روی PHP 7.4 حدود ۱۳۹ و روی PHP 8.5 حدود ۱۴۸ درخواست در ثانیه پاسخ داده — نزدیک ۷ درصد، نه چند برابر. اما همان تست روی ووکامرس از ۴۴ به ۷۱ می‌رسد، و تقریباً همه‌اش مال 8.5 است چون ووکامرس روی ۸٫۲ تا ۸٫۴ حدود ۵۳ تا ۵۵ می‌ماند: کد سنگین‌تر، فضای بیشتر برای بهبود.
  • سرور نزدیک به بازدیدکننده — پینگ کاربر ایرانی به سرور اروپا معمولاً ۸۰ تا ۱۵۰ میلی‌ثانیه است و به سرور داخل کشور زیر ۳۰؛ چون هر صفحه ده‌ها رفت‌وبرگشت دارد، این اختلاف چند صد میلی‌ثانیه در بارگذاری واقعی تفاوت می‌سازد. سرورهای ابری مهران هاست به همین دلیل در دیتاسنتر داخل ایران و روی NVMe ارائه می‌شوند.

نسخه‌ی PHP فعلی‌تان را همین حالا بررسی کنید:

php -v
# PHP 7.4.33 (cli) (built: Nov  4 2022 10:32:56) ( NTS )

# اوبونتو 24.04 در مخزن رسمی تا 8.3 دارد؛ برای 8.4:
sudo add-apt-repository ppa:ondrej/php && sudo apt update
sudo apt install php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd \
  php8.4-mbstring php8.4-xml php8.4-zip php8.4-imagick

یک تذکر: این دستور نسخه‌ی php-cli را می‌دهد، نه لزوماً نسخه‌ای که سایت با آن اجرا می‌شود؛ نسخه‌ی واقعی PHP-FPM در «ابزارها ← سلامت سایت ← اطلاعات» است. کدام نسخه را هدف بگیرید؟ PHP 7.4 و 8.1 دیگر وصله نمی‌گیرند، 8.2 پایان عمرش دی ۱۴۰۵ است و 8.3 فقط وصله‌ی امنیتی می‌گیرد؛ پشتیبانی فعال روی 8.4 و 8.5 است. pm.max_children هم مهم است: کم، یعنی صف‌بستن درخواست‌ها در ساعت شلوغی؛ زیاد، یعنی تمام‌شدن رم.

کش وردپرس: بزرگ‌ترین جهش در افزایش سرعت وردپرس

ایده‌ی کش صفحه ساده است: وردپرس برای هر صفحه PHP اجرا می‌کند و کوئری می‌زند، ولی صفحه‌ای که برای همه یکسان است چرا هر بار از نو ساخته شود؟ کش وردپرس HTML آماده را یک بار می‌سازد و دفعات بعد همان را می‌دهد — بدون PHP، بدون دیتابیس. تنها تغییری است که TTFB را به چند ده میلی‌ثانیه می‌رساند.

راه ساده: افزونه‌ی کش

اگر دسترسی root ندارید، WP Super Cache (ساده) یا W3 Total Cache (پرامکانات‌تر ولی پیچیده‌تر) را نصب کنید؛ در اولی کافی است «Caching On» و روش «Expert» (mod_rewrite) را فعال کنید تا HTML مستقیم سرو شود. و هرگز دو افزونه‌ی کش صفحه را هم‌زمان فعال نکنید؛ نتیجه‌اش صفحه‌های نصفه‌کش‌شده است.

راه حرفه‌ای: fastcgi_cache در Nginx

روی سرور مجازی خودتان، کش در لایه‌ی وب‌سرور از هر افزونه‌ای سریع‌تر است چون درخواست اصلاً به PHP نمی‌رسد:

fastcgi_cache_path /var/cache/nginx levels=1:2
    keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

server {
    # ... تنظیمات فعلی سایت ...
    set $skip_cache 0;
    if ($request_method = POST) { set $skip_cache 1; }
    if ($query_string != "")    { set $skip_cache 1; }
    if ($http_cookie ~* "comment_author|wordpress_logged_in|wp-postpass") {
        set $skip_cache 1;
    }
    if ($request_uri ~* "/wp-admin/|/cart/|/checkout/|/my-account/") {
        set $skip_cache 1;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
        add_header X-Cache $upstream_cache_status;
    }
}

هدر X-Cache می‌گوید هر درخواست از کش آمده (HIT) یا نه (MISS). به fastcgi_cache_key دقت کنید: پیش‌فرض ندارد و بدون آن Nginx با خطای no "fastcgi_cache_key" for "fastcgi_cache" بالا نمی‌آید — رایج‌ترین دلیل شکست کانفیگ‌های کپی‌شده. اگر با Nginx آشنا نیستید، اول راهنمای راه‌اندازی سایت با Nginx را بخوانید.

چطور مطمئن شوم کش واقعاً کار می‌کند؟

ادعای پنل افزونه را باور نکنید؛ پاسخ سرور را ببینید. دو بار پشت سر هم همان آدرس را بخواهید.

curl -sI https://example.com/ | grep -iE "x-cache|cache-control|age"
# x-cache: MISS

curl -sI https://example.com/ | grep -iE "x-cache|cache-control|age"
# x-cache: HIT
# cache-control: max-age=3600

اگر بار دوم هم MISS بود، چیزی کش را دور می‌زند: کوکی‌ای که همه می‌گیرند (آمارگیر، نوار اعلان)، یا شرطی زیادی گسترده — مثلاً $query_string != "" در نمونه‌ی بالا که لینک‌های کمپین با utm_source را هم بی‌کش می‌کند.

⚠️ کاربر لاگین‌شده و سبد خرید ووکامرس نباید کش شوند — شرط‌های skip_cache بالا همین را کنترل می‌کنند. بعد از فعال‌سازی کش، فرایند خرید را با یک کاربر تست کنید؛ سبدِ کش‌شده یعنی مشتری سبد مشتری قبلی را می‌بیند.

OPcache: کشِ خودِ PHP را روشن کنید

حتی وقتی صفحه کش نمی‌شود (مثلاً برای کاربر لاگین‌شده)، لازم نیست PHP هر بار فایل‌ها را از نو کامپایل کند. OPcache بایت‌کد را در حافظه نگه می‌دارد و در PHP های مدرن پیش‌فرض فعال است — ولی مقادیر پیش‌فرضش یعنی ۱۲۸ مگابایت حافظه و سقف ۱۰٬۰۰۰ فایل، برای وردپرسی با قالب و بیست افزونه کم است. در php.ini:

opcache.enable=1
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=16000
opcache.validate_timestamps=1
opcache.revalidate_freq=60

و بعد sudo systemctl reload php8.4-fpm. سه نکته‌ی گم‌شده در راهنماهای کپی‌شده: max_accelerated_files به عدد اولی از فهرستی ثابت گرد می‌شود، پس ۱۶۰۰۰ عملاً ۱۶۲۲۹ است؛ interned_strings_buffer از داخل memory_consumption کم می‌شود، نه اضافه بر آن؛ و validate_timestamps=0 سریع‌ترین حالت است اما هر تغییر فایل را تا ریستارت سرویس نادیده می‌گیرد. همین چند خط، کم‌زحمت‌ترین بردِ بهینه‌سازی وردپرس است.

⚠️ php -r 'print_r(opcache_get_status(false));' وضعیت OPcache نسخه‌ی CLI را می‌دهد، که جدا از OPcache پروسه‌های PHP-FPM است و اغلب خالی به نظر می‌رسد. برای وضعیت واقعی یک phpinfo() موقت بگذارید و حذفش کنید.

کش آبجکت پایدار: وقتی کش صفحه کافی نیست

کش صفحه فقط صفحه‌های عمومی و یکسان را نجات می‌دهد؛ هر بازدید کش‌نشدنی — کاربر لاگین‌شده، سبد خرید، پیشخوان، admin-ajax — همچنان ده‌ها کوئری تکراری می‌زند، و کش آبجکت نتیجه‌شان را در حافظه نگه می‌دارد. کش آبجکت پیش‌فرض وردپرس «غیرپایدار» است و با پایان هر درخواست پاک می‌شود؛ کش پایدار یعنی همان داده‌ها در Redis یا Memcached بمانند. از وردپرس ۶٫۱ «سلامت سایت» هم نبودنش را گزارش می‌کند — ولی به‌عنوان پیشنهاد، و فقط بالای آستانه‌های داخلی هسته.

sudo apt install redis-server php8.4-redis
sudo systemctl enable --now redis-server

# سپس افزونه‌ی Redis Object Cache را نصب و فعال کنید، و در wp-config.php:
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_CACHE_KEY_SALT', 'example.com:');

redis-cli info stats | grep keyspace
# keyspace_hits:184320
# keyspace_misses:9117

دو صداقت لازم. اول اینکه سرور مجازی می‌خواهد و روی هاست اشتراکی نیست؛ مسیر کاملش در راهنمای وردپرس روی سرور مجازی آمده. دوم اینکه برای وبلاگی که همه‌ی صفحاتش کش صفحه دارند تفاوت محسوسی نمی‌سازد؛ سودش برای فروشگاه ووکامرس و سایت عضویتی است، جایی که تسویه‌حساب ذاتاً کش‌نشدنی است.

تصاویر: سنگین‌ترین مسافر هر صفحه

در یک صفحه‌ی معمولی وردپرس بیش از نیمی از حجم دانلود تصویر است. چهار کار عملی:

  1. فرمت WebP — گوگل در مستندات رسمی WebP می‌گوید WebP با اتلاف در کیفیت هم‌ارز ۲۵ تا ۳۴ درصد کوچک‌تر از JPEG است و بدون اتلاف ۲۶ درصد کوچک‌تر از PNG. افزونه‌هایی مثل EWWW یا Imagify تصاویر قدیمی را یک‌جا تبدیل می‌کنند؛ روی سرور خودتان یک خط کافی است: cwebp -q 82 photo.jpg -o photo.webp.
  2. ابعاد درست — تصویر ۴۰۰۰ پیکسلی را برای باکس ۸۰۰ پیکسلی آپلود نکنید؛ وردپرس سایزهای میانی می‌سازد، ولی قالب باید از آن‌ها استفاده کند.
  3. Lazy loading — وردپرس از نسخه‌ی ۵٫۵ پیش‌فرض loading="lazy" می‌گذارد؛ فقط مطمئن شوید افزونه یا قالبی خرابش نکرده باشد.
  4. عرض و ارتفاع اعلام‌شده — تگ img بدون width و height باعث پریدن صفحه هنگام رسیدن تصویر می‌شود؛ همان چیزی که در CLS جریمه می‌شود. ضمناً وردپرس فقط به تصویرهای دارای این دو صفت loading="lazy" اضافه می‌کند.

از وردپرس ۶٫۳ هسته به محتمل‌ترین تصویر LCP صفت fetchpriority="high" می‌دهد و از lazy loading مستثنایش می‌کند؛ طبق اعلام تیم هسته‌ی وردپرس معمولاً ۵ تا ۱۰ درصد LCP را بهتر می‌کند. دخالت دستی لازم نیست؛ فقط مراقب افزونه‌های «لِیزی‌لود پیشرفته» باشید که این منطق را بازنویسی می‌کنند.

💡 نکته: تصویر بالای صفحه اگر با CSS به‌عنوان background-image گذاشته شده باشد، از دید وردپرس پنهان است و اولویت نمی‌گیرد؛ برایش <link rel="preload" as="image"> بگذارید.

CSS و جاوااسکریپت: چیزی که جلوی نمایش صفحه را می‌گیرد

مرورگر تا همه‌ی CSS و اسکریپت‌های بدون defer یا async را نگرفته و پردازش نکرده، چیزی روی صفحه نمی‌کشد. به این‌ها «منابع مسدودکننده‌ی رندر» می‌گویند و در وردپرس معمولاً از یک جا می‌آیند: افزونه‌هایی که فایل خودشان را در همه‌ی صفحه‌ها بار می‌کنند، حتی جایی که کاری ندارند. اول بشمارید:

curl -s https://example.com/ | grep -oE '<(link[^>]*stylesheet|script[^>]*src)[^>]*>' | wc -l
# 34

سی‌وچهار فایل برای صفحه‌ی اصلی یک سایت محتوایی زیاد است. فایل افزونه‌ی فرم تماس فقط در همان صفحه لازم است؛ با wp_dequeue_style() و wp_dequeue_script() در قالب فرزند از بقیه برش دارید. هر اسکریپت غیرضروری برای اولین نمایش باید defer بگیرد، و فونت با font-display: swap بیاید وگرنه مرورگر تا رسیدنش متن را نشان نمی‌دهد.

یک توصیه‌ی قدیمی را هم کنار بگذارید: «همه‌ی CSS و JS را در یک فایل ادغام کن». این حرف مال HTTP/1.1 بود که مرورگر همزمان فقط چند اتصال داشت. روی HTTP/2 و HTTP/3 چند فایل کوچک روی یک اتصال مالتی‌پلکس می‌شوند و ادغام اجباری فقط کش را بی‌اثر می‌کند: تغییر یک افزونه، کل فایل را برای همه باطل می‌کند.

رژیم افزونه و خانه‌تکانی دیتابیس

ارزان‌ترین راه افزایش سرعت وردپرس، اضافه‌کردن نیست؛ حذف چیزهایی است که لازم ندارید.

افزونه کم، سایت سبک

هر افزونه‌ی فعال یعنی PHP بیشتر و اغلب چند فایل CSS/JS اضافه. قاعده‌ی سرانگشتی: بالای ۲۰ افزونه‌ی فعال وقت بازنگری است. با Query Monitor رایگان ببینید کدام‌ها کندترین کوئری‌ها را دارند؛ اسلایدرها، آمارگیر داخلی و بیلدرهای سنگین متهم‌های ردیف اول‌اند.

تله‌ی autoload در جدول wp_options

وردپرس پیش از ساختن هر صفحه، همه‌ی ردیف‌های «خودبارشونده»ی wp_options را یک‌جا می‌خواند. افزونه‌های بدنوشته آرایه‌های بزرگ را همان‌جا می‌گذارند و این حجم مالیاتی ثابت روی هر درخواست می‌شود. وردپرس ۶٫۶ برای همین بررسی‌ای در «سلامت سایت» افزود، با آستانه‌ی هشدار ۸۰۰٬۰۰۰ بایت. اندازه‌ی خودتان را ببینید:

wp option list --autoload=on --format=total_bytes
# 2418733

wp db query "SELECT option_name, ROUND(LENGTH(option_value)/1024) AS kb
  FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on')
  ORDER BY LENGTH(option_value) DESC LIMIT 5"
# option_name                    kb
# oldplugin_scan_results        912
# _transient_feed_ab12cd34      301
# theme_mods_mytheme             77

ردیف اول گویاست: نتیجه‌ی اسکن افزونه‌ای که سال‌ها پیش حذف شده، هنوز در هر بازدید خوانده می‌شود. چنین ردیف‌هایی را — بعد از بکاپ — پاک یا غیرخودبارشونده کنید. اگر عدد WP-CLI با «سلامت سایت» نخواند تعجب نکنید: فیلتر --autoload=on فقط on و yes را می‌شمارد و auto و auto-on را جا می‌اندازد؛ کوئری بالا هر چهار را می‌گیرد.

دیتابیس را جارو کنید

transient های منقضی‌شده و ریویژن‌های بی‌پایان پست‌ها جدول‌ها را باد می‌کنند. افزونه‌ی WP-Optimize ریویژن، پیش‌نویس خودکار، کامنت اسپم و transient مرده را پاک می‌کند. با WP-CLI همین کار دو خط است؛ برای جمع‌نشدن دوباره، سقف ریویژن بگذارید:

wp transient delete --expired
wp db optimize

# wp-config.php
define('WP_POST_REVISIONS', 5);

دو مصرف‌کننده‌ی پنهان: Heartbeat و wp-cron

Heartbeat در ویرایشگر هر ۱۵ ثانیه و در پیشخوان هر ۶۰ ثانیه یک درخواست به admin-ajax.php می‌زند؛ برای یک نویسنده بی‌اهمیت است، برای ده‌ها ادمین هم‌زمان ترافیک جدی PHP. wp-cron هم کرون واقعی نیست و کارهای زمان‌بندی‌شده را روی بازدید کاربران سوار می‌کند؛ راه درست، کرون سیستم است:

# wp-config.php
define('DISABLE_WP_CRON', true);

# crontab -e
*/5 * * * * cd /var/www/example.com && /usr/bin/php8.4 wp-cron.php >/dev/null 2>&1

ساختار crontab و تله‌های رایجش را در راهنمای کرون‌جاب لینوکس توضیح داده‌ایم.

⚠️ قبل از هر عملیات روی دیتابیس بکاپ بگیرید: wp db export backup.sql یا خروجی phpMyAdmin. سی ثانیه احتیاط، ساعت‌ها پشیمانی را حذف می‌کند — و اگر بکاپ منظم ندارید، راهنمای بکاپ‌گیری از سرور را همین امروز پیاده کنید.

بازدیدکننده‌ی ایرانی: تله‌هایی که در راهنماهای خارجی نیست

بیشتر مقاله‌های سرعت وردپرس فرض می‌کنند کاربر و سرور در یک اینترنت بی‌دردسرند. برای سایت فارسی این فرض غلط است و دو تفاوت جدی می‌سازد.

اول، وابستگی به میزبان‌های خارجی: هر فونت گوگل، آواتار Gravatar و کتابخانه‌ی جاوااسکریپت از CDN خارجی یعنی یک جست‌وجوی DNS و اتصال TCP و TLS تازه روی گذرگاه بین‌الملل؛ در دسترس هم که باشند صدها میلی‌ثانیه اضافه می‌کنند، و وقتی نباشند مرورگر تا انقضای مهلت منتظر می‌ماند. راه‌حل، آوردن همین‌ها روی دامنه‌ی خودتان است: فونت را با @font-face محلی بدهید، Gravatar را خاموش کنید و کتابخانه‌ها را کنار قالب بگذارید.

دوم، مسیر شبکه: سایت کاملاً بهینه هم اگر سرورش خارج از کشور باشد هزینه‌ی ثابت رفت‌وبرگشت را می‌پردازد، و در ساعت شلوغی نوسانش از خودش بدتر است. دو راه دارید: مبدأ را داخل کشور بیاورید، یا دست‌کم فایل‌های ایستا را از شبکه‌ی توزیع محتوایی با نود ایران بدهید — که HTML داینامیک را نجات نمی‌دهد ولی تصویر و CSS و JS را از نزدیک‌ترین نود می‌رساند.

💡 یک تست ساده: صفحه‌ی اصلی را در زبانه‌ی Network ابزار توسعه‌دهنده باز کنید و ستون دامنه را نگاه کنید. هر دامنه‌ای جز دامنه‌ی خودتان وابستگی خارجی است و باید توجیه داشته باشد.

اندازه‌گیری: بدون عدد، بهینه‌سازی حدس است

سرعت سایت وردپرس را قبل و بعد از هر تغییر بسنجید، وگرنه نمی‌فهمید کدام کار جواب داده. سه ابزار کافی است: PageSpeed Insights برای Core Web Vitals با داده‌ی کاربران واقعی (روی سایت کم‌ترافیک خالی می‌ماند)، GTmetrix برای آبشار بارگذاری، و curl برای TTFB خالص:

for i in 1 2 3; do
  curl -o /dev/null -s -w "%{time_starttransfer}\n" https://example.com/
done
# 0.812
# 0.104
# 0.098

یعنی اولین درخواست کش را گرم کرده و دو تای بعدی از کش آمده‌اند؛ اگر هر سه بزرگ بودند، کش صفحه کار نمی‌کند. جدول زیر از نشانه به علت می‌رساندتان:

نشانهعلت محتملاقدام
TTFB بالا در همه‌ی صفحه‌ها، حتی تکراریکش صفحه فعال نیست یا دور زده می‌شودهدر کش را با curl -sI ببینید؛ کوکی‌ها و query string را بررسی کنید
TTFB فقط در ساعت شلوغی بالا می‌رودکمبود پروسه‌ی PHP-FPM یا رمpm.max_children و مصرف حافظه را بازبینی کنید
پیشخوان کند، سایت سریعحجم زیاد داده‌ی autoload یا Heartbeatاندازه‌ی autoload را بسنجید و ردیف‌های یتیم را پاک کنید
TTFB خوب، ولی صفحه دیر دیده می‌شودمنابع مسدودکننده‌ی رندر یا فونتاسکریپت‌های غیرضروری را defer و فونت را با swap بار کنید
چیدمان صفحه هنگام بارگذاری می‌پردنبود width و height روی تصویرهاابعاد را در HTML اعلام کنید تا CLS اصلاح شود
برای شما سریع، برای کاربران کندوابستگی خارجی یا فاصله‌ی جغرافیاییمنابع خارجی را محلی یا فایل‌های ایستا را روی CDN ببرید

عدد قطعی برای «بعد از هر لایه» نمی‌دهیم، ولی ترتیب بزرگی اثر ثابت است: کش صفحه TTFB را از چند صد میلی‌ثانیه به چند ده می‌رساند؛ نزدیک‌کردن سرور ۸۰ تا ۱۵۰ میلی‌ثانیه از هر رفت‌وبرگشت می‌کاهد؛ ارتقای PHP چند درصد است، نه چند برابر؛ و کار روی تصویر و اسکریپت به TTFB کاری ندارد ولی LCP را جابه‌جا می‌کند. پس اول زیرساخت و کش، بعد تصاویر، بعد جزئیات.

ابزارها و سرویس‌های مهران هاست برای سرعت وردپرس

برای عددگرفتن از وضعیت فعلی، آزمون سرعت و سلامت سایت رایگان است و چیزی نصب نمی‌کند. بررسی می‌کند: زمان پاسخ DNS، شناسایی سرویس‌دهنده و CDN، سه نمونه‌گیری TTFB، نسخه‌ی پروتکل (HTTP/2 و HTTP/3)، فشرده‌سازی HTML و CSS و JS، هدرهای کش مرورگر، فرمت و حجم تصاویر، lazy loading، فایل‌های مسدودکننده‌ی نمایش و افشای آی‌پی سرور اصلی — و به‌جای یک نمره، فهرستی مرتب بر اساس اثر هر اصلاح می‌دهد. یک صداقت لازم: درخواست‌ها از سرور خودِ ما می‌روند و آن سرور در ایران نیست، پس TTFB این گزارش را مبنای مقایسه‌ی قبل و بعدِ خودتان بدانید، نه تجربه‌ی بازدیدکننده‌ی ایرانی.

سه سرویس هم به لایه‌های بالا می‌خورند: هاست اشتراکی روی cPanel یا DirectAdmin، که کارهای روزمره‌اش — دیتابیس، فایل منیجر، کرون‌جاب، SSL رایگان و بکاپ — از پنل فارسی انجام می‌شود؛ سرور ابری ساعتی روی KVM و NVMe در دیتاسنتر داخل ایران، برای تست چندساعته‌ی نسخه‌ی آزمایشی؛ و CDN با نودهای لبه در ایران و اروپا، که با یک کلید کنار رکورد A فعال می‌شود و روی دامنه‌ی با DNS همین‌جا هزینه‌ی جداگانه ندارد.

قدم بعدی

افزایش سرعت وردپرس یک‌روزه نیست، ولی ترتیبش روشن است. اگر امروز وقت چهار کار دارید، این چهار تا:

  1. وضعیت فعلی را با curl و PageSpeed Insights ثبت کنید.
  2. نسخه‌ی PHP را به‌روز و OPcache را با مقادیر بالا تنظیم کنید.
  3. یک — و فقط یک — کش صفحه فعال کنید و با هدر پاسخ مطمئن شوید HIT می‌گیرد.
  4. اندازه‌ی autoload را بسنجید و ردیف‌های افزونه‌های حذف‌شده را بعد از بکاپ پاک کنید.

برای تمرین این کارها پیش از دست‌کاری سایت اصلی، سرور ابری ساعتی دقیقاً همین است: چند ساعت بالا می‌آید، تمرین می‌کنید و نتیجه را روی سایت اصلی می‌برید.

⚠️ سرور آزمایشی را وقتی کارتان تمام شد حذف کنید، نه فقط خاموش. سرور خاموش همچنان درصدی از نرخ ساعتی را حساب می‌کند (پیش‌فرض: نصف)، چون منابع و دیسکش رزرو مانده‌اند؛ تنها چیزی که صورت‌حساب را صفر می‌کند حذف سرور است.

سؤالات پرتکرار

سریع‌ترین راه افزایش سرعت سایت وردپرسی چیست؟

فعال‌کردن کش صفحه بیشترین بهبود را با کمترین زحمت می‌دهد. کش صفحه خروجی HTML آماده را نگه می‌دارد و درخواست‌های بعدی را بدون اجرای PHP و بدون کوئری دیتابیس جواب می‌دهد؛ همین معمولاً زمان پاسخ سرور را به چند ده میلی‌ثانیه می‌رساند. روی هاست اشتراکی یک افزونه‌ی کش کافی است، و روی سرور مجازی کش در لایه‌ی وب‌سرور سریع‌تر است.

چند افزونه برای وردپرس زیاد است؟

عدد ثابتی وجود ندارد؛ معیار درست تعداد نیست، کاری است که هر افزونه در هر درخواست انجام می‌دهد و ده افزونه‌ی تمیز از سه افزونه‌ی بدنوشته سبک‌ترند. با این حال بالای بیست افزونه‌ی فعال وقت بازنگری است: با Query Monitor ببینید کدام‌یک کندترین کوئری‌ها را دارد.

ارتقای PHP چقدر سرعت وردپرس را زیاد می‌کند؟

ارتقای PHP معمولاً چند درصد بهبود می‌دهد، نه چند برابر. در بنچمارک‌های منتشرشده، یک وردپرس استاندارد با رفتن از PHP 7.4 به 8.5 حدود ۷ درصد درخواست بیشتری در ثانیه پاسخ می‌دهد. روی ووکامرس فاصله بزرگ‌تر است و از ۴۴ به ۷۱ درخواست می‌رسد، ولی تقریباً همه‌ی این جهش مخصوص 8.5 است و نسخه‌های ۸٫۲ تا ۸٫۴ حدود ۵۳ تا ۵۵ می‌مانند. با این حال ارتقا را عقب نیندازید: نسخه‌های قدیمی دیگر وصله‌ی امنیتی نمی‌گیرند.

چرا سایت وردپرسی من برای بازدیدکننده‌ی ایرانی کند است ولی در تست‌ها سریع؟

معمولاً به دو دلیل: فاصله‌ی شبکه و وابستگی به میزبان‌های خارجی. سرور خارج از کشور برای هر درخواست هزینه‌ی ثابت رفت‌وبرگشت بین‌الملل را می‌پردازد. جدا از آن، هر فونت یا آواتاری که از دامنه‌ای بیرون از سایت بار می‌شود اتصالی تازه می‌خواهد و اگر در دسترس نباشد مرورگر تا انقضای مهلت منتظر می‌ماند.

کش آبجکت با Redis برای هر سایت وردپرسی لازم است؟

خیر. کش آبجکت وقتی ارزش دارد که سهم بزرگی از بازدیدها کش‌نشدنی باشند: فروشگاه ووکامرس، سایت عضویتی، انجمن، یا هر جایی که کاربران لاگین‌شده زیادند. برای وبلاگی که تقریباً همه‌ی صفحاتش کش صفحه می‌گیرند تفاوت محسوسی نمی‌سازد. ضمناً به سرور مجازی و نصب Redis یا Memcached نیاز دارد و روی هاست اشتراکی معمولاً در دسترس نیست. اول کش صفحه را درست کنید، بعد سراغ این بروید.

آموزش‌های مرتبط

آماده‌ی تمرین عملی هستید؟

سرور ابری ساعتی مهران هاست در ۶۰ ثانیه تحویل می‌شود — تمرین کنید و فقط بابت همان ساعت‌ها پرداخت کنید. هزینه را پیش از ثبت‌نام با محاسبه‌گر برآورد کنید.