سرعت سایت را چطور اندازه بگیریم و چه چیزی کندش می کند

یاسین
1405/7/5
13 دقیقه
126 بازدید
سرعت سایت را چطور اندازه بگیریم و چه چیزی کندش می کند

پاسخ کوتاه: سرعت سایت یک عدد نیست، شش عدد است. زمان حل نام دامنه (DNS)، زمان اتصال TCP، زمان دست دادن TLS، زمان اولین بایت یا TTFB، حجم واقعی انتقال و زمان رندر شدن صفحه. اگر این شش عدد را جدا اندازه بگیری، در چند دقیقه می فهمی گلوگاه روی شبکه است، روی سرور، روی تصاویر یا روی کد و اسکریپت. برای گرفتن پنج عدد اول فقط یک دستور curl لازم است. در اندازه گیری امروز روی سایت خودمان، DNS حدود ۵ میلی ثانیه، اتصال TCP حدود ۸۵ میلی ثانیه، دست دادن TLS حدود ۹۰ میلی ثانیه و TTFB بین ۰٫۶۴ تا ۰٫۷۳ ثانیه بود؛ یعنی مسیر شبکه سالم است و اگر کندی وجود داشته باشد از سمت سرور و پردازش می آید نه از اینترنت کاربر.

هر راهنمای فارسی سرعت سایت تو را به یک ابزار آنلاین می فرستد که در پایان یک نمره از ۱۰۰ می دهد. آن نمره نقطه شروع بدی نیست، ولی یک چیز را نمی گوید: گلوگاه کجاست. نمره ۶۰ می تواند از یک عکس چهار مگابایتی باشد، می تواند از هاست ضعیف باشد، و می تواند از یک اسکریپت چت آنلاین باشد که سرورش از ایران کند جواب می دهد. سه راهکار کاملا متفاوت، یک نمره یکسان. به همین دلیل اول باید اندازه گیری کرد و بعد تصمیم گرفت.

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

سرعت سایت در کدام لایه اندازه گیری می شود؟

درخواست یک کاربر، شش مرحله پشت سر هم است. هر مرحله یک عدد جدا دارد و هر عدد به یک علت متفاوت اشاره می کند:

لایهچه چیزی را می سنجدعدد امروز سایت مااگر بد باشد، مقصر کجاست
حل نام دامنه (DNS)تبدیل دامنه به آی پی۵ تا ۱۱ میلی ثانیهسرور DNS یا رکوردهای اضافه
اتصال TCPراه افتادن ارتباط با سرور۸۵ تا ۹۶ میلی ثانیهفاصله جغرافیایی سرور از کاربر
دست دادن TLSرمزنگاری HTTPSحدود ۹۰ میلی ثانیهتنظیمات سرور، ریدایرکت های اضافه
اولین بایت (TTFB)پردازش درخواست در سرور۰٫۶۴ تا ۰٫۷۳ ثانیههاست، دیتابیس، کد بدون کش
انتقال محتوادانلود HTML، تصویر و فونت۱۸۱ کیلوبایت HTMLتصویر و فایل بهینه نشده
رندر شدننقاشی صفحه در مرورگراندازه گیری با Chromeجاوااسکریپت و CSS سنگین

نکته کلیدی همین جدول است: پنج لایه اول را با خط فرمان می سنجی و کسی هم نمی تواند به تو بگوید «نمی شود اندازه گرفت». فقط لایه آخر نیاز به مرورگر دارد، چون رندر شدن به دستگاه و اینترنت کاربر بستگی دارد.

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

با یک دستور curl، پنج عدد سرعت سایت را بگیر

curl یک قالب خروجی به نام format دارد که هر عدد را جدا چاپ می کند. این دستور را عینا در ترمینال (یا در پنل هاست) اجرا کن و آدرس را با دامنه خودت عوض کن:

curl -s -o /dev/null -A "Mozilla/5.0" \
  -w "DNS=%{time_namelookup} اتصال=%{time_connect} TLS=%{time_appconnect} \
اولین بایت=%{time_starttransfer} کل=%{time_total} بایت=%{size_download} کد=%{http_code} http=%{http_version}\n" \
  https://example.com/

خروجی واقعی همین دستور روی یکی از مقالات سایت ما، در سه درخواست پشت سر هم با فاصله چند ثانیه:

1: DNS=0.010659 اتصال=0.096139 TLS=0.187507 اولین بایت=0.728062 کل=0.928504 بایت=181571 کد=200 http=2
2: DNS=0.005083 اتصال=0.084666 TLS=0.173760 اولین بایت=0.637273 کل=0.791156 بایت=181544 کد=200 http=2
3: DNS=0.009335 اتصال=0.088952 TLS=0.177856 اولین بایت=0.671072 کل=0.823818 بایت=181496 کد=200 http=2

سه چیز را از همین سه خط بخوان. اول، TTFB حدود ۰٫۶۴ تا ۰٫۷۳ ثانیه است: از کل زمان، هفتاد درصدش صرف پردازش درخواست در سرور می شود، نه دانلود. دوم، اعداد اتصال و TLS در هر سه خط یکی است چون مسیر شبکه ثابت است. سوم، تعداد بایت ۱۸۱ کیلوبایت است و کل زمان زیر یک ثانیه می ماند.

اگر در اجرای دوم عدد اتصال و TLS را صفر دیدی، هیچ اشکالی ندارد: یعنی curl همان ارتباط قبلی را دوباره استفاده کرده (keep-alive) و فقط TTFB و دانلود را اندازه گرفته است. برای عدد دقیق، همان درخواست را با فاصله حداقل سه چهار ثانیه سه بار بزن؛ نه بیست بار پشت سر هم.

سه دستور دیگر که هر کدام یک لایه را جدا می سنجند:

# حجم واقعی انتقال با فشار دادن پاسخ از gzip: اگر نزدیک حجم خام شد، gzip کار نمی کند
curl -s -H "Accept-Encoding: gzip" https://example.com/ | wc -c

# هدرهای فشرده سازی و کش را ببین
curl -sI -H "Accept-Encoding: gzip" https://example.com/ | grep -iE "content-encoding|cache-control|content-length|vary"

# زمان پاسخ سرور نام دامنه
dig example.com | grep -i "Query time"

خروجی همین دستورها روی صفحه اصلی سایت ما: هدر content-encoding: gzip فعال است، هدر cache-control مقدار no-cache, private دارد و نسخه پروتکل HTTP/2 است. HTML صفحه اصلی ۱۷۱٬۹۷۷ بایت است و با gzip به ۲۸٬۱۹۶ بایت می رسد؛ یعنی ۸۴ درصد کمتر. صفحه خدمات ۱۱۵٬۶۱۴ بایت بود و به ۲۸٬۶۷۶ بایت رسید (۷۵ درصد کمتر). همین یک هدر، حجمی که کاربر روی موبایل دانلود می کند را به یک پنجم کاهش می دهد.

چه عددی نرمال است؟ جدول آستانه ها

بدون یک خط کش، اندازه گیری به هیچ تصمیمی نمی رسد. این آستانه ها مرجع بیرونی دارند و امروز واکشی شده اند:

شاخصمقدار قابل قبولمعنایشمنبع
TTFB۰٫۸ ثانیه یا کمترسرور سریع پاسخ می دهدweb.dev/articles/ttfb
LCPزیر ۲٫۵ ثانیهبزرگ ترین عنصر صفحه ظاهر شده استweb.dev/articles/vitals
INPزیر ۲۰۰ میلی ثانیهصفحه به کلیک و لمس پاسخ می دهدweb.dev/articles/vitals
CLSزیر ۰٫۱عناصر صفحه جابه جا نمی شوندweb.dev/articles/vitals
حجم HTML فشردهزیر ۱۰۰ کیلوبایتصفحه سبک شروع می شوداندازه گیری ما، ۲۸ تا ۴۱ کیلوبایت
هر تصویر درون متنزیر ۱۲۰ کیلوبایتتصویر WebP و در اندازه نمایشاندازه گیری ما، ۵۴ تا ۱۰۷ کیلوبایت

سه عدد اول را گوگل تجربه صفحه نامیده و اعلام کرده که در رتبه بندی دخالت دارد؛ ولی خودش هم گفته محتوای مرتبط مهم تر است. پس تصور نکن سرعت ضعیف همه چیز را خراب می کند یا سرعت کامل همه چیز را حل می کند. سرعت یک شرط لازم است، نه کافی.

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

کندی سایت از کدام لایه می آید؟ نقشه عیب یابی

حالا که شش عدد را داری، تشخیص یک کار مکانیکی است. هر الگوی عددی به یک علت مشخص اشاره می کند:

الگوی عددیگلوگاهاولین کاری که باید کرد
DNS بالای ۲۰۰ میلی ثانیهسرور نام دامنهسرور DNS سریع تر یا کاهش رکوردهای اضافه
اتصال TCP بالای ۳۰۰ میلی ثانیهفاصله سرور از کاربرهاست نزدیک تر یا شبکه توزیع محتوا
TTFB بالای ۰٫۸ ثانیه ولی دانلود کمسرور، دیتابیس یا کدکش، ایندکس دیتابیس، بهینه سازی کوئری
TTFB کم ولی کل زمان زیادتصویر، فونت و اسکریپتفشرده سازی تصویر، کاهش فونت، بارگذاری تاخیری
حجم HTML بالا با gzip کمفشرده سازی خاموشروشن کردن gzip یا brotli روی وب سرور
دانلود سریع ولی صفحه دیر ظاهر می شودرندر و جاوااسکریپتحذف اسکریپت غیرضروری، تقسیم کد

۱) لایه سرور: TTFB بالا، دانلود کم

اگر TTFB بالای ۰٫۸ ثانیه است و حجم صفحه کوچک، مشکل در پردازش است. سه کار را به ترتیب انجام بده. اول کش: صفحه ای که هر بار از صفر ساخته می شود، هر بار هزینه پردازش می دهد. دوم دیتابیس: کوئری بدون ایندکس روی جدولی با صد هزار ردیف، به تنهایی یک ثانیه می خورد. سوم سطح منابع هاست؛ در هاست اشتراکی، ورودی همزمان و آی نود دو سقف پنهان هستند که کندی را در ساعت پیک می سازند. راهنمای انتخاب هاست و انواع میزبانی را جداگانه نوشته ایم و لازم نیست دوباره کشف شود. جزئیات سقف های پنهان هاست اشتراکی (ورودی همزمان، آی نود و حافظه) همان جاست.

-- کوئری مشکوک را با EXPLAIN ببین: اگر type برابر ALL بود، اسکن کامل جدول است
EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'paid';

-- ایندکس ترکیبی روی همان دو ستون، هزینه اسکن کامل را حذف می کند
CREATE INDEX idx_orders_user_status ON orders (user_id, status);

روی سرور لینوکس، سه دستور زیر نشان می دهد منابع تمام شده اند یا نه. اگر حافظه به صد درصد نزدیک باشد، سرور شروع به استفاده از فضای مبادله روی دیسک می کند و همان لحظه کندی عمومی پیدا می شود:

uptime                 # بار سرور؛ اگر از تعداد هسته ها بیشتر بود، سرور اشباع است
free -m                # حافظه آزاد؛ اگر swap پر شده، دیسک جای رم کار می کند
ps -eo pid,pcpu,pmem,comm --sort=-pcpu | head -6   # پنج پردازش پرمصرف

۲) لایه محتوا: TTFB سالم، ولی صفحه سنگین

اگر TTFB زیر ۰٫۸ ثانیه است ولی صفحه روی موبایل دیر می آید، مقصر تقریبا همیشه تصویر است. وزن واقعی تصاویر یک مقاله از سایت ما، با GET اندازه گیری شد: سه تصویر درون متن ۵۸، ۷۳ و ۵۴ کیلوبایت و کاور ۵۴ کیلوبایت. یک مقاله قدیمی تر چهار تصویر داشت که مجموعشان ۳۳۶ کیلوبایت شد. اگر همان تصاویر JPEG با کیفیت بالا بودند، همان صفحه چند برابر می شد. این دستور وزن تصاویر یک صفحه را جمع می زند:

for img in $(curl -s https://example.com/blog/post/ | grep -oE 'src="[^"]+\.(webp|jpg|jpeg|png)"' | cut -d'"' -f2); do
  curl -sL -o /dev/null -w "%{size_download} $img\n" "$img"
done | awk '{s+=$1; print} END {print "مجموع بایت:", s}'

سه قاعده تصویر: اندازه خروجی را به اندازه جایی که نمایش داده می شود کوچک کن، فرمت را WebP یا AVIF بردار، و تصویرهای پایین صفحه را با بارگذاری تاخیری لود کن. تصویر بالای صفحه را تاخیر نده، چون همان تصویر معمولا LCP است.

۳) لایه کد: دانلود سریع، رندر کند

وقتی دانلود تمام شده ولی کاربر هنوز صفحه سفید می بیند، مسئله اجرای جاوااسکریپت است. هر اسکریپت خارجی (چت آنلاین، ابزار آمارگیری، ابزار تبلیغات) یک درخواست به سرور دیگری است و اگر آن سرور کند جواب دهد، صفحه معطل می ماند. این اسکریپت ها را با تاخیر و غیر همزمان بارگذاری کن و بعد از هر تغییر، فرم، منو و سبد خرید را آزمایش کن:

<script src="/assets/app.js" defer></script>
<script src="/assets/chat.js" async></script>
دو دفتر یادداشت کنار هم روی میز چوبی برای مقایسه قبل و بعد
دو دفتر کنار هم: یک صفحه سنگین و یک صفحه سبک. بدون عدد قبل و بعد هیچ بهینه سازی اثبات نمی شود.

یک نمونه واقعی: اندازه گیری روی سایت خودمان

عدد حرف آخر را وقتی می زند که قبل و بعدش را داشته باشی. سه اندازه گیری از پروژه هایی که خودمان ساختیم:

کار انجام شدهقبلبعد
تبدیل پنج تصویر JPEG به WebP در یک مقاله۲٬۳۷۱ کیلوبایت تصویر۱۸۱ کیلوبایت تصویر
همان مقاله، وزن کل صفحه و زمان بارگذاری۷٬۲۳۴ کیلوبایت، ۲٫۴۹ ثانیه۵٬۱۲۲ کیلوبایت، ۱٫۴۲ ثانیه
فشرده سازی HTML یک مقاله۱۷۴٬۴۶۷ بایت۴۰٬۹۷۵ بایت با gzip

سه تصویر سنگین صفحه اصلی هم به WebP تبدیل شد و وزن تصاویرش از ۵٬۲۳۸ کیلوبایت به ۶۴۳ کیلوبایت رسید. تامبنیل مقالات مرتبط از مسیر ویژه ای سرو می شود و هر کدام ۷٫۵ تا ۱۱٫۳ کیلوبایت است؛ قبلا کاور کامل هر مقاله با ۶۳۵ تا ۸۹۳ کیلوبایت در قالب یک تصویر کوچک بار می شد. این دقیقا همان الگوی رایج است: بزرگ ترین برد از جایی می آید که انتظارش را نداری.

سه اشتباهی که نتیجه تست سرعت را بی اعتبار می کند

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

for i in 1 2 3; do
  curl -s -o /dev/null -w "اجرا $i: اولین بایت=%{time_starttransfer} کل=%{time_total} کد=%{http_code}\n" \
    -A "Mozilla/5.0" https://example.com/
  sleep 5
done

اشتباه دوم: اندازه گیری وقتی خودت وارد پنل هستی. صفحه ای که برای کاربر وارد شده ساخته می شود کش شدنی نیست. روی سایت ما هدر cache-control: no-cache, private است، یعنی مرورگر نسخه ای را نگه نمی دارد. پس همیشه یک پنجره ناشناس باز کن و از همان جا تست بگیر، وگرنه عددی می بینی که کاربر واقعی هیچ وقت نمی بیند.

اشتباه سوم: مقایسه دو صفحه متفاوت. عدد سرعت یک صفحه، عدد کل سایت نیست. صفحه اصلی ما ۱۷۱٬۹۷۷ بایت با TTFB بین ۰٫۶۸ تا ۰٫۸۸ ثانیه بود، ولی صفحه خدمات ۱۱۵٬۶۱۴ بایت با TTFB بین ۱٫۰۰ تا ۱٫۳۷ ثانیه. حجم کمتر، پردازش بیشتر: صفحه خدمات جدول و پرسش و اسکیمای بیشتری می سازد. اگر این دو را با هم مقایسه کنی، نتیجه گیری غلط می شود.

کدام عدد را گوگل می بیند؟

سه شاخص LCP و INP و CLS را گوگل زیر نام Core Web Vitals جمع کرده و در گزارش تجربه صفحه سرچ کنسول نشان می دهد. در همین گزارش دو نوع داده وجود دارد و اشتباه گرفتنشان گیج کننده است: داده میدانی که از تجربه واقعی کاربران مرورگر کروم می آید، و داده آزمایشگاهی که همان لحظه روی یک دستگاه شبیه سازی شده تولید می شود. اگر سایت ترافیک کمی داشته باشد، بخش میدانی خالی می ماند و باید به داده آزمایشگاهی تکیه کنی. یعنی برای سایت تازه، عدد تلفن همراه خودت هنوز معتبرترین چیزی است که در اختیار داری.

یک نکته درباره ضریب اهمیت: سرعت یکی از شرط های تجربه کاربر است، نه کل ماجرا. صفحه ای کند که دقیقا به پرسش کاربر جواب می دهد، از صفحه سریعی که جواب نمی دهد جلوتر است. پس سرعت را درست کن، ولی آن را جانشین محتوا نکن.

پیش از سفارش سایت، چه چیزی درباره سرعت در قرارداد بیاید؟

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

  • سه صفحه مشخص و یک عدد هدف. مثلا صفحه اصلی، یک صفحه خدمات و یک صفحه مقاله؛ TTFB زیر ۰٫۸ ثانیه و LCP موبایل زیر ۲٫۵ ثانیه، اندازه گیری شده روی داده آزمایشگاهی.
  • بودجه تصویر. هر تصویر درون متن زیر ۱۲۰ کیلوبایت و در فرمت WebP؛ تصویر بالای صفحه تاخیر نداشته باشد.
  • فشرده سازی و کش روشن. gzip یا brotli فعال باشد و هدر کش برای فایل های ثابت تنظیم شده باشد. این دو، همان جایی هستند که در صفحه اصلی ما ۸۴ درصد از حجم HTML کم کردند.
  • گزارش قبل و بعد. یک صفحه گزارش با اعداد اندازه گیری شده در روز تحویل، نه وعده های کلی. هزینه طراحی سایت در ایران بیشتر از همه به دامنه کار و کیفیت اجرا برمی گردد و همین گزارش، تفاوت کیفیت اجرا را نشان می دهد.

روی سرور، همان دو تنظیم فشرده سازی معمولا در چند خط انجام می شود:

gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/html text/css application/javascript application/json image/svg+xml;
# اگر ماژول brotli نصب است، این خط هم اضافه می شود
brotli on;

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

جمع بندی: چک لیست هفت مرحله ای

  1. DNS را بسنج؛ بالای ۲۰۰ میلی ثانیه یعنی سرور نام دامنه باید عوض شود.
  2. اتصال و TLS را بسنج؛ بالای ۳۰۰ میلی ثانیه یعنی سرور از کاربر دور است.
  3. TTFB را با سه درخواست و با فاصله اندازه بگیر؛ بالای ۰٫۸ ثانیه یعنی مشکل پردازش است.
  4. حجم فشرده HTML را ببین؛ بالای ۱۰۰ کیلوبایت یعنی gzip یا brotli خاموش است.
  5. وزن تصاویر را با GET جمع بزن؛ هر تصویر بالای ۱۲۰ کیلوبایت یک برد آماده است.
  6. سه شاخص LCP و INP و CLS را با داده آزمایشگاهی بگیر و با آستانه ها مقایسه کن.
  7. هر تغییر را با همان روش قبلی دوباره بسنج؛ بدون عدد قبل و بعد، هیچ بهبودی اثبات نمی شود.

اگر همین حالا در حال انتخاب مجری هستی، این چهار بند را می توانی در قالب یک بند قرارداد با هر کسی که طراحی سایت در شیراز را به تو پیشنهاد می دهد بنویسی؛ اجرای هر بند قابل اندازه گیری است و سرعت سایت را از حالت وعده بیرون می آورد.

نتیجه عملی این هفت مرحله ساده است: سرعت سایت را می شود با چند دستور خط فرمان سنجید و گلوگاه را دقیق پیدا کرد. هر عددی که در این راهنما دیدی از اندازه گیری زنده روی سایت خودمان و منابع رسمی آمده؛ همان روش را روی سایت خودت اجرا کن و نتیجه را با قبل مقایسه کن.

اشتراک‌گذاری مقاله:

سوالات متداول

نظرات کاربران

ارسال نظر جدید

حداقل ۱۰ و حداکثر ۱۰۰۰ کاراکتر

هنوز نظری ثبت نشده است

اولین نفری باشید که دیدگاه خود را می‌نویسد!

مطالب مرتبط

مقالات مشابه که ممکن است برایتان جالب باشد