صفحه محصول با SSG در ۳۰۰ میلیثانیه باز میشود، اما قیمت یک ساعت عقب است. تیم آن را SSR میکند؛ قیمت تازه میشود، ولی در کمپین شبانه API موجودی کند و همه صفحهها ۵۰۳ میشوند. سؤال درست «SSR سریعتر است یا SSG؟» نیست؛ سؤال این است که هر بخش صفحه چه مقدار تازگی، شخصیسازی، تابآوری و هزینه میخواهد.
SSR و SSG زمان و محل تولید HTML را تعیین میکنند، نه کیفیت محصول را. هر دو میتوانند سریع یا کند، امن یا آسیبپذیر، قابلایندکس یا معیوب باشند. تصمیم خوب باید برای هر Route و Dataset جداگانه نوشته، با Cache و Invalidation کامل و در شبکه و دستگاه واقعی آزموده شود.
SSR و SSG دقیقاً چه تفاوتی دارند؟
در SSR، HTML معمولاً هنگام درخواست یا روی Server/Edge تولید میشود. در SSG یا Prerendering، HTML پیش از درخواست—در Build یا مرحله تولید—ساخته و بهصورت Artifact منتشر میشود. با Cache و Revalidation، مرز این دو کمتر از گذشته مطلق است.
| روش | زمان تولید HTML | داده در پاسخ اولیه | نقطه شکست غالب |
|---|---|---|---|
| SSG/Prerender | Build یا پیشتولید | Snapshot هنگام تولید | Build، Invalidation یا داده کهنه |
| SSR | هر Request یا Cache miss | Snapshot زمان درخواست | Origin/API/compute latency و overload |
| CSR | مرورگر | Shell و سپس API | Bundle، دستگاه، شبکه و API Client |
| Revalidated static | Build/درخواست/رویداد | آخرین Artifact معتبر | Stale window یا regeneration failure |
| Hybrid/Partial | ترکیبی در یک Route | Shell پایدار + بخش پویا | Cache boundary، Hydration و consistency |
«Static» به معنی بدون JavaScript نیست و «Server-rendered» هم به معنی بدون Cache نیست. هر دو ممکن است Hydrate شوند و تعامل Client داشته باشند.
Rendering mode را با Hosting mode یکی نگیرید
Edge rendering محل اجرای Server logic را نزدیکتر میکند؛ یک Rendering mode مستقل نیست. فایل Static نیز ممکن است از CDN بیاید و SSR میتواند پشت CDN Cache شود. همچنین Server Components، Streaming، Islands و Partial prerendering مرز تولید و تعامل را ریزتر میکنند.
- Render: HTML کجا و چه زمانی ساخته میشود؟
- Cache: چه Artifact/Dataی با چه Key و مدتی نگه داشته میشود؟
- Deploy: کد یا فایل در Origin، Serverless یا Edge اجرا/توزیع میشود؟
- Hydrate: چه مقدار JavaScript برای تعامل به مرورگر میرسد؟
این چهار تصمیم به هم مرتبطاند، اما معادل نیستند. Nuxt نیز Edge-side rendering را بیشتر Deployment target میداند و Route rules را برای Hybrid rendering عرضه میکند؛ نام قابلیتها میان Frameworkها و نسخهها فرق دارد.
تصمیم را برای Route بنویسید، نه برای کل پروژه
یک سایت واحد میتواند خانه Static، صفحه خبر Revalidated، محصول Hybrid، Checkout SSR و Dashboard خصوصی CSR داشته باشد. Route Contract پیشنهادی:
Route: /product/:slug Audience/Search: public + indexable Data: description, price, stock, seller, reviews Freshness: description 24h; price 5m; stock at checkout real-time Personalization: city/shipping after user context Initial HTML: identity, description, honest price state, links Cache key: locale + currency; NOT user id Invalidation: CMS event + price event + manual purge Failure: last-known description; fail-closed purchase if stock unknown SLO: TTFB/LCP/error/staleness/checkout correctness Render: static shell + revalidated product + dynamic checkout Owner/Rollback: Catalog Platform / prior artifact
اگر Contract فقط «Next.js با ISR» نوشته باشد، تصمیم معماری هنوز ناقص است.
Freshness budget: داده چقدر میتواند کهنه باشد؟
«پویا» واژه دقیقی نیست. قیمت میتواند پنج دقیقه Stale باشد، موجودی هنگام خرید نباید حدس زده شود و توضیح محصول شاید یک روز تحمل داشته باشد. برای هر Field بنویسید:
| داده | Staleness مجاز | هنگام اختلال | منبع حقیقت |
|---|---|---|---|
| مقاله | ساعت/روز | آخرین نسخه معتبر | CMS version |
| قیمت نمایشی | طبق سیاست کسبوکار | زمان بهروزرسانی یا unavailable | Pricing service |
| موجودی خرید | نزدیک Real-time | Fail closed در Commit | Inventory reservation |
| وضعیت سفارش | کوتاه | Retry/last event با هشدار | Order system |
| پروفایل شخصی | Session/context | Login/fallback امن | Identity/Profile |
Render mode از سختگیرانهترین Field لزوماً تعیین نمیشود. میتوانید بخش پایدار را Cache و Validation حیاتی را در Action نهایی انجام دهید.
SSG فقط Build-time کامل نیست
الگوهای Static مدرن چند شکل دارند:
- Full build: همه Routeها پیش از Deploy تولید میشوند.
- Popular prebuild: صفحههای پرترافیک ساخته و Long tail هنگام اولین درخواست تولید میشود.
- Time-based revalidation: پس از بازه، نسخه تازه تولید میشود.
- Event/on-demand invalidation: تغییر CMS/Product، Cache مربوط را نامعتبر میکند.
- Stale-while-revalidate: نسخه کهنه مجاز سریع سرو و Refresh در پسزمینه انجام میشود.
Next.js ISR و Route rules در Nuxt نمونههای Framework-specific این خانوادهاند. معنای دقیق Cache، درخواست اول، Background regeneration و Adapter/Platform را از مستند همان نسخه/میزبانی بخوانید؛ «ISR» یک رفتار جهانی یکسان نیست.
Cache بدون Key و Invalidation، طراحی نیست
سرعت SSG و SSR cached از Cache میآید. قرارداد Cache حداقل این موارد را دارد:
Artifact: product HTML + payload Key: route × locale × currency × approved variant Source versions: CMS#1842 + Price#991 + Catalog#551 Freshness: fresh 5m; stale-if-error 30m for non-transactional view Invalidation: product.updated, price.changed, publish.rollback Purge scope: exact route + category/card dependencies Personal data: forbidden in shared cache Observability: hit/miss/age/version/regeneration/error Recovery: serve prior safe artifact or explicit unavailable
TTL تنها پاسخ نیست. تغییر محصول ممکن است صفحه دسته، جستجو، Sitemap، Related card و Schema را نیز تحتتأثیر قرار دهد. برای Cache key، Header و Service Worker، راهنمای جامع Cache وب را ببینید.
Invalidation را از Event تا Evidence طراحی کنید
رویداد product.updated باید Idempotent، Versioned و قابلتکرار باشد. مسیر ساده:
- Source of truth تغییر را Commit میکند.
- Event قابلاعتماد با Entity/version منتشر میشود.
- Dependency map، Route/Fragmentهای متأثر را پیدا میکند.
- Cache tag/Artifact نامعتبر و Regeneration اجرا میشود.
- نسخه عمومی با Marker/Checksum تأیید میشود.
- Lag، Failure و Dead-letter Alert میگیرند.
اگر Event از دست برود، TTL/periodic reconciliation باید راه ترمیم داشته باشد. الگوهای Outbox، Idempotency و DLQ در معماری Event-driven توضیح داده شدهاند.
Snapshot consistency: صفحه سریع اما متناقض نباشد
Build ممکن است عنوان را از CMS نسخه جدید و قیمت را از Catalog نسخه قدیم بگیرد. SSR هم در چند درخواست موازی دچار همین مسئله میشود. Data contract باید Version یا Timestamp منابع، timeout، Retry و سازگاری را ثبت کند.
| خطر | نمونه | کنترل |
|---|---|---|
| Mixed snapshot | Variant حذفشده با قیمت جدید | version pin/snapshot token |
| Partial build | صفحه جدید بدون دسته | atomic publish/manifest |
| Out-of-order event | نسخه قدیمی آخر اعمال شود | monotonic version/idempotency |
| Schema drift | UI و JSON-LD قیمت متفاوت | single render data model |
«HTML ساخته شد» Acceptance نیست؛ Business invariants باید پاس شوند.
Performance: TTFB، LCP و INP را جدا ببینید
SSG معمولاً TTFB پایینی میدهد، ولی Image بزرگ، Font، JavaScript و Third-party هنوز LCP/INP/CLS را خراب میکنند. SSR میتواند HTML را سریع Stream کند، اما Data waterfall یا Cold start TTFB را بالا ببرد. Hydration نیز صفحه قابلمشاهدهای میسازد که هنوز به Interaction پاسخ نمیدهد.
| مرحله | SSG risk | SSR risk | شاهد |
|---|---|---|---|
| Server/Edge | Cache miss/regeneration | compute/API/cold start | server timing, trace |
| Network | Payload/asset بزرگ | HTML stream/asset بزرگ | waterfall, transfer |
| Render | Hero/Font/CLS | stream order/late CSS | LCP/CLS attribution |
| Interact | Hydration/third-party | Hydration/duplicate work | INP/long task/RUM |
web.dev هشدار میدهد Full hydration میتواند با وجود FCP بهتر، TBT و INP را بدتر کند. نتیجه را با Field data و دستگاه میانرده بسنجید؛ راهنمای Core Web Vitals و RUM مرز Lab و Field را روشن میکند.
SSR برای Dashboard شخصی الزام سئو نیست
صفحه خصوصی که نباید Index شود، صرفاً برای SEO به SSR نیاز ندارد. SSR ممکن است برای First view، اشتراک UI یا Security boundary مفید باشد؛ CSR هم میتواند برای Back-office مناسب باشد. مهمتر:
- داده شخصی در Cache مشترک نرود؛
- Cache key به Cookie/User اشتباه وابسته نشود؛
- HTML شخصی در CDN عمومی ذخیره نشود؛
- Authorization در Server action/API دوباره کنترل شود؛
- Logout و Back/Forward داده قبلی را نشت ندهند.
امنیت: SSG سطح حمله را حذف نمیکند، جابهجا میکند
نبود Database query در Request عمومی میتواند ریسک Runtime را کم کند؛ اما Build pipeline، CMS token، Dependency، CI runner، CDN، Third-party script، فرم/API و Artifact integrity باقیاند. SSR نیز Secret isolation، Injection، SSRF، Cache poisoning و Dependency failure دارد.
| سطح | SSG | SSR |
|---|---|---|
| Build | CMS/CI secret و supply chain حیاتی | Build + runtime dependency |
| Runtime | CDN/form/client/API | server/API/cache/auth |
| Data leak | Secret در Bundle/Artifact | Shared cache/personalized HTML/log |
| Recovery | Artifact rollback سریع اگر سالم | App/config/data rollback هماهنگ |
«Static پس امن است» یک Anti-pattern است. Threat model و Evidence لازماند.
Reliability: Failure mode هر روش متفاوت است
SSG میتواند هنگام خرابی CMS همچنان آخرین Artifact را سرو کند؛ اما اگر Build ناقص را Atomic منتشر نکنید، کل سایت ناسازگار میشود. SSR داده تازه دارد؛ ولی هر Dependency به مسیر درخواست وارد میشود.
| Failure | Static/Revalidated | SSR | راهحل |
|---|---|---|---|
| CMS down | آخرین Artifact | Request failure/timeout | cache/fallback/circuit breaker |
| Build fail | نسخه جدید منتشر نشود | ممکن است بیاثر باشد | atomic manifest + keep prior |
| Invalidation lost | Stale طولانی | Cache-dependent | reconciliation + age alert |
| Traffic spike | CDN مناسب، regeneration stampede ممکن | origin overload | request coalescing/rate/capacity |
Availability را با Freshness و Correctness با هم بسنجید؛ صفحه همیشه ۲۰۰ اما دارای قیمت غلط، Reliable نیست.
مقیاسپذیری: تعداد Route تنها عامل نیست
یک میلیون URL الزاماً Full build را ناممکن نمیکند و ده هزار صفحه الزاماً آسان نیست. Driverها:
- تعداد URL × نرخ تغییر × Fan-out وابستگی؛
- زمان و هزینه Fetch/Transform/Image در Build؛
- تعداد Locale/Variant و اندازه Artifact؛
- Cache hit ratio و Long-tail traffic؛
- Concurrency، quota و Deploy window؛
- Regeneration stampede و Purge limit.
Popular prebuild + on-demand generation + event invalidation اغلب از ساخت کامل بهتر است. برای Quota، Peak/Failure و Economics، راهنمای مقیاسپذیری پلتفرم را ببینید.
TCO: Compute تنها هزینه نیست
| هزینه | SSG/Revalidated | SSR |
|---|---|---|
| Compute | Build/regeneration | Request/cold start |
| Storage/CDN | Artifact/payload زیاد | Cache و egress |
| Engineering | dependency/invalidation/build ops | runtime/cache/capacity ops |
| Incident | stale/partial publish | outage/latency/cache leak |
| Vendor | build minute/purge/function | function/edge/observability |
Cost per page build یا Cost per request را با Incident، Human on-call و Vendor lock-in جمع کنید. ارزانترین Benchmark، لزوماً ارزانترین سیستم سالانه نیست.
سئو: HTML کامل شرط مفید است، تضمین رتبه نیست
SSR و SSG هر دو میتوانند محتوای اصلی را در پاسخ اولیه قرار دهند و وابستگی Crawler به JavaScript را کم کنند. اما SEO به URL، Status، Canonical، Robots، لینک، Sitemap، محتوای مفید، Schema و Performance هم وابسته است. صفحه Static با Canonical اشتباه یا ۴۰۴ نرم، «SEO عالی» نیست.
گوگل Server-side یا pre-rendering را ایده خوبی میداند، اما Dynamic rendering مخصوص Bot را راهحل بلندمدت توصیه نمیکند. برای Raw/Rendered diff، History API و Soft ۴۰۴، راهنمای سئوی JavaScript Intent تخصصی مکمل است.
Build pipeline را یک سامانه Production بدانید
SSG Build یک Script جانبی نیست؛ بخشی از Serving path است. حداقل Gateها:
Source snapshot/version pinned Schema/content/route validation passed Required URLs and redirects emitted No secret/PII in client artifact Link/canonical/robots/status fixtures passed Asset and bundle budgets passed Atomic manifest ready Canary deploy and smoke journeys passed Previous artifact retained for rollback Post-deploy URL/version/freshness verified
برای Artifact، Promotion، Canary و Rollback، راهنمای CI/CD جزئیات بیشتری دارد.
Headless CMS بدون Publish contract، Freshness نمیدهد
CMS باید Draft/Preview، Scheduled publish، Version، Webhook retry، Locale، Relation و Unpublish را مشخص کند. Preview نباید Artifact عمومی یا Cache را آلوده کند. انتشار باید Entityهای وابسته را invalidate و نتیجه عمومی را تأیید کند.
اگر Editor انتظار انتشار ۳۰ثانیهای دارد ولی Build دو ساعت طول میکشد، مشکل «کندی CMS» نیست؛ Operating contract غلط است. برای Content model و Preview/Rendering/Exit، راهنمای Headless CMS را ببینید.
Framework را پس از معماری انتخاب کنید
Next.js، Nuxt، Astro، SvelteKit، Gatsby، Hugo و دیگر ابزارها Capabilityهای متفاوت و متغیری دارند. Checklist بهتر از فهرست محبوبیت است:
- Static، dynamic، streaming و partial behavior در نسخه فعلی؛
- Time/event/tag revalidation و Failure semantics؛
- Self-host/adapter/CDN portability؛
- Cache header/key/purge visibility؛
- Preview، local development و production parity؛
- Observability، artifact export و rollback؛
- Bundle/Hydration controls و accessibility؛
- Pricing/quota/lock-in و Exit drill.
Feature در Roadmap یا Blog را قابلیت Production فرض نکنید؛ PoC را روی Adapter و Hosting واقعی اجرا کنید.
چهار سناریوی انتخاب
مجله و Documentation
Static/Revalidated معمولاً نقطه شروع خوبی است. Popular routes پیشساخته، Long tail on-demand، Publish event برای Invalidation و آخرین Artifact هنگام CMS outage. جستجوی داخلی و Comment میتوانند سرویس جدا باشند. Acceptance شامل انتشار، Unpublish، Redirect و Sitemap است.
سایت خبری
صفحه مقاله میتواند event-revalidated باشد؛ Home/Live feed Freshness کوتاهتر یا SSR cached میخواهد. Breaking news باید Purge و verification سریع داشته باشد. Scheduled publish، Correction و Traffic spike از اول تست شوند.
فروشگاه ایرانی
شرح، تصویر و Category قابلکشاند؛ قیمت/موجودی Budget جدا دارند و Checkout دوباره Validate میکند. شهر، هزینه ارسال و Login به Shared HTML نشت نمیکنند. UI، Schema، Feed و Order truth Reconcile میشوند؛ وابستگی درگاه یا Catalog خارجی fallback دارد.
SaaS و Dashboard
Marketing/docs عمومی Static یا SSR cached؛ Dashboard خصوصی CSR/SSR براساس UX و Security، نه SEO. Shell میتواند Cache شود ولی Data شخصی نه. Permission در API/Server action enforce و Session expiry/Back navigation تست میشود.
شرایط ایران را در معماری دخیل کنید
Latency فقط فاصله جغرافیایی نیست. ISP/mobile operator، CDN و Origin، DNS، دسترسی API خارجی، نرخ ارز، محدودیت پرداخت Vendor و کیفیت Android/WebView در نتیجه اثر دارند.
- SSR Origin خارج از دسترس یا پرLatency میتواند همه Routeها را همزمان مختل کند.
- Static artifact داخلی/چندمبدأ تابآوری میدهد، اما Invalidation باید هماهنگ باشد.
- Font/Analytics/CAPTCHA/Image optimizer خارجی fallback و timeout میخواهند.
- تومان/ریال، تاریخ شمسی/میلادی، RTL/Bidi و Locale باید در Cache key و Snapshot آزموده شوند.
- Probe از چند اپراتور داخل و خارج، Cold/warm cache و دستگاه میانرده لازم است.
مهاجرت را Route-by-Route انجام دهید
بازنویسی کامل معماری قبل از Evidence، ریسک بالایی دارد. یک Vertical slice نماینده انتخاب کنید:
- Baseline Field/Server/Cost/Freshness/Incident ثبت شود.
- Route contract و Hard gate تصویب شود.
- نسخه جدید در Shadow یا Host آزمایشی با Production data safe اجرا شود.
- Canary درصدی با URL/SEO parity و Business journey آغاز شود.
- Cache age، stale، error، LCP/INP و Outcome مقایسه شوند.
- Scale/Hold/Rollback براساس Gate انجام شود.
برای Bundle، CPU، Memory و Security سمت Client، راهنمای Performance و Security اپ JavaScript را در Acceptance قرار دهید.
Scorecard تصمیم SSR یا SSG
| عامل | گرایش Static/Revalidated | گرایش SSR/Request |
|---|---|---|
| Freshness | ثانیه/دقیقه/ساعت قابلتحمل | در هر Request لازم |
| Personalization | کم یا Client fragment | HTML وابسته به Request با Cache امن |
| Traffic | بالا/نامنظم با Cache hit خوب | قابلظرفیتگذاری و Cache |
| Dependency | میتوان Snapshot گرفت | باید Live query شود |
| Failure preference | آخرین نسخه معتبر بهتر از خطاست | داده تازه/Unavailable بهتر از Stale است |
| Update fan-out | کم یا Invalidation کنترلشده | بسیار زیاد/غیرقابلپیشبینی |
| Operations | Build/artifact expertise | runtime/capacity expertise |
سؤالهای متداول
آیا SSG همیشه از SSR سریعتر است؟
نه. SSG معمولاً TTFB خوبی دارد، اما Asset، تصویر، JavaScript و Hydration میتوانند LCP/INP را خراب کنند. SSR cached/streamed نیز ممکن است سریع باشد. Field data، Cache state و مسیر کامل کاربر را مقایسه کنید.
آیا فروشگاه اینترنتی حتماً باید SSR باشد؟
خیر. Description و Category میتوانند Static/Revalidated، قیمت و موجودی با Freshness budget و Checkout با Validation لحظهای باشند. انتخاب Route/Data-specific بهتر از SSR کامل فروشگاه است.
ISR همان SSG با TTL ثابت است؟
ISR نام یک Capability در Next.js است و رفتار دقیقش به Router، نسخه و Hosting وابسته است. خانواده الگو شامل time-based، on-demand و background revalidation است. Failure، stale serving، invalidation و observability را از مستند محیط خود اثبات کنید.
کدام روش برای سئو بهتر است؟
هر دو میتوانند HTML کامل و سئوی فنی درست بدهند. رتبه تضمین نمیشود؛ URL، Status، Canonical، Robots، Link، محتوا، Schema و Performance تعیینکنندهاند. خروجی عمومی را تست کنید، نه نام روش را.
آیا سایت Static امن و بدون سرور است؟
معمولاً Runtime عمومی سادهتر میشود، اما Build، CMS، CI/CD، Dependency، CDN، Third-party، فرم/API و Secretها باقیاند. Attack surface جابهجا میشود؛ Threat model، Access control، Artifact integrity و Incident response لازم است.
جمعبندی
انتخاب SSR یا SSG پاسخ ثابت پروژه نیست؛ قرارداد هر Route و Field است. Freshness، شخصیسازی، Cache key، Invalidation، Snapshot، Failure، Hydration، Security، Scale و TCO را بنویسید. سپس با Artifact/Request evidence، Field performance، Business correctness و Rollback آن را در Production ثابت کنید. معماری خوب معمولاً ترکیبی است و مرزهایش عمداً طراحی شدهاند.
منابع فنی منتخب
- web.dev — Rendering on the Web
- Google Search Central — JavaScript SEO basics
- Next.js — Incremental Static Regeneration
- Nuxt — Rendering modes and hybrid route rules
- RFC 9111 — HTTP Caching






