← بازگشت به صفحه اصلی

تمام تغییرات مهم در این پروژه در این فایل مستند می‌شود.


[2.3.1] - 2025-12-29

⚡ بهینه‌سازی عملکرد (Performance)

🎯 رفع Forced Reflow در app-vendor.js، Swiper، و reflow-optimizer (v3.0 - CRITICAL)

مشکل 1: app-vendor.js (Update 1)

راه‌حل Update 1:

$vendor_deps = array();
if ($enable_reflow_optimization) {
    $vendor_deps[] = 'dom-interceptor';
}
wp_enqueue_script('app-vendor', ..., $vendor_deps, ...);

مشکل 2: swiper.js (Update 2)

راه‌حل Update 2:

// Swiper را در header بعد از dom-interceptor لود کنیم
if ($load_swiper) {
    wp_enqueue_script('swiper-script', ..., array('dom-interceptor'), ..., false);
    
    if ($enable_reflow_optimization) {
        wp_enqueue_script('swiper-wrapper', ..., array('swiper-script'), ..., false);
    }
}

مشکل 3 (CRITICAL): reflow-optimizer خودش reflow ایجاد می‌کرد! (Update 3)

راه‌حل Update 3 (Architectural Fix):

  1. DOM Interceptor مستقل شد (v2.0):
    • دیگر به ReflowOptimizer وابسته نیست
    • یک lightweight batcher داخلی دارد
    • می‌تواند قبل از همه لود شود
// dom-interceptor.js v2.0
let batchQueue = {
    measureQueue: [],
    mutateQueue: [],
    measure(callback) { /* RAF batching */ },
    mutate(callback) { /* RAF batching */ },
    flush() { /* execute queues */ }
};

const optimizer = typeof window.ReflowOptimizer !== "undefined" 
    ? window.ReflowOptimizer 
    : batchQueue;
  1. Load Order تغییر کرد: ```php // قبلی (❌ WRONG): wp_enqueue_script(‘reflow-optimizer’, …, array(), …, false); // اول wp_enqueue_script(‘dom-interceptor’, …, array(‘reflow-optimizer’), …, false); // دوم

// جدید (✅ CORRECT): wp_enqueue_script(‘dom-interceptor’, …, array(), …, false); // اول wp_enqueue_script(‘reflow-optimizer’, …, array(‘dom-interceptor’), …, false); // دوم


**ترتیب load نهایی (v3 - FINAL):**
1. ✅ **dom-interceptor.js** (NO deps) ← CRITICAL FIX! اول از همه
2. ✅ reflow-optimizer.js (deps: dom-interceptor)
3. ✅ performance-optimizer.js (deps: reflow-optimizer)
4. ✅ inp-optimizer.js
5. ✅ swiper-script.js (deps: dom-interceptor) [if needed]
6. ✅ swiper-wrapper.js (deps: swiper-script) [if needed]
7. ✅ app-vendor.js (deps: dom-interceptor)
8. ✅ app-coins.js (deps: app-vendor)

**فایل‌های تغییر یافته:**
- `app/Support/Assets.php`: تغییر CRITICAL در load order - dom-interceptor حالا اول
- `assets/js/dom-interceptor.js`: نسخه 2.0 - مستقل با internal batcher
- `assets/js/swiper-wrapper.js`: نسخه 2.0 - ساده‌تر
- `docs/FORCED-REFLOW.md`: بروزرسانی با Update 3 - توضیح circular problem

**نتیجه پیش‌بینی شده:**
- ✅ reflow-optimizer دیگر خودش reflow ایجاد نمی‌کند (10ms → ~0ms)
- ✅ کاهش **85-95%** در forced reflow time (61ms → **~3-8ms**)
- ✅ تمام scripts از native methods override شده استفاده می‌کنند
- ✅ circular problem حل شد

#### 🚀 بهینه‌سازی Real-Time بروزرسانی قیمت‌ها
- **حذف تاخیرها:**
  - حذف `idleTimeout: 5000` و `fallbackDelay: 3000` از config
  - حذف کامل متد `scheduleCheck()` و تمام تاخیرهای مصنوعی
  - چک فوری قیمت‌ها به محض باز شدن صفحه (0ms بجای 3000-5000ms)

- **کاهش Cache TTL:**
  - Frontend: کاهش `cacheExpirySeconds` از 60 به 5 ثانیه
  - Backend: کاهش `$cache_ttl` از 15 به 5 ثانیه
  - بروزرسانی قیمت‌ها هر 5 ثانیه بجای 60 ثانیه

- **افزودن Cache-Busting:**
  - افزودن پارامتر timestamp (`?t=${Date.now()}`) به URL های چک
  - جلوگیری از کش CDN (Arvan) برای داده‌های قیمت
  - اطمینان از دریافت همیشگی آخرین قیمت‌ها

- **بهبود ساختار:**
  - اجرای فوری `checkSymbol()` در `init()` بجای `scheduleCheck()`
  - حفظ ساختار ماژولار IIFE
  - عملیات async غیرمسدودکننده با catch handlers

- **فایل‌های تغییر یافته:**
  - `assets/js/symbol-updater.js`: حذف تاخیرها و کاهش cache TTL
  - `app/Controllers/ApiController.php`: کاهش cache TTL در `updateSymbolData()`

- **مزایا:**
  - ✅ بروزرسانی فوری قیمت‌ها (بدون تاخیر 3-5 ثانیه‌ای)
  - ✅ داده‌های fresh هر 5 ثانیه
  - ✅ عدم استفاده از cache های قدیمی CDN
  - ✅ حفظ ساختار ماژولار و تمیز کد
  - ✅ عدم کاهش سرعت صفحه

#### 📚 مستندات جدید
- **PRICE-UPDATE-API.md**: مستندات جامع سیستم بروزرسانی قیمت‌ها (700+ خط)
- **FORCED-REFLOW.md v2.0**: بروزرسانی مستندات با رفع مشکل app-vendor

---

## [2.3.0] - 2025-12-21

### ✨ ویژگی‌های جدید (Features)

#### 🔄 کنترل Cache Version Redirect
- **افزودن گزینه جدید** برای کنترل نحوه reload صفحه هنگام تغییر ورژن
  - گزینه `enable_cache_version_redirect` در تنظیمات PageSpeed
  - دو حالت: با query string یا silent reload
  - پیش‌فرض: فعال (با query string)

- **حالت فعال (با Query String):**
  - هنگام تغییر ورژن: `/?_v=5.5.14&_t=timestamp`
  - تضمین دریافت asset های جدید
  - مناسب برای Production با CDN
  - URL بلافاصله بعد از reload تمیز می‌شود

- **حالت غیرفعال (Silent Reload):**
  - بدون تغییر URL
  - `location.reload(true)` ساده
  - تجربه کاربری بهتر
  - مناسب برای Development

- **مستندات کامل:**
  - فایل `docs/CACHE-VERSION-REDIRECT.md` اضافه شد
  - شامل فلوچارت، use cases، و troubleshooting
  - توضیحات فارسی و انگلیسی

#### 🎛️ سیستم کنترل PageSpeed Optimizations
- **افزودن Master Switch** برای فعال/غیرفعال کردن تمام بهینه‌سازی‌های PageSpeed
  - گزینه `enable_optimizations` در تنظیمات PageSpeed
  - امکان غیرفعال کردن کامل بهینه‌سازی‌ها با یک کلیک
  - UI آبی رنگ برای سوئیچ اصلی در صفحه تنظیمات

- **کنترل Third-Party Scripts**
  - گزینه `enable_third_party_scripts` برای مدیریت اسکریپت‌های tracking
  - قابلیت غیرفعال کردن Google Tag Manager، Najva، و Mediaad
  - بهینه‌سازی مستقل از سایر optimizations

- **بهبود تجربه کاربری**
  - توضیحات فارسی کامل برای هر گزینه
  - طراحی بصری بهتر برای گزینه‌های مهم
  - جداسازی واضح بین گزینه‌های مختلف

### 🐛 رفع مشکلات (Bug Fixes)

#### 🔄 رفع مشکل Cache Version Check Loop
- **مشکل:** پارامترهای `?_v=X.X.X&_t=timestamp` در هر رفرش صفحه نمایش داده می‌شد
- **علت:** بعد از redirect با query string، کد دوباره ورژن را چک می‌کرد و مجدد redirect انجام می‌داد
- **راه‌حل:**
  - تشخیص اتوماتیک query parameters مربوط به cache bust
  - پاک کردن خودکار URL با `history.replaceState()` بعد از reload
  - جلوگیری از چک مجدد ورژن بعد از اولین redirect
- **نتیجه:** 
  - URL تمیز بعد از رفرش صفحه
  - عدم نمایش مجدد پارامترهای cache bust
  - اجرای یکباره فرآیند clear cache در زمان تغییر ورژن

#### 📱 رفع مشکل نمایش بنر GIF در iOS
- **مشکل:** بنر GIF موبایل در گوشی‌های آیفون نمایش داده نمی‌شد
- **علت:** کلاس CSS `mobile none` باعث `display: none` در iOS می‌شد
- **راه‌حل:**
  - حذف کلاس `none` از تگ `<img>`
  - افزودن `<source>` tag برای GIF format fallback
  - اضافه کردن inline styles برای اطمینان از نمایش صحیح
  - بهبود سازگاری با مرورگرهای iOS قدیمی‌تر
- **نتیجه:** نمایش صحیح بنر در تمام دستگاه‌های iOS

### 🔧 بهبودها (Improvements)

#### 📋 بهبود سیستم مدیریت تنظیمات
- **PageSpeedAdmin.php:**
  - افزودن فیلدهای جدید به سیستم ذخیره‌سازی
  - بهبود مقادیر پیش‌فرض
  - اضافه کردن validation برای تنظیمات جدید

- **PageSpeedController.php:**
  - چک کردن `enable_optimizations` قبل از اجرای هر optimization
  - بهینه‌سازی منطق تصمیم‌گیری برای hooks
  - کاهش overhead در صورت غیرفعال بودن optimizations

- **header.php:**
  - دریافت تنظیمات PageSpeed در ابتدای فایل
  - شرطی کردن بارگذاری third-party scripts
  - بهبود سازگاری با تنظیمات مختلف

---

## [2.2.0] - 2025-12-08

### ⚡ بهینه‌سازی عملکرد (Performance)

#### 🎯 رفع کامل Forced Reflow در صفحات Coin
- **مشکل:** PageSpeed Insights 373ms forced reflow گزارش می‌کرد
- **راه‌حل:**
  - پیاده‌سازی `reflow-fix.js` - سیستم جامع DOMQueue
  - Cache کردن scroll position برای جلوگیری از repeated reads
  - Batch کردن تمام DOM reads و writes
  - استفاده از IntersectionObserver به جای manual scroll checking
- **نتیجه:** کاهش 97% زمان forced reflow (373ms → <10ms)

#### 📦 ماژول `reflow-fix.js` (Core Performance Module)
**ویژگی‌های اصلی:**

- `window.DOMQueue` - صف بهینه برای batch operations
  - `DOMQueue.read()` - جمع‌آوری تمام DOM reads
  - `DOMQueue.write()` - اعمال تمام DOM writes
  - Automatic scheduling با requestAnimationFrame

- `window.getScrollPositionSafe()` - دریافت scroll بدون reflow
  - Cache شده per-frame
  - Auto-update با passive listeners
  - صفر overhead برای multiple calls

- `window.getDimensionsSafe(element)` - همه dimensions با یک read
  - Width, height, client, scroll dimensions
  - Cache تا آخر frame
  - Perfect برای responsive calculations

- `element.getBoundingClientRectCached()` - cached rect queries
  - Override بهینه شده getBoundingClientRect
  - WeakMap caching
  - Frame-based invalidation

- `window.isElementVisibleSafe(element)` - visibility بدون reflow
  - استفاده از IntersectionObserver
  - هیچ getBoundingClientRect ندارد
  - Auto-observes و caches results

- Helper functions:
  - `animateElementSafe()` - animations بدون reflow
  - `setStylesSafe()` - batch style changes
  - jQuery integration برای سازگاری

#### 🔧 بهینه‌سازی `custom-coins.js`
- Refactor تمام scroll handlers با `getScrollPositionSafe()`
- Batch کردن TOC scroll operations با DOMQueue
- بهینه‌سازی gift box scrolling
- جداسازی کامل read/write operations

#### 📊 نتایج Benchmark

**قبل:**

[unattributed] 155 ms ⛔ /coin/uvoucher/:1456 92 ms ⛔ /coin/uvoucher/:1457 92 ms ⛔ custom-coins.js 2 ms app-vendor.js 32 ms ───────────────────────── مجموع: 373 ms ⛔


**بعد:**

reflow-fix.js 0 ms ✅ custom-coins.js 0 ms ✅ app-vendor.js ~5 ms ✅ ───────────────────────── مجموع: < 10 ms 🎉


#### 🌐 بهینه‌سازی CDN Cache Lifetime
- **مشکل:** PageSpeed هشدار "Use efficient cache lifetimes" می‌داد
  - فایل‌های CDN فقط 7 روز cache می‌شدند
  - Estimated savings: 38 KiB
- **راه‌حل:**
  - ایجاد فایل `.htaccess` اختصاصی برای CDN
  - تنظیم Cache-Control: `max-age=31536000` (1 سال)
  - اضافه کردن `immutable` directive برای فایل‌های استاتیک
  - پیکربندی CORS headers برای cross-origin requests
- **فایل‌های تأثیرگذار:**
  - تصاویر: jpg, jpeg, png, gif, webp, svg, ico
  - فونت‌ها: woff, woff2, ttf, eot, otf
  - CSS/JS: با Vary: Accept-Encoding
  - مدیا: mp4, webm, ogg, mp3, pdf
- **نتیجه:** 
  - ✅ حذف کامل PageSpeed warning
  - ✅ کاهش بار سرور و CDN
  - ✅ بهبود سرعت برای بازدیدکنندگان تکراری
  - ✅ بهبود امتیاز PageSpeed: +3 تا +5
- **مستندات:** مراجعه کنید به `docs/CDN-CACHE-OPTIMIZATION.md`

#### ⚡ بهینه‌سازی JavaScript Execution Time
- **مشکل:** PageSpeed هشدار "Reduce JavaScript execution time: 2.1s"
  - `app-vendor.js` خیلی سنگین: 1.25 MB (1,497ms CPU time)
  - همه کتابخانه‌ها در یک فایل: React, Highcharts, moment, axios
  - Main-thread blocking برای مدت طولانی
- **راه‌حل:**
  - **Code Splitting**: تقسیم به 8 bundle جداگانه
    - `runtime.js` (3.32 KB) - webpack runtime
    - `app-react.js` (133 KB) - React + ReactDOM
    - `app-highcharts.js` (726 KB) - Highcharts
    - `app-datetime.js` (308 KB) - moment + dayjs
    - `app-vendor.js` (118 KB) - بقیه vendorها
    - `app-chart.js` (29 KB)
    - `app-calculator.js` (21 KB)
    - `app-coins.js` (1.5 KB)
  - **TerserPlugin**: minification پیشرفته
    - حذف console.log در production
    - حذف کدهای غیرفعال (dead code)
    - حذف کامنت‌ها
    - Parallel processing با multi-core
  - **Webpack Optimization**:
    - Tree shaking برای حذف کدهای استفاده نشده
    - Priority-based cacheGroups
    - Runtime chunk جداگانه
- **فایل‌های تغییریافته:**
  - `webpack.config.js` - افزودن TerserPlugin و splitChunks پیشرفته
  - `app/Support/Assets.php` - بروزرسانی enqueue با dependencies صحیح
  - `app/Admin/PageSpeedController.php` - بروزرسانی defer_scripts
- **نتیجه:**
  - ✅ کاهش 45% در JS execution time (2,743ms → ~1,500ms)
  - ✅ کاهش 60% در parse time برای vendor bundle
  - ✅ Parallel loading فایل‌ها توسط مرورگر
  - ✅ بهبود browser cache (تغییر یک کتابخانه بقیه را invalidate نمی‌کند)
  - ✅ کاهش main-thread blocking
- **مستندات:** مراجعه کنید به `docs/JS-EXECUTION-OPTIMIZATION.md`

#### 📦 بهینه‌سازی Unused JavaScript (Tree Shaking)
- **مشکل:** PageSpeed هشدار "Reduce unused JavaScript: 271 KiB"
  - `app-highcharts.js`: 157 KB unused (69% استفاده نشده)
  - `app-datetime.js`: 57.5 KB unused (moment-jalaali سنگین)
  - `swiper.js`: 22.6 KB unused
- **راه‌حل:**
  - **Dynamic Import Highcharts**:
    - Lazy load با `import()` به جای static import
    - فقط زمانی بارگذاری می‌شود که نمودار نمایش داده شود
    - Chunk‌های جداگانه: core, react, boost
  - **جایگزینی moment-jalaali با dayjs + jalaliday**:
    - moment-jalaali: ~300 KB
    - dayjs + jalaliday: ~15 KB (✅ 95% کاهش)
  - **Webpack Tree Shaking**:
    - `sideEffects: false` در package.json
    - `usedExports: true` در webpack.config
    - Terser passes: 2 برای compression بهتر
- **فایل‌های تغییریافته:**
  - `src/components/CoinChart.jsx` - dynamic import Highcharts, dayjs
  - `webpack.config.js` - tree shaking فعال
  - `package.json` - sideEffects: false, jalaliday اضافه شد
- **نتیجه:**
  - ✅ کاهش ~60% unused code در Highcharts
  - ✅ حذف app-datetime.js (285 KB کاهش)
  - ✅ dayjs: 15 KB vs moment: 300 KB
  - ✅ Lazy loading: chart فقط وقتی لازم است load می‌شود
- **مستندات:** مراجعه کنید به `docs/JS-EXECUTION-OPTIMIZATION.md`

#### 🗺️ رفع Source Maps برای Webpack Bundles
- **مشکل:** PageSpeed warning "Missing source maps for large JavaScript"
  - فایل‌های `.map` در deploy exclude شده بودند
  - SyntaxError: Unexpected token '<' در source maps
  - 404 errors برای تمام `.v5.5.x.js.map` فایل‌ها
- **راه‌حل:**
  - بروزرسانی `create-versioned-sourcemaps.js` برای شامل شدن همه bundle ها:
    - runtime, app-react, app-highcharts, app-datetime, app-vendor
    - app-calculator, app-chart, app-coins
  - بروزرسانی `.github/workflows/deploy.yml`:
    - حذف `assets/js/*.map` از exclude list
    - فقط base files (non-versioned) exclude می‌شوند
    - Versioned files با `.v5.5.x.js.map` deploy می‌شوند
- **فایل‌های تغییریافته:**
  - `create-versioned-sourcemaps.js` - لیست فایل‌ها به 8 bundle افزایش یافت
  - `.github/workflows/deploy.yml` - exclude pattern بهینه شد
- **نتیجه:**
  - ✅ تمام source maps در production در دسترس هستند
  - ✅ Browser DevTools می‌تواند کد اصلی را نمایش دهد
  - ✅ Debugging در production راحت‌تر شد
  - ✅ PageSpeed warning برطرف شد

#### 🔄 اتوماسیون Source Maps در AssetVersionManager
- **مشکل:** source map ها باید به صورت دستی توسط اسکریپت ساخته شوند
- **راه‌حل:**
  - اضافه شدن متد `createVersionedSourceMap()` به `AssetVersionManager.php`:
    - هنگام ساخت فایل JS ورژن‌دار، source map هم خودکار ساخته می‌شود
    - کپی فایل `.js.map` → `.v5.5.8.js.map`
    - به‌روزرسانی خودکار `sourceMappingURL` در فایل JS
  - به‌روزرسانی `BrowserCacheAdmin::regenerateVersionedSourceMaps()`:
    - لیست webpack bundles از 4 به 8 افزایش یافت
    - همگام با تغییرات code splitting
- **چرخه کار:**

کاربر صفحه را باز می‌کند ↓ AssetVersionManager ورژن را از .env می‌خواند (مثلا 5.5.8) ↓ بررسی: app-vendor.v5.5.8.js وجود دارد? ↓ اگر نه → فایل‌های ورژن‌دار + source map ساخته می‌شوند ↓ ادمین روی “Clear Browser Cache” کلیک می‌کند ↓ BrowserCacheAdmin ورژن را افزایش می‌دهد: 5.5.8 → 5.5.9 ↓ فایل‌های قدیمی پاک + فایل‌های جدید با source maps ساخته می‌شوند ```

بهبود: 97% کاهش (363ms صرفه‌جویی)

📚 مستندات

🔧 بهبودها

Load Priority


[2.1.0] - 2025-12-07

✨ ویژگی‌های جدید

🗺️ Source Maps برای Webpack

🔔 بهینه‌سازی Najva Notifications

🔧 بهبودها

Security

Performance

Images & Assets

🐛 رفع باگ‌ها

Error Handling

🔄 CI/CD

Developer Experience

📚 مستندات


[2.0.0] - 2025-11-01

✨ ویژگی‌های جدید

🏗️ معماری MVC

🔄 سیستم Routing

📁 ساختار فایل‌ها

🚀 بهینه‌سازی‌های PageSpeed

Critical Path Optimization

JavaScript Optimization

YouTube Embed Optimization

CSS Optimization

🔧 بهبودهای SEO

Rank Math Integration

Redirects و URL Management

🌍 GeoLocation

IP-based Location Detection

📚 مستندات

راهنماهای توسعه

🔄 GitHub Actions

CI/CD Pipeline


[1.0.0] - 2025-10-15

✨ نسخه اولیه

ویژگی‌های اصلی


راهنمای نگارش Changelog

انواع تغییرات


نگهداری شده توسط: تیم توسعه XPay
آخرین به‌روزرسانی: 2025-12-07