دموی رایگان

مطالعهٔ موردی: استقرار SSR برای سایت‌های Vue

دلوین خیری مقدم خواندن ~۹ دقیقه سئو فنی
مطالعهٔ موردی: استقرار SSR برای سایت‌های Vue
استقرار SSR برای سایت‌های Vue یعنی ساختن صفحه‌ها روی سرور پیش از ارسال، تا خزنده به‌جای پوستهٔ خالی جاوااسکریپت، محتوای کامل ببیند. در کار ثبت‌شدهٔ سوئیت، فعال‌سازی رندر سمت سرور (SSR) روی همین سایتِ Vue با اینرشیا، حجم HTML صفحهٔ اصلی را از ۳٫۴ به ۷۴٫۷ کیلوبایت رساند و TTFB را از ۰٫۱۸۵ به ۰٫۱۰۷ ثانیه کوتاه کرد؛ بازهٔ اندازه‌گیری: مهر-آبان ۱۴۰۵.

سایتی که با Vue ساخته شده برای کاربر پرسرعت و روان است؛ اما همین نرمی یک هزینهٔ پنهان دارد. تا وقتی جاوااسکریپت در مرورگر اجرا نشود، خروجی سرور چیزی جز یک پوستهٔ خالی نیست و خزنده‌های موتور جستجو نخستین دیدارشان را با همین پوسته شروع می‌کنند. در این مطالعهٔ موردی، استقرار رندر سمت سرور را روی سایت خودمان مرور می‌کنیم: چرا انجام شد، چطور اجرا شد، چه اعدادی پیش و پس ثبت شد و کجاها این روش پاسخگو نیست. همهٔ اعداد از اندازه‌گیری خودمان است و بازهٔ اندازه‌گیری مشخص آمده است.

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

در اپلیکیشن‌های تک‌صفحه‌ای (SPA)، سرور یک HTML کوچک می‌فرستد که معمولاً فقط یک ریشهٔ خالی و چند تگ اسکریپت دارد. مرورگر جاوااسکریپت را دانلود و اجرا می‌کند و صفحه همان‌جا ساخته می‌شود. کاربر این تأخیر را به‌شکل «لحظهٔ سفید» می‌بیند؛ خزنده اما با یک مشکل جدی‌تر روبه‌روست: اگر جاوااسکریپت اجرا نشود، محتوایی برای دیدن وجود ندارد.

گوگل می‌تواند جاوااسکریپت را رندر کند، اما طبق مستندات Google Search Central دربارهٔ سئوی جاوااسکریپت، این رندر در موج جداگانه‌ای از خزش انجام می‌شود؛ یعنی میان «دیدن پوسته» و «دیدن محتوای کامل» فاصلهٔ زمانی می‌افتد (تاریخ گردآوری: آبان ۱۴۰۵). خزنده‌های دیگر و ربات‌های سرویس‌های هوش مصنوعی هم ضعیف‌تر از گوگل عمل می‌کنند. به تجربهٔ ما، سایت‌های SPA که محتوایشان فقط بعد از اجرای جاوااسکریپت ظاهر می‌شود، در گزارش پوشش ایندکس دیرتر و ناسازگارتر ثبت می‌شوند؛ چون هر برخورد خزنده با نسخه‌ای متفاوت از صفحه، سیگنال ناپایداری می‌سازد. راه‌حل‌های فنی این دست مسئله‌ها را در راهنمای سئو فنی پوشش داده‌ایم.

سه راه‌حل: SSR، SSG و پررندرینگ

سه راه‌حل مرسوم وجود دارد و انتخاب میان آن‌ها به نرخ تغییر محتوا بستگی دارد. رندر سمت سرور (SSR) هر درخواست را همان لحظه روی سرور کامل می‌کند؛ مناسب صفحاتی که مرتب عوض می‌شوند. تولید سایت استاتیک (SSG) صفحه‌ها را پیشاپیش می‌سازد؛ سریع‌ترین پاسخ را دارد اما هر تغییر محتوا به بازسازی نیاز دارد. پیش‌رندرینگ (Prerendering) هم خروجی استاتیک را برای خزنده‌ها می‌فرستد و نسخهٔ کلاینت را برای کاربر؛ راه‌حل میانه‌ای است که نگهداری دو نسخه را به‌دنبال دارد.

به تجربهٔ ما، برای سایتی که محتوایش هفته‌ای چند بار تغییر می‌کند، SSR منطقی‌تر از SSG است؛ چون زنجیرهٔ تولید و انتشار محتوا باید بدون بازسازی دستی کل سایت جریان داشته باشد. برای سایت‌های کم‌تغییر مثل مستندات، SSG ساده‌تر و ارزان‌تر است. تصمیم را با یک سؤال بگیرید: «محتوای این صفحه چه فاصله‌ای عوض می‌شود؟»

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

کار ثبت‌شدهٔ سوئیت: نقطهٔ شروع

سایت خودمان — ویژن‌پرایم سوئیت — با Vue و اینرشیا ساخته شده است؛ همان ترکیبی که صفحاتش قبل از استقرار SSR، سمت کلاینت رندر می‌شد. در نقطهٔ شروع، حجم HTML صفحهٔ اصلی فقط ۳٫۴ کیلوبایت بود؛ عملاً یک پوسته. خزنده برای دیدن محتوای واقعی به اجرای جاوااسکریپت وابسته بود و TTFB — زمان تا رسیدن اولین بایت — در حدود ۰٫۱۸۵ ثانیه ثبت می‌شد.

این تغییرات در یک تسک مشخص انجام شد و در بازهٔ مهر-آبان ۱۴۰۵ با ثبت رسمی اندازه‌گیری و نگهداری شد. سنجه‌ها استانداردند: حجم بایت‌های خروجی HTML صفحهٔ اصلی و زمان تا اولین بایت از پاسخ سرور. برچسب همهٔ اعداد این بخش «کار ثبت‌شدهٔ سوئیت» است؛ یعنی داخل سوئیت، با ثبت رسمی و بازهٔ مشخص، نه روایت بی‌سند.

اجرا: فعال‌سازی SSR برای سایت‌های Vue با اینرشیا

اینرشیا (Inertia) لایه‌ای است که SPA را بدون API جداگانه به بک‌اند وصل می‌کند و برای SSR مسیر مشخصی دارد. گام‌های اجرا — از تجربهٔ اجرای همین پروژه — این‌طوری جمع می‌شود:

  1. راه‌اندازی سرور رندر. ماژول سرور اینرشیا را کنار اپ فعال کنید تا درخواست‌ها به‌جای پوسته، خروجی کامل بگیرند؛ در Vue با تابع createServer.
  2. فهرست سفید مسیرها. فقط صفحات عمومی را روی SSR ببرید؛ پنل‌های احراز هویت‌شده و صفحات شخصی نیازی به رندر سمت سرور ندارند و بار اضافه می‌سازند.
  3. کش پاسخ. برای صفحات پرتقاضا، پاسخ رندرشده را در لبه یا روی سرور کش کنید تا هزینهٔ رندر تکراری نپردازید.
  4. مسیر برگشت (Fallback). اگر سرور رندر خطا داد، درخواست به نسخهٔ کلاینت برود؛ سایت قطع نشود. این شرط برای انتشار امن است.
  5. پایش بعد از انتشار. لاگ سرور و زمان پاسخ را در ساعت‌های اول پس از انتشار زیر نظر بگیرید و نرخ خطای رندر را ثبت کنید.

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

هیدریشن: نیمهٔ پنهان SSR در Vue

ارسال HTML کامل پایان ماجرا نیست؛ نیمهٔ دوم داستان، هیدریشن است. مرورگر بعد از دریافت صفحه، باندل جاوااسکریپت را بارگیری می‌کند و Vue کنترل صفحه را به‌دست می‌گیرد؛ از این لحظه تعامل‌ها مثل کلیک و فرم مثل یک اپ معمولی کار می‌کنند. تا پیش از هیدریشن، صفحه دیده می‌شود اما پاسخ‌گو نیست. به تجربهٔ ما، بخش بزرگی از باگ‌های استقرار SSR همین ناحیهٔ گذار است؛ چون خروجی سرور و خروجی کلاینت باید دقیقاً یک‌شکل باشند.

دو خطای رایج را جدی بگیرید. اول، ناهم‌خوانی هیدریشن: اگر سرور تاریخ را با منطقهٔ زمانی سرور بسازد و کلاینت با ساعت مرورگر، Vue در کنسول هشدار می‌دهد و بخشی از صفحه دوباره رندر می‌شود؛ هر چیزی که به ساعت، لوکیشن یا localStorage وابسته است را بعد از هیدریشن بچسبانید. دوم، دسترسی به window در فاز سرور: کدی که برای مرورگر نوشته شده روی سرور متوقف می‌شود؛ شرط محیط را در setup بگذارید و کد وابسته به مرورگر را به چرخهٔ عمر بعد از mount منتقل کنید. با یک صفحهٔ آزمایشی و لاگ خطای سرور، این دو خطا قبل از انتشار قابل شکارند.

نتیجه: HTML و TTFB قبل و بعد

سنجهپیش از SSRپس از SSRتغییر
حجم HTML صفحهٔ اصلی۳٫۴ کیلوبایت۷۴٫۷ کیلوبایترسیدن نشانه‌گذاری کامل به‌جای پوسته
TTFB صفحهٔ اصلی۰٫۱۸۵ ثانیه۰٫۱۰۷ ثانیهکاهش حدود ۴۲٪
بازهٔ اندازه‌گیریبازهٔ مهر-آبان ۱۴۰۵ — کار ثبت‌شدهٔ سوئیت

دو سنجه، دو معنا دارند. حجم HTML بالاتر این‌جا خبر خوب است؛ یعنی محتوای کامل در پاسخ اولیه است، نه پوسته. و TTFB زیر ۲۰۰ میلی‌ثانیه، طبق توصیهٔ مستندات web.dev گوگل برای سنجهٔ TTFB در منطقهٔ «خوب» است (تاریخ گردآوری: آبان ۱۴۰۵). هر دو عدد را با برچسب «کار ثبت‌شدهٔ سوئیت» و در بازهٔ همان تسک ببینید. الگوی ثبت اعداد در اجراهای دیگر هم در مطالعات موردی و شواهد آمده است.

مسیر تسک استقرار SSR
کل استقرار در یک تسک ثبت‌شده انجام و اندازه‌گیری شد.

تفسیر صادقانه: چرا HTML بزرگ‌تر شد اما بهتر است؟

روی کاغذ عجیب است: سروری که خودش صفحه را رندر می‌کند، باید کندتر شود؛ چون کار بیشتری انجام می‌دهد. در این کیس برعکس شد و TTFB کمتر شد. توضیح ما این است: نسخهٔ ۳٫۴ کیلوبایتی همان پوستهٔ کلاینت‌رندر بود و مسیر پاسخ، انتقال وزن سنگین جاوااسکریپت و اجرای آن را به زمان درک محتوا جابه‌جا می‌کرد؛ در نسخهٔ SSR، پاسخ کامل اما بهینه‌شده از مسیر کش و سرور تنظیم‌شده می‌آید. TTFB فقط «اولین بایت» را می‌سنجد، نه کل زمان دیدن محتوا؛ پس دو نسخه را با این سنجه مقایسه کنید، نه با سرعت درک صفحه.

این تفسیر را به هر زیرساختی تعمیم نکنید. بدون کش درست و سرور مناسب، SSR می‌تواند TTFB را بدتر هم کند؛ عدد ما نتیجهٔ یک اجرای مشخص است، نه قانون فیزیک.

محدودیت‌های این کیس

چهار محدودیت را صادقانه بنویسیم. اول، اندازه‌گیری روی صفحهٔ اصلی انجام شد؛ صفحات دیگر — مثل مقاله‌های مجله یا صفحات محصول — می‌توانند رفتار متفاوتی داشته باشند. دوم، بازهٔ اندازه‌گیری یک تسک مشخص است؛ نوسان‌های ترافیک و شبکه در بازه‌های دیگر می‌توانند اعداد را جابه‌جا کنند. سوم، اندازه‌گیری داخلی است و توسط تیم خودمان ثبت شده؛ با معیارهای آزمایشگاهی مستقل، ممکن است اعداد کمی متفاوت بیرون بیاید. چهارم، جزئیات زیرساختی — تنظیم کش و منابع سرور — در این مقاله تفکیک نشده و همان‌ها بخشی از نتیجه‌اند.

این محدودیت‌ها اعتبار روش را زیر سؤال نمی‌برد؛ فقط مرز ادعا را می‌کشد: آن‌چه ثبت شد، یک استقرار موفق با دو سنجهٔ استاندارد است، نه یک مطالعهٔ آماری روی چند سایت.

بعد از SSR: زنجیرهٔ رصد تا انتشار

SSR شرط لازم است، اما کافی نیست؛ بعد از آن باید بدانید چه محتوایی بسازید و چطور منتشر کنید. چرخهٔ سوئیت همین را می‌بندد: رصد ← فرصت‌های شماره‌دار ← تولید و انتشار با خط کیفیت ۳۱ گایته ← گزارش هفتگی؛ همه در یک پنل. در پلن پیشرو، انتشار خودکار محتوای تأییدشده و پایش مستمر اپراتور هم به همین زنجیره اضافه می‌شود؛ یعنی صفحه‌های رندرشده سمت سرور، هر هفته با محتوای تازه تغذیه می‌شوند و رصدشان از دست‌تان خارج نمی‌شود.

برای سایت‌های Vue که می‌خواهند همین مسیر را بی‌درز بروند، نقطهٔ شروع ساده است: یک دمو بگیرید و در قابلیت‌های ویژن‌پرایم سوئیت ببینید رصد و فرصت‌یابی و انتشار چطور کنار هم می‌نشینند.

جمع‌بندی اقدام‌محور

سه کار همین امروز جلوی شماست. اول: سورس صفحهٔ اصلی سایت‌تان را بدون اجرای جاوااسکریپت ببینید؛ اگر فقط پوسته است، مسئله را دارید. دوم: TTFB را اندازه بگیرید و با آستانهٔ ۲۰۰ میلی‌ثانیه مقایسه کنید؛ اگر مبنای ممیزی می‌خواهید، ممیزی ده‌صفحه‌ای دامنه نقطهٔ شروع است. سوم: اگر تصمیم گرفتید، SSR را فقط برای مسیرهای عمومی فعال کنید، کش و مسیر برگشت را قبل از انتشار ببندید و اعداد قبل و بعد را در یک بازهٔ ثبت‌شده نگه دارید؛ همین الگو در کار ثبت‌شدهٔ سوئیت، HTML را از ۳٫۴ به ۷۴٫۷ کیلوبایت رساند و TTFB را از ۰٫۱۸۵ به ۰٫۱۰۷ ثانیه کوتاه کرد. زنجیرهٔ کامل رصد تا انتشار هم در یک پنل آماده است؛ با دموی رایگان پلتفرم ببینید.

دموی رایگان پلتفرم

پلن پیشرو — ۷٫۹ میلیون تومان/ماه (انتشار خودکار + اپراتور)

دموی رایگان پلتفرم

رصد ما، رشد شما.

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

SSR برای سایت‌های Vue در چه حالتی لازم است؟

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

آیا SSR سرعت سایت را کند نمی‌کند؟

هزینهٔ رندر به سرور منتقل می‌شود؛ با کش درست برای صفحات پرتقاضا، TTFB می‌تواند حتی بهتر هم شود — در کار ثبت‌شدهٔ سوئیت از ۰٫۱۸۵ به ۰٫۱۰۷ ثانیه رسید. بدون کش، می‌تواند بدتر هم شود.

تفاوت SSR با پیش‌رندرینگ چیست؟

پیش‌رندر خروجی استاتیک ثابت برای خزنده می‌فرستد؛ SSR صفحه را در هر درخواست کامل می‌کند. برای محتوای متغیر، SSR نگهداری‌پذیرتر است.

ایمرشیا هم SSR دارد؟

بله؛ اینرشیا مسیر رسمی SSR دارد و با یک سرور رندر کنار اپ کار می‌کند. همان مسیری که در این کیس اجرا شد.

این اعداد برای سایت ما تکرار می‌شود؟

قابل قول نیست. اعداد مال یک استقرار مشخص با زیرساخت خود سوئیت است؛ برای سایت شما باید قبل و بعد را در بازهٔ ثبت‌شده اندازه گرفت.