یک فروشگاه وردپرسی روی لپتاپ مدیر امتیاز ۹۶ میگیرد، اما کاربر با گوشی اقتصادی بعد از لمس «افزودن به سبد» یک ثانیه منتظر میماند. تیم برای بهبود بیشتر، همه CSSها را ادغام و JavaScript را Delay میکند؛ منوی موبایل بیاستایل چشمک میزند، Consent بعد از Analytics اجرا میشود و بازگشت درگاه گاهی از کار میافتد. مشکل کمبود یک افزونه دیگر نیست؛ تیم بدون دانستن هزینه هر Resource و وابستگی هر Interaction، تنظیم عمومی را روی کل سایت اعمال کرده است.
بهینهسازی CSS و JavaScript یعنی رساندن کمترین کد لازم، در زمان درست، با ترتیب و Cache درست، بدون شکستن ظاهر، تعامل، دسترسپذیری، سنجش یا امنیت. Minify و Brotli مفیدند، اما فقط Transfer را کم میکنند؛ کار اصلی با تشخیص زنجیره Discover → Request → Download → Parse/Compile → Execute → Style/Layout/Paint و حذف گلوگاه واقعی آغاز میشود.
پاسخ کوتاه: از کجا شروع کنیم؟
- Template و Journey مهم را انتخاب کنید؛ Homepage نماینده Checkout نیست.
- Field data و RUM را برای کاربران واقعی، سپس Lab trace را برای تشخیص جمع کنید.
- LCP، INP یا مشکل بصری را به Resource، Task و Owner مشخص نسبت دهید.
- اول Remove، سپس Reduce/Split، بعد Schedule و Cache را بررسی کنید.
- تغییر را روی Staging و دستگاه/شبکه هدف آزمایش، محدود منتشر و با Guardrail پایش کنید.
اگر پرسش شما اثر سرعت بر UX، سئو و Conversion است، مقاله سرعت سایت و سنجش اثر کسبوکار لایه تصمیم و ROI را پوشش میدهد.
CSS و JS دقیقاً کجا هزینه میسازند؟
| مرحله | هزینه CSS/JS | شاهد | مداخله نمونه |
|---|---|---|---|
| Discover/Request | کشف دیرهنگام، DNS/TLS، زنجیره Third-party | Network waterfall | HTML discovery، حذف chain، Hint هدفمند |
| Transfer | بایت زیاد یا Compression/Cache ضعیف | Transfer size، headers | Minify، br/gzip، immutable caching |
| Parse/Compile | کد فشرده اما زیاد روی CPU ضعیف | Performance trace | Remove، Split، syntax target |
| Execute | Long task، listener یا hydration سنگین | Main-thread flame chart | کمکردن کار، Yield، load-on-demand |
| Style/Layout | CSS حجیم، DOM زیاد، layout thrashing | Recalculate style/Layout | Scope، 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 journey | Release مسیر حیاتی را شکسته یا کند کرده؟ | تجربه همه کاربران را نمایندگی نمیکند |
راهنمای 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
چارچوب عملی:
- Remove: قابلیت، Plugin، Tag، Polyfill، Locale یا کتابخانه بیارزش را حذف کنید.
- Reduce: Tree shaking، هدف Build، Minification و CSS scope را اصلاح کنید.
- Split: Route، Feature، Interaction و Vendor boundary را جدا کنید.
- Schedule: Critical را زود و Non-critical را در زمان نیاز بیاورید.
- Compress/Cache: انتقال و بازدید تکراری را بهینه کنید.
- 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 default | Parser را هنگام Fetch/Execute متوقف میکند | سندی | کد واقعاً ضروری و کوچک | تاخیر DOM/Render |
defer | Fetch موازی؛ اجرا پس از Parse و پیش از DOMContentLoaded | حفظ میشود | DOM-dependent و dependency-ordered | همچنان Execution میتواند سنگین باشد |
async | Fetch موازی؛ اجرا بهمحض آمادگی | تضمین ندارد | 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 | کار | زمان مناسب | خطای رایج |
|---|---|---|---|
preconnect | DNS/TCP/TLS را جلو میاندازد | Origin ثالث حیاتی و قطعی | اتصالهای زیادِ بلااستفاده |
dns-prefetch | فقط DNS را جلو میاندازد | Origin محتمل با اولویت کمتر | انتظار اثر بزرگ |
preload | Resource فعلی را زود کشف میکند | LCP/font/style واقعاً حیاتی | نوع/CORS اشتباه یا Download دوباره |
modulepreload | Module 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، analytics | Dependency allowlist + interaction test |
| Remove unused CSS | کلاس Dynamic، RTL، Modal، Error | state/template corpus + visual diff |
| Combine files | order conflict، invalidation، giant bundle | waterfall/error/cache comparison |
| Minify | syntax/plugin conflict | console + smoke + rollback |
| CDN rewrite | CORS/SRI/mixed content/stale asset | header/hash/version validation |
| Preload/Critical CSS | FOUC، CLS، duplicate fetch | filmstrip + network initiator |
نمونه ایرانی: فروشگاه وردپرسی با فونت و درگاه
Baseline نشان میدهد Product LCP به Hero پس از CSS، INP سبد به اجرای همزمان Chat/Heatmap/Variation plugin و Checkout error به Delay شدن SDK درگاه مربوط است. برنامه درست:
- Chat و Heatmap فقط پس از Consent/Intent و خارج Checkout؛
- CSS Product جدا از Builder admin و Pluginهای بینیاز؛
- Hero در HTML قابلکشف و اولویت فقط همان Resource؛
- SDK پرداخت Exclusion مستند با integrity/availability monitoring متناسب؛
- فونت فارسی با وزن لازم، fallback همتراز و Cache نسخهدار؛
- Canary روی درصدی از Productها و Synthetic بازگشت درگاه؛
- 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
| لایه | معیار | تقسیمبندی |
|---|---|---|
| Delivery | request، transfer، compression، cache hit | route/resource/origin/cache state |
| CPU | parse/execute، long task، style/layout | device/release/interaction |
| User | LCP/INP/CLS و error | template/device/network/region |
| Correctness | checkout/form/menu/render/analytics | state/consent/auth |
| Business | qualified conversion، abandonment، support | cohort/release |
| Security | CSP/SRI violation، dependency incident | route/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 و مستند جاری را در زمان اجرا بررسی کنید.
- Google: About PageSpeed Insights
- MDN: script element، async/defer/module
- MDN: Compression in HTTP
- Chrome DevTools: Lighthouse و Coverage
- Chrome DevTools: Runtime performance
- web.dev: Optimize LCP
- web.dev: Third-party JavaScript
- MDN: Subresource Integrity
سوالات متداول بهینهسازی 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 آزمایش کنید. همین انضباط از ده «تکنیک طلایی» قابلاعتمادتر است.






