بهینه‌سازی CSS و JavaScript؛ تحویل، اجرا و سنجش

یک فروشگاه وردپرسی روی لپ‌تاپ مدیر امتیاز ۹۶ می‌گیرد، اما کاربر با گوشی اقتصادی بعد از لمس «افزودن به سبد» یک ثانیه منتظر می‌ماند. تیم برای بهبود بیشتر، همه CSSها را ادغام و JavaScript را Delay می‌کند؛ منوی موبایل بی‌استایل چشمک می‌زند، Consent بعد از Analytics اجرا می‌شود و بازگشت درگاه گاهی از کار می‌افتد. مشکل کمبود یک افزونه دیگر نیست؛ تیم بدون دانستن هزینه هر Resource و وابستگی هر Interaction، تنظیم عمومی را روی کل سایت اعمال کرده است.

بهینه‌سازی CSS و JavaScript یعنی رساندن کمترین کد لازم، در زمان درست، با ترتیب و Cache درست، بدون شکستن ظاهر، تعامل، دسترس‌پذیری، سنجش یا امنیت. Minify و Brotli مفیدند، اما فقط Transfer را کم می‌کنند؛ کار اصلی با تشخیص زنجیره Discover → Request → Download → Parse/Compile → Execute → Style/Layout/Paint و حذف گلوگاه واقعی آغاز می‌شود.

پاسخ کوتاه: از کجا شروع کنیم؟

  1. Template و Journey مهم را انتخاب کنید؛ Homepage نماینده Checkout نیست.
  2. Field data و RUM را برای کاربران واقعی، سپس Lab trace را برای تشخیص جمع کنید.
  3. LCP، INP یا مشکل بصری را به Resource، Task و Owner مشخص نسبت دهید.
  4. اول Remove، سپس Reduce/Split، بعد Schedule و Cache را بررسی کنید.
  5. تغییر را روی Staging و دستگاه/شبکه هدف آزمایش، محدود منتشر و با Guardrail پایش کنید.

اگر پرسش شما اثر سرعت بر UX، سئو و Conversion است، مقاله سرعت سایت و سنجش اثر کسب‌وکار لایه تصمیم و ROI را پوشش می‌دهد.

CSS و JS دقیقاً کجا هزینه می‌سازند؟

مرحلههزینه CSS/JSشاهدمداخله نمونه
Discover/Requestکشف دیرهنگام، DNS/TLS، زنجیره Third-partyNetwork waterfallHTML discovery، حذف chain، Hint هدفمند
Transferبایت زیاد یا Compression/Cache ضعیفTransfer size، headersMinify، br/gzip، immutable caching
Parse/Compileکد فشرده اما زیاد روی CPU ضعیفPerformance traceRemove، Split، syntax target
ExecuteLong task، listener یا hydration سنگینMain-thread flame chartکم‌کردن کار، Yield، load-on-demand
Style/LayoutCSS حجیم، DOM زیاد، layout thrashingRecalculate style/LayoutScope، DOM، read/write batching
Paint/Compositeافکت پرهزینه یا تغییر بزرگ بصریRendering/Paint profilerساده‌سازی، stable geometry

فایل ۸۰KB می‌تواند به‌خاطر اجرای سنگین از فایل ۲۰۰KB بدتر باشد. بنابراین «حجم Bundle» Proxy است، نه تجربه کامل.

مرورگر CSS و JavaScript را چگونه پردازش می‌کند؟

HTML به DOM و CSS به CSSOM تبدیل می‌شود؛ برای ساخت Render tree، مرورگر به هر دو نیاز دارد. Stylesheetهای قابل‌اعمال معمولاً Render را تا آماده‌شدن CSSOM نگه می‌دارند. Classic script بدون async، defer یا type="module" هنگام برخورد Parser دانلود/اجرا می‌شود و Parsing را متوقف می‌کند. جزئیات به محل، نوع Resource، Cache، Media و Dependency وابسته‌اند.

منبع رسمی MDN برای عنصر script تأکید می‌کند async ترتیب اجرا را تضمین نمی‌کند، defer ترتیب سند را حفظ و پس از Parse اجرا می‌شود و Module script به‌طور پیش‌فرض Deferred است. این ویژگی‌ها «کد را سریع‌تر» نمی‌کنند؛ زمان Fetch/Execution را تغییر می‌دهند.

Field، Lab و Synthetic را مخلوط نکنید

مستند رسمی PageSpeed Insights Field data را از CrUX و تجربه واقعی ۲۸ روز گذشته و Lab data را از Lighthouse در شرایط شبیه‌سازی‌شده می‌داند. Field برای دیدن توزیع تجربه واقعی و Lab برای بازتولید/تشخیص مفید است. سبزشدن یک Run آزمایشگاهی تضمین نمی‌کند کاربران واقعی خوب باشند؛ تغییر امروز نیز فوراً در پنجره تاریخی Field ظاهر نمی‌شود.

دادهپرسشمحدودیت
CrUX/Search Consoleگروه کاربران واقعی چه تجربه‌ای داشته‌اند؟تجمیعی/تاریخی و Attribution محدود
RUMکدام Template/Release/Device/Interaction بد است؟نیازمند طراحی Telemetry و Privacy
Lighthouseدر سناریوی کنترل‌شده چه فرصت‌هایی دیده می‌شود؟یک شبیه‌سازی و مستعد نوسان
DevTools traceکدام Request/Task/Style/Layout علت است؟مهارت تحلیل و سناریوی تکرارپذیر می‌خواهد
Synthetic journeyRelease مسیر حیاتی را شکسته یا کند کرده؟تجربه همه کاربران را نمایندگی نمی‌کند

راهنمای Core Web Vitals، LCP/INP/CLS و RUM تعریف معیار، صدک ۷۵ و Attribution را عمیق‌تر پوشش می‌دهد.

یک Baseline قابل‌مقایسه بسازید

page_type + route + state + device + network + cache_state + auth_state + consent_state + release_id

برای سایت ایرانی دست‌کم Article، Product، Category، Search، Cart و Checkout را روی موبایل میان‌رده/اقتصادی، اینترنت همراه و ثابت، Cache سرد/گرم و حالت Login/Guest نمونه‌برداری کنید. در Checkout، بازگشت درگاه و خطای شبکه را هم سناریو بدانید. تغییرات را با Release marker ثبت کنید تا «قبل/بعد» واقعاً به یک Deploy اشاره کند.

Performance budget را بر اساس Route و Journey تعریف کنید

Budget فقط سقف KB نیست. برای هر Template حد Transfer، تعداد Request، مقدار JavaScript اولیه، Long task، LCP subpart، INP، CLS و Third-party CPU تعیین کنید. عدد باید از Baseline، دستگاه هدف و هدف محصول بیاید؛ بودجه عمومی ۱۰۰KB برای همه سایت‌ها وجود ندارد.

Checkout mobile cold-cache:
- initial JS transfer budget
- main-thread CPU before usable
- third-party request/CPU budget
- LCP/INP/CLS field guardrail
- payment callback correctness = must pass
- error rate and conversion = must not regress

ترتیب اقدام: Remove پیش از Minify

چارچوب عملی:

  1. Remove: قابلیت، Plugin، Tag، Polyfill، Locale یا کتابخانه بی‌ارزش را حذف کنید.
  2. Reduce: Tree shaking، هدف Build، Minification و CSS scope را اصلاح کنید.
  3. Split: Route، Feature، Interaction و Vendor boundary را جدا کنید.
  4. Schedule: Critical را زود و Non-critical را در زمان نیاز بیاورید.
  5. Compress/Cache: انتقال و بازدید تکراری را بهینه کنید.
  6. Verify: عملکرد، صحت، A11y، Analytics، SEO و Security را دوباره بسنجید.

این ترتیب مانع می‌شود فایل غیرضروری را عالی فشرده و تا ابد Cache کنید.

Minification چه می‌کند و چه نمی‌کند؟

Minifier فاصله/Comment و شکل‌های قابل‌کوتاه‌شدن کد را تغییر می‌دهد و گاهی با Mangle نام‌ها حجم را کم می‌کند. مقدار کاهش ثابت ۳۰ یا ۴۰ درصد وجود ندارد. Source، Tool، Target و Compression نتیجه را عوض می‌کند.

  • Build production را Minify و Source map را از دسترسی ناخواسته محافظت کنید.
  • Banner مجوزهای لازم را بدون بررسی حقوقی حذف نکنید.
  • Syntax قدیمی، eval، inline handler یا Plugin ناسازگار ممکن است پس از Transform بشکند.
  • Minification رمزنگاری، Obfuscation امن یا دفاع XSS نیست.
  • Original، Minified و Compressed transfer size را جدا گزارش کنید.

Compression: Brotli و Gzip را از روی Header اثبات کنید

Browser با Accept-Encoding قابلیت را اعلام و Server/CDN با Content-Encoding Representation را مشخص می‌کند. راهنمای Compression در MDN استفاده از Vary: Accept-Encoding برای Cache representationهای مختلف و پرهیز از فشرده‌سازی دوباره فایل‌های ذاتاً فشرده مانند تصویر/ویدئو را توضیح می‌دهد.

curl -I -H 'Accept-Encoding: br, gzip' https://example.com/assets/app.js

Expected evidence:
Content-Type: text/javascript
Content-Encoding: br   # or gzip by negotiation
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000, immutable  # only for content-hashed asset

Brotli همیشه «سریع‌تر» نیست؛ سطح Compression بالا ممکن است CPU Build/Origin را زیاد کند. Asset ثابت را Precompress کنید یا از Edge بهره بگیرید و نسبت، CPU و latency را بسنجید.

Cache و نام‌گذاری فایل: محتوای تغییرناپذیر، URL تغییرپذیر

Asset نسخه‌دار مانند app.a81f3c.js می‌تواند TTL طولانی و immutable داشته باشد، چون با تغییر محتوا URL عوض می‌شود. HTML کوتاه‌تر Cache یا Revalidation می‌خواهد تا به Chunk جدید اشاره کند. انتشار ناقص که HTML جدید را قبل از Upload همه Chunkها فعال کند، ChunkLoadError می‌سازد.

نسخه‌های قبلی Asset را به‌اندازه پنجره Cache/Session نگه دارید، Deploy را Atomic کنید و Rollback artifact داشته باشید. تنظیم دقیق لایه‌ها در راهنمای Cache وردپرس و رفع نسخه قدیمی آمده است.

آیا همه فایل‌های CSS و JS را Combine کنیم؟

خیر. در HTTP/۲ و HTTP/۳، درخواست متعدد همان هزینه HTTP/۱.۱ را ندارد؛ یک Bundle عظیم می‌تواند Cache invalidation، Code sharing و Load-on-demand را بدتر کند. از طرف دیگر Chunkهای بسیار ریز نیز Waterfall، Overhead و اولویت‌بندی پیچیده می‌سازند.

Boundary را با Route/Feature/Change frequency/Cache reuse و Waterfall واقعی انتخاب کنید. تصمیم «Combine on/off» در افزونه وردپرس باید روی Templateهای واقعی آزمایش شود، نه از نسخه عمومی اینترنت کپی شود.

Tree shaking چه زمانی واقعاً کار می‌کند؟

Tree shaking به Static module graph و اطلاعات Side effect وابسته است. CommonJS پویا، importهای شرطی غیرقابل‌تحلیل، package metadata نادرست یا Barrel export ممکن است کد را نگه دارد یا بدتر، کد لازم را حذف کند.

  • Bundle analyzer را برای Duplicate package، Locale و Polyfill بررسی کنید.
  • Import خاص را جای Import کل کتابخانه، فقط پس از اندازه‌گیری، به‌کار ببرید.
  • Side-effect declaration را با Test و مستند Package تنظیم کنید.
  • Build report را در CI ذخیره و Diff کنید.
  • قابلیت‌های Dynamic و Admin-only را روی Front-end عمومی نفرستید.

Coverage کد استفاده‌نشده را چگونه تفسیر کنیم؟

راهنمای Lighthouse و Coverage در Chrome DevTools نشان می‌دهد Coverage می‌تواند کد اجراشده در همان Load را تفکیک کند. اما قرمز بودن در یک Page load به معنای حذف قطعی نیست؛ ممکن است کد پس از Scroll، Login، Consent، Error، Variant، Keyboard یا Add-to-cart لازم شود.

Coverage candidate → map to owner/feature → exercise states/interactions → remove/split hypothesis → regression suite → canary

برای CSS نیز حالت‌های Responsive، Hover/Focus، RTL، چاپ، Validation، Modal و محتوای CMS را آزمایش کنید. Safelist بزرگ و بی‌قاعده Purge را بی‌اثر می‌کند؛ Safelist کوچک بدون تست کلاس‌های Dynamic را می‌شکند.

Code splitting و Lazy loading را روی مرز درست انجام دهید

Chunk را وقتی جدا کنید که احتمالاً در Journey اولیه لازم نیست و در لحظه نیاز هم می‌تواند به‌موقع برسد. Modal نادر، Editor، Chart یا نقشه پس از intent کاندید خوب‌اند؛ Validation اصلی Checkout یا منوی موبایل کاندید پرریسک‌اند.

برای Dynamic import، Loading/Error/Timeout/Retry و نسخه قدیمی Chunk را طراحی کنید. Prefetch/Preload کورکورانه می‌تواند پهنای‌باند Resource حیاتی را بدزدد. روی شبکه ضعیف و Save-Data، سیاست محافظه‌کارانه‌تر داشته باشید.

async، defer و module: جدول تصمیم

نوعFetch/Executionترتیبمناسب برایریسک
Classic defaultParser را هنگام Fetch/Execute متوقف می‌کندسندیکد واقعاً ضروری و کوچکتاخیر DOM/Render
deferFetch موازی؛ اجرا پس از Parse و پیش از DOMContentLoadedحفظ می‌شودDOM-dependent و dependency-orderedهمچنان Execution می‌تواند سنگین باشد
asyncFetch موازی؛ اجرا به‌محض آمادگیتضمین نداردScript مستقلRace و قطع Parsing هنگام Execute
moduleبه‌طور پیش‌فرض Deferred، graph fetchقواعد Moduleکد مدرن ماژولارCORS، dependency graph، legacy behavior
On-demandپس از Intent/Interactionبا State machine شماقابلیت غیرحیاتیLatency لحظه نیاز/Failure

Analytics همیشه async و همه فایل‌های حیاتی همیشه defer نیستند. Consent order، dataLayer، dependency و business event را با Test ثابت کنید.

JavaScript را فقط دیرتر نیاورید؛ کار Main Thread را کم کنید

Delay دانلود، Parse/Execute را حذف نمی‌کند؛ ممکن است کار سنگین را دقیقاً هنگام اولین تعامل کاربر اجرا کند و INP را بدتر کند. Trace را برای Long task و Interaction بررسی کنید، work را تقسیم یا حذف، handler را سبک و DOM read/write را Batch کنید.

مقاله بهینه‌سازی اپلیکیشن JavaScript، INP و امنیت درباره Main thread، Worker، Rendering/Hydration، Memory، XSS و Supply chain مرجع عمیق‌تر است.

CSS حیاتی: Critical را کوچک کنید، نه اینکه CSS را پنهان کنید

CSS لازم برای اولین Render می‌تواند Inline یا بسیار زود تحویل شود و CSS غیرحیاتی با روش آزموده‌شده بعدتر برسد. اما Critical CSS به Template، Viewport، State، فونت و محتوای واقعی وابسته است.

  • Inline بیش‌ازحد HTML را بزرگ و Cache مشترک stylesheet را ضعیف می‌کند.
  • Generator یک Viewport ممکن است Menu باز، Error، Cookie banner یا RTL را جا بیندازد.
  • Load دیرهنگام CSS می‌تواند FOUC و CLS بسازد.
  • CSP برای Style inline باید از ابتدا طراحی شود.
  • Critical CSS به‌تنهایی LCP زیر یک ثانیه یا رتبه بهتر را تضمین نمی‌کند.

LCP را با چهار زیربخش تشخیص دهید

راهنمای رسمی web.dev برای LCP پیشنهاد می‌کند Time to First Byte، Resource load delay، Resource load duration و Element render delay جدا بررسی شوند. CSS/JS ممکن است در هر کدام نقش متفاوت داشته باشد:

  • Hero در CSS background یا پس از JS دیر کشف می‌شود؛
  • CSS render-blocking یا Font نمایش را نگه می‌دارد؛
  • Client rendering داده/عنصر LCP را دیر می‌سازد؛
  • Main-thread work اجازه Paint به‌موقع نمی‌دهد.

برای Resource واقعی LCP و اندازه مناسب، preload یا fetchpriority ممکن است کمک کند؛ همه Assetها را High priority نکنید، چون Priority معنایش را از دست می‌دهد.

Unused CSS، Cascade و Component ownership

یک stylesheet جهانی از Theme، Builder و Plugin معمولاً Selectorهایی برای Templateهای دیگر دارد. هدف صفرکردن Coverage روی هر Page نیست؛ هدف جلوگیری از ارسال غیرمنطقی همراه با حفظ Cache reuse و قابلیت نگهداری است.

CSS را بر پایه Base/Token/Layout/Component/Template/Utility مالکیت‌دهی کنید. از Cascade layer و Scope مناسب، Split در سطح Template و حذف Plugin CSS در Pageهای بی‌نیاز بهره ببرید. برای معماری Cascade و Progressive enhancement، راهنمای CSS مدرن در Production را ببینید.

Third-party JavaScript: هر Tag یک Supplier فعال است

راهنمای Third-party JavaScript در web.dev به هزینه CPU، Privacy/Security، SPOF، Cache، Duplicate dependency و رفتار غیرقابل‌پیش‌بینی اشاره می‌کند. Inventory بسازید:

vendor, owner, purpose, pages, consent_basis, data_access, load_condition, network_bytes, main_thread_ms, timeout, fallback, expiry, removal_test

Chat، Map، A/B test، Heatmap، Ads، CAPTCHA و Analytics را بر اساس Outcome نگه دارید. Facade یا load-after-intent می‌تواند مفید باشد، اما اگر کاربر برای قابلیت اصلی باید منتظر Vendor بماند، Fallback لازم است. Self-hosting نیز Update، License، Privacy و Cache responsibility را به شما منتقل می‌کند.

Resource hint را با Waterfall انتخاب کنید

Hintکارزمان مناسبخطای رایج
preconnectDNS/TCP/TLS را جلو می‌اندازدOrigin ثالث حیاتی و قطعیاتصال‌های زیادِ بلااستفاده
dns-prefetchفقط DNS را جلو می‌اندازدOrigin محتمل با اولویت کمترانتظار اثر بزرگ
preloadResource فعلی را زود کشف می‌کندLCP/font/style واقعاً حیاتینوع/CORS اشتباه یا Download دوباره
modulepreloadModule graph candidate را زود می‌آوردEntry/module بحرانی ثابتPreload کل graph
prefetchبرای Navigation آینده hint می‌دهداحتمال بالا و شبکه مناسبمصرف داده برای حدس ضعیف

Font و CSS: مسئله فقط JavaScript نیست

فونت فارسی حجیم، وزن‌های زیاد و مسیر Cross-origin می‌تواند Text LCP و CLS را تحت‌تأثیر قرار دهد. Family/weight/style لازم را محدود، Subset را با حقوق و Coverage واقعی فارسی بسنجید، Fallback metrics را هم‌تراز و رفتار نمایش را روی دستگاه هدف آزمایش کنید. Preload فقط فونت واقعاً مصرف‌شده در اولین View را با CORS درست انجام دهد.

Performance و Security هم‌پوشانی دارند، مترادف نیستند

حذف Dependency بی‌استفاده می‌تواند سطح نگهداری و Exposure را کم کند، اما CSS/JS Minified «امن» نمی‌شود. XSS به Source/Sink، Encoding/Sanitization و Policy مربوط است. Library قدیمی باید با Reachability، vulnerability، exploitability و upgrade test بررسی شود؛ حجم کم نشانه نبود آسیب‌پذیری نیست.

برای استقرار عمیق XSS defense، مقاله Content Security Policy و XSS در وردپرس را بخوانید.

SRI را دقیق و با CORS به‌کار ببرید

مستند جاری Subresource Integrity در MDN توضیح می‌دهد Browser هش Resource را با integrity مقایسه و در صورت عدم تطابق Load را رد می‌کند. برای Resource Cross-origin، CORS و معمولاً crossorigin="anonymous" لازم است.

<script
  src="https://cdn.example.com/library.v1.min.js"
  integrity="sha384-..."
  crossorigin="anonymous"
  defer></script>

SRI برای فایل Immutable مناسب‌تر است. اگر Vendor فایل را زیر همان URL تغییر دهد، Hash mismatch قابلیت را می‌شکند؛ Pin version، fallback، monitoring و update process لازم است. SRI جای CSP، Vendor review یا HTTPS را نمی‌گیرد.

CSP و Inline optimization را با هم طراحی کنید

Inline کردن CSS/JS برای Performance می‌تواند Strict CSP را دشوار کند. Nonce/Hash را در Build/Response pipeline طراحی کنید و 'unsafe-inline' را برای حل سریع عمومی اضافه نکنید. CSP را ابتدا Report-Only، سپس با نمونه واقعی Route/State و Rollback به Enforcement ببرید.

SEO: سرعت مهم است، اما «JS کمتر = رتبه بالاتر» قانون نیست

Performance بخشی از Page experience است و می‌تواند دسترسی و رضایت را بهتر کند؛ اما رتبه به Relevance، کیفیت، رقابت و سیگنال‌های متعدد وابسته است. تغییر CSS/JS همچنین ممکن است متن، لینک، H1، canonical یا schema را فقط پس از Interaction نمایش دهد و مسئله Rendering/Index بسازد.

برای Route، Status، Raw/Rendered HTML، لینک و Metadata از چک‌لیست سئوی JavaScript و Release gate رندر استفاده کنید. «امتیاز Lighthouse SEO» نیز رتبه یا Indexability کامل نیست.

WordPress: تنظیم سراسری، ریسک سراسری

Theme، Builder و Pluginها ممکن است Dependency و ترتیب خاص داشته باشند. Delay/Defer/Remove-unused-CSS/Combine را به‌ترتیب و روی Staging فعال کنید؛ بعد Header، Menu، Search، Form، Login، Cart، Checkout، Payment return، Consent، Analytics، CAPTCHA و Admin bar را تست کنید.

تغییرشکست محتملGuardrail
Delay all JSاولین click، consent، payment، analyticsDependency allowlist + interaction test
Remove unused CSSکلاس Dynamic، RTL، Modal، Errorstate/template corpus + visual diff
Combine filesorder conflict، invalidation، giant bundlewaterfall/error/cache comparison
Minifysyntax/plugin conflictconsole + smoke + rollback
CDN rewriteCORS/SRI/mixed content/stale assetheader/hash/version validation
Preload/Critical CSSFOUC، CLS، duplicate fetchfilmstrip + network initiator

نمونه ایرانی: فروشگاه وردپرسی با فونت و درگاه

Baseline نشان می‌دهد Product LCP به Hero پس از CSS، INP سبد به اجرای هم‌زمان Chat/Heatmap/Variation plugin و Checkout error به Delay شدن SDK درگاه مربوط است. برنامه درست:

  1. Chat و Heatmap فقط پس از Consent/Intent و خارج Checkout؛
  2. CSS Product جدا از Builder admin و Pluginهای بی‌نیاز؛
  3. Hero در HTML قابل‌کشف و اولویت فقط همان Resource؛
  4. SDK پرداخت Exclusion مستند با integrity/availability monitoring متناسب؛
  5. فونت فارسی با وزن لازم، fallback هم‌تراز و Cache نسخه‌دار؛
  6. Canary روی درصدی از Productها و Synthetic بازگشت درگاه؛
  7. RUM بر اساس دستگاه/ISP/Release و Guardrail Conversion/Error.

اگر CDN در مسیر Asset است، معماری Origin/Cache/ایران را با راهنمای انتخاب و راه‌اندازی CDN برای سایت ایرانی تطبیق دهید.

تست صحت پس از هر تغییر

  • Console error و unhandled rejection صفر یا دارای Baseline موجه؛
  • Network: ۴۰۴/blocked/MIME/CORS/SRI/duplicate fetch بررسی؛
  • Visual diff در Viewport/RTL/Theme/Stateهای نماینده؛
  • Keyboard، Focus، reduced motion و Screen reader smoke؛
  • Form validation، Cart، Checkout، Login، Payment return؛
  • Analytics/Consent event order و عدم Double fire؛
  • Raw/Rendered content، internal links، canonical/schema؛
  • Cold/warm cache و Deploy/Rollback؛
  • شبکه قطع/کند و Third-party unavailable؛
  • RUM/Business guardrail در Canary.

انتشار امن: یک متغیر، Canary و Rollback

hypothesis → baseline → staging → representative test → canary → field guardrail → scale/hold/rollback

هم‌زمان Minify، Delay، Combine، Critical CSS و CDN را روشن نکنید؛ در شکست علت ناشناخته می‌ماند. Config قبل را Export، Purge/Preload را ثبت و Kill switch قابل‌دسترسی نگه دارید. Rollback فقط خاموش‌کردن UI افزونه نیست؛ Cacheهای Browser/CDN و HTML اشاره‌کننده به Asset را نیز در نظر بگیرید.

Measurement plan و Definition of Done

لایهمعیارتقسیم‌بندی
Deliveryrequest، transfer، compression، cache hitroute/resource/origin/cache state
CPUparse/execute، long task، style/layoutdevice/release/interaction
UserLCP/INP/CLS و errortemplate/device/network/region
Correctnesscheckout/form/menu/render/analyticsstate/consent/auth
Businessqualified conversion، abandonment، supportcohort/release
SecurityCSP/SRI violation، dependency incidentroute/vendor/version

Done یعنی Hypothesis در Segment هدف بهتر شده، Guardrailها Regression ندارند، مالک و مستند تغییر ثبت شده و Rollback تمرین شده است؛ نه اینکه Score یک بار بالا رفته باشد.

برنامه ۱۴روزه بهینه‌سازی CSS و JavaScript

روز ۱ تا ۳: Inventory و Baseline

Template/Journey، Field/RUM، Network/Performance trace، Asset ownership و Third-party inventory را ثبت کنید. یک گلوگاه با Outcome مهم انتخاب شود.

روز ۴ تا ۶: Remove و Budget

Resource یا قابلیت بی‌ارزش را حذف، Budget Route را تعریف و Bundle/Coverage را در حالت‌های نماینده تحلیل کنید.

روز ۷ تا ۱۰: Delivery و Scheduling

Minify/Compression/Cache، Split، async/defer/module، Critical CSS یا Resource hint را فقط در حد Hypothesis اجرا کنید.

روز ۱۱ تا ۱۲: Regression و Failure

Checkout/Payment/Consent/Analytics/RTL/A11y/SEO و Third-party failure را روی Staging و دستگاه واقعی تست کنید.

روز ۱۳ تا ۱۴: Canary و تصمیم

Release marker، درصد محدود، RUM/Error/Conversion guardrail و تصمیم Scale/Hold/Rollback را ثبت کنید.

خطاهای رایج در بهینه‌سازی CSS و JS

  • بهینه‌سازی Homepage به‌جای Journey پرارزش؛
  • اتکا به یک Lighthouse score بدون Field/RUM؛
  • گرفتن Transfer size به‌جای Parse/Execute/Main thread؛
  • ترکیب همه فایل‌ها بدون توجه به HTTP/۲/۳ و Cache؛
  • حذف هر خط قرمز Coverage بدون تست State؛
  • Delay همه JavaScript و انتقال CPU به لحظه Interaction؛
  • async برای Script وابسته و ساخت Race؛
  • Critical CSS تولیدشده برای یک Viewport؛
  • Preload همه فونت‌ها/تصاویر/Chunkها؛
  • فشرده‌سازی دوباره تصویر و فایل از قبل فشرده؛
  • TTL طولانی روی Asset بدون Content hash؛
  • Minification به‌عنوان Security؛
  • SRI بدون CORS/Version/Fallback؛
  • خاموش‌کردن CSP برای Inline optimization؛
  • فعال‌کردن چند گزینه افزونه هم‌زمان بدون Rollback.

منابع و وضعیت زمانی

این راهنما در ۱۲ اوت ۲۰۲۶ بازبینی شده است. Browser، ابزار و قابلیت‌های وب تغییر می‌کنند؛ Support و مستند جاری را در زمان اجرا بررسی کنید.

سوالات متداول بهینه‌سازی CSS و JavaScript

تفاوت Minify و Brotli یا Gzip چیست؟

Minify ساختار Source را با حذف/کوتاه‌سازی بخش‌های غیرضروری تغییر می‌دهد؛ Brotli/Gzip Representation انتقالی را فشرده می‌کند و Browser آن را Decode می‌کند. می‌توان هر دو را داشت، اما اثر باید از Build artifact و Header واقعی سنجیده شود.

برای JavaScript از async استفاده کنیم یا defer؟

اگر Script مستقل و بی‌نیاز از ترتیب است، async ممکن است مناسب باشد. اگر به DOM یا ترتیب Scriptها وابسته است، defer معمولاً قابل‌پیش‌بینی‌تر است. Moduleها Deferred هستند. در هر حالت Execution سنگین همچنان Main thread را درگیر می‌کند.

آیا حذف CSS و JavaScript استفاده‌نشده امن است؟

فقط پس از آزمون Template، Viewport، Login، Consent، خطا، Hover/Focus، RTL و Interactionهای واقعی. Coverage یک اجرا Candidate می‌دهد، نه مجوز حذف. Dynamic class و مسیرهای کم‌استفاده باید در Corpus تست باشند.

آیا افزونه Cache برای بهینه‌سازی CSS و JS کافی است؟

خیر. افزونه Delivery و برخی Transformها را کمک می‌کند، اما Plugin/Theme بی‌نیاز، Main-thread work، Third-party value، Dependency، Rendering، Regression و Outcome را به‌تنهایی حل نمی‌کند. تنظیمات نیز باید Staging، Canary و Rollback داشته باشند.

آیا بهینه‌سازی CSS و JS رتبه سئو را بهتر می‌کند؟

ممکن است تجربه و برخی معیارهای عملکرد را بهتر کند، اما تضمین رتبه نیست. Relevance، کیفیت و عوامل متعدد دیگر مهم‌اند. تغییر نباید محتوای اصلی، لینک، Metadata، schema یا قابلیت Rendering/Index را خراب کند.

جمع‌بندی: کد کمتر فقط وقتی ارزش دارد که تجربه بهتر بماند

بهترین Optimization دکمه «Minify all» نیست؛ حذف Resource بی‌ارزش و کاهش کار مسیر حیاتی بر اساس شاهد است. Field مشکل را نشان می‌دهد، Lab/Trace علت را پیدا می‌کند و Canary ثابت می‌کند راه‌حل بدون Regression کار کرده است.

برای شروع، یک Journey مانند Product→Cart→Checkout را انتخاب کنید. Waterfall و Main-thread trace آن را روی موبایل هدف بگیرید، پرهزینه‌ترین CSS/JS را به Owner و Purpose وصل کنید و فقط یک Hypothesis را با Rollback آزمایش کنید. همین انضباط از ده «تکنیک طلایی» قابل‌اعتمادتر است.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *