عنوان:

‫شناسایی تغییرات فایل‌ها و مدیریت کش در Blazor WebAssembly


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۱/۲۹ ۰۷:۴۶
آدرس: www.dntips.ir
مقدمه
Blazor WebAssembly (WASM) یکی از فناوری‌های نوین مایکروسافت برای توسعه برنامه‌های وب تک‌صفحه‌ای (Single-Page Applications یا SPA) است که امکان اجرای کدهای .NET را مستقیماً در مرورگر فراهم می‌کند. این فناوری با استفاده از WebAssembly، عملکردی نزدیک به برنامه‌های بومی ارائه می‌دهد. یکی از چالش‌های کلیدی در استقرار برنامه‌های Blazor WASM، مدیریت کش (Caching) فایل‌های برنامه و اطمینان از بارگذاری نسخه‌های به‌روز آن‌ها در مرورگر است. Blazor WASM از مکانیزم‌های خاصی برای شناسایی تغییرات فایل‌ها و جلوگیری از استفاده از فایل‌های کش‌شده قدیمی استفاده می‌کند. این مقاله به بررسی چگونگی تشخیص تغییرات فایل‌ها توسط Blazor WASM و مدیریت کش با تمرکز بر مکانیزم‌های بررسی یکپارچگی (Integrity Checking) و بارگذاری منابع اولیه (Boot Resources) می‌پردازد. هدف این است که توسعه‌دهندگان .NET درک عمیقی از این فرآیندها به دست آورند و بتوانند برنامه‌های خود را بهینه‌سازی کنند.

1. مفهوم کش و یکپارچگی فایل‌ها در Blazor WASM
Blazor WASM برای اجرای برنامه، مجموعه‌ای از فایل‌ها شامل فایل‌های .NET runtime، کتابخانه‌های .dll، فایل‌های WebAssembly (.wasm) و فایل‌های پیکربندی را به مرورگر بارگذاری می‌کند. این فایل‌ها به دلیل حجم نسبتاً زیادشان، معمولاً در مرورگر کش می‌شوند تا بارگذاری‌های بعدی سریع‌تر انجام شوند. با این حال، اگر فایل‌های کش‌شده قدیمی باشند و با نسخه جدید برنامه همخوانی نداشته باشند، ممکن است خطاهایی در اجرای برنامه رخ دهد. برای جلوگیری از این مشکل، Blazor WASM از مکانیزم بررسی یکپارچگی فایل‌ها استفاده می‌کند.
فایل blazor.boot.json نقش مرکزی در این فرآیند دارد. این فایل یک مانیفست (Manifest) است که فهرستی از تمام فایل‌های مورد نیاز برنامه به همراه مقادیر هش (Hash) SHA-256 آن‌ها را شامل می‌شود. این هش‌ها به‌عنوان امضایی برای شناسایی محتوای فایل‌ها عمل می‌کنند. هنگامی که برنامه در مرورگر بارگذاری می‌شود، Blazor هش فایل‌های کش‌شده یا دانلودشده را با مقادیر موجود در blazor.boot.json مقایسه می‌کند. اگر این مقادیر مطابقت نداشته باشند، مرورگر فایل را از سرور درخواست می‌کند و از استفاده از نسخه کش‌شده جلوگیری می‌شود. این فرآیند تضمین می‌کند که همیشه نسخه‌های به‌روز فایل‌ها بارگذاری شوند.
در صورت عدم تطابق هش‌ها، خطایی مشابه زیر در کنسول توسعه‌دهنده مرورگر نمایش داده می‌شود:
Failed to find a valid digest in the 'integrity' attribute for resource
'https://myapp.example.com/_framework/MyBlazorApp.dll' with computed 
SHA-256 integrity 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY='. 
The resource has been blocked.
این خطا معمولاً نشان‌دهنده مشکلی در سرور یا فرآیند استقرار است، نه نقص در خود مکانیزم بررسی یکپارچگی.

متوجه شدن تغییرات و نگارش جدید در Blazor WASM و مدیریت کش:
تشخیص تغییرات و دریافت نگارش جدید:
Blazor WASM یک مانیفست بوت (blazor.boot.json) دارد که شامل لیستی از تمام فایل‌های مورد نیاز برنامه به همراه هش محتوای آن‌ها است. هر بار که برنامه اجرا می‌شود، Blazor WASM هش فایل‌های موجود در حافظه کش مرورگر را با هش‌های موجود در مانیفست بوت مقایسه می‌کند. اگر هش فایلی در حافظه کش با هش موجود در مانیفست متفاوت باشد، Blazor WASM تشخیص می‌دهد که فایل تغییر کرده است و نگارش جدید آن را از سرور دانلود می‌کند.

مدیریت کش و غیرمعتبر کردن آن:
Blazor WASM به طور پیش‌فرض از API حافظه کش مرورگر برای ذخیره فایل‌های دانلود شده استفاده می‌کند. هنگام دانلود فایل‌ها، Blazor WASM به مرورگر دستور می‌دهد تا یکپارچگی پاسخ‌ها را بررسی کند. مقادیر هش SHA-256 را برای فایل‌های DLL، WebAssembly و سایر فایل‌ها در مانیفست بوت ارسال می‌کند. این مانیفست کش نمی‌شود. اگر هش فایل‌های کش شده با هش‌های موجود در مانیفست مطابقت داشته باشد، Blazor WASM از فایل‌های کش شده استفاده می‌کند. در غیر این صورت، فایل‌ها از سرور درخواست می‌شوند. پس از دانلود یک فایل جدید، هش آن مجدداً برای اطمینان از یکپارچگی بررسی می‌شود.

نقش فایل blazor.boot.json در Blazor WebAssembly
فایل blazor.boot.json قلب فرآیند بوت‌استرپ (Bootstrap) در Blazor WebAssembly است. این فایل JSON حاوی اطلاعاتی درباره منابع موردنیاز برای اجرای برنامه، از جمله مجموعه‌های .NET (Assemblies)، فایل‌های جاوااسکریپت، فایل‌های runtime و وابستگی‌های دیگر است. ساختار این فایل به Blazor کمک می‌کند تا منابع را به‌صورت کارآمد بارگیری کند و از سازگاری نسخه‌ها اطمینان حاصل شود.

ساختار فایل blazor.boot.json
یک نمونه ساده از فایل blazor.boot.json به‌صورت زیر است:
{
  "cacheBootResources": true,
  "config": [ "appsettings.json" ],
  "entryAssembly": "MyApp",
  "resources": {
    "assembly": {
      "MyApp.dll": "sha256-abc123...",
      "System.Text.Json.dll": "sha256-xyz789..."
    },
    "runtime": {
      "dotnet.wasm": "sha256-def456..."
    },
    "js": {
      "blazor.webassembly.js": "sha256-ghi789..."
    }
  }
}
  • cacheBootResources: مشخص می‌کند که آیا منابع در مرورگر کش شوند یا خیر.
  • config: فایل‌های تنظیمات برنامه مانند appsettings.json را فهرست می‌کند.
  • entryAssembly: نام مجموعه اصلی برنامه را مشخص می‌کند.
  • resources: فهرستی از منابع موردنیاز، همراه با هش‌های SHA-256 برای اعتبارسنجی یکپارچگی فایل‌ها.

نقش هش فایل‌ها در blazor.boot.json
هش‌های SHA-256 در فایل blazor.boot.json برای هر منبع (مانند .dll یا .wasm) تضمین می‌کنند که مرورگر نسخه صحیح فایل را بارگیری کند. این هش‌ها به‌عنوان بخشی از مکانیزم Content-Based Addressing عمل می‌کنند، به این معنا که اگر محتوای فایل تغییر کند، هش آن نیز تغییر می‌کند و مرورگر مجبور به بارگیری نسخه جدید می‌شود. این رویکرد مشکلات مربوط به کش شدن نسخه‌های قدیمی را حل می‌کند.

2. فرآیند بارگذاری منابع اولیه (Boot Resources)
Blazor WASM از یک API به نام loadBootResource برای سفارشی‌سازی نحوه بارگذاری منابع اولیه استفاده می‌کند. این API امکان کنترل دقیق بر فرآیند بارگذاری فایل‌ها را فراهم می‌کند و می‌تواند برای مدیریت کش و بهبود عملکرد برنامه مورد استفاده قرار گیرد. به‌طور پیش‌فرض، Blazor فایل‌های مورد نیاز را از سرور بارگذاری می‌کند، اما توسعه‌دهندگان می‌توانند این رفتار را تغییر دهند، مثلاً با استفاده از فایل‌های فشرده‌شده یا بارگذاری از یک شبکه تحویل محتوا (Content Delivery Network یا CDN).
یکی از روش‌های رایج برای بهینه‌سازی، استفاده از فایل‌های فشرده‌شده با الگوریتم Brotli است. در این حالت، Blazor می‌تواند فایل‌های فشرده‌شده را از سرور دریافت کرده و در مرورگر از حالت فشرده خارج کند. نمونه کد زیر نشان‌دهنده استفاده از loadBootResource برای بارگذاری فایل‌های فشرده‌شده با Brotli است:
<script type="module">
  import { BrotliDecode } from './decode.min.js';
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration' && type !== 'manifest') {
          return (async function () {
            const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
            if (!response.ok) {
              throw new Error(response.statusText);
            }
            const originalResponseBuffer = await response.arrayBuffer();
            const originalResponseArray = new Int8Array(originalResponseBuffer);
            const decompressedResponseArray = BrotliDecode(originalResponseArray);
            const contentType = type === 'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
            return new Response(decompressedResponseArray, {
              headers: { 'content-type': contentType }
            });
          })();
        }
      }
    }
  });
</script>
در این کد، فایل‌های غیرمرتبط با dotnetjs، configuration و manifest از سرور به‌صورت فشرده‌شده (.br) بارگذاری می‌شوند. گزینه cache: 'no-cache' تضمین می‌کند که مرورگر نسخه جدید فایل را از سرور درخواست کند، حتی اگر نسخه‌ای در کش موجود باشد. این روش به‌ویژه برای محیط‌های غیرمحلی (Non-Localhost) مفید است و از مشکلات مربوط به کش قدیمی جلوگیری می‌کند.

3. مدیریت خطاهای بررسی یکپارچگی
خطاهای بررسی یکپارچگی معمولاً به دلایل زیر رخ می‌دهند:
  • تغییر فایل‌ها پس از انتشار: اگر فایل‌های منتشرشده (مانند .dll یا .wasm) پس از فرآیند انتشار تغییر کنند، هش‌های آن‌ها با مقادیر موجود در blazor.boot.json مطابقت نخواهد داشت.
  • مشکلات استقرار: استقرار نادرست یا تغییرات محیطی در سرور ممکن است باعث شود فایل‌های نادرست به مرورگر ارسال شوند.
  • لایه‌های کش میانی: شبکه‌های تحویل محتوا (CDN) یا پراکسی‌ها ممکن است نسخه‌های قدیمی فایل‌ها را ارائه دهند.

برای تشخیص و رفع این خطاها، مایکروسافت اسکریپت PowerShell به نام integrity.ps1 را ارائه کرده است. این اسکریپت فایل‌های موجود در پوشه انتشار و فایل‌های دانلودشده از سرور را بررسی می‌کند تا مشکلات احتمالی در مانیفست‌های حاوی هش‌ها را شناسایی کند. توسعه‌دهندگان می‌توانند این اسکریپت را برای نسخه‌های PowerShell بالاتر از 7.2.0 سفارشی‌سازی کنند.
اگر نیاز به غیرفعال کردن بررسی یکپارچگی باشد (مثلاً در سناریوهای خاص توسعه)، می‌توان از تنظیم زیر در فایل پروژه (.csproj) استفاده کرد:
<PropertyGroup>
  <BlazorCacheBootResources>false</BlazorCacheBootResources>
</PropertyGroup>
این تنظیم بررسی یکپارچگی را غیرفعال می‌کند و رفتار پیش‌فرض کش کردن فایل‌های .dll و .wasm را تغییر می‌دهد. با این حال، این گزینه برای برنامه‌های پیش‌رونده وب (Progressive Web Apps یا PWA) توصیه نمی‌شود، زیرا ممکن است باعث مشکلات دیگری شود.

4. بهینه‌سازی کش و استقرار
برای بهینه‌سازی کش و جلوگیری از مشکلات، توسعه‌دهندگان می‌توانند اقدامات زیر را انجام دهند:
  • استفاده از Webcil: از .NET 8 به بعد، Blazor WASM از فرمت Webcil برای بسته‌بندی فایل‌های .NET به‌صورت .wasm استفاده می‌کند. این فرمت به بهبود عملکرد و کاهش اندازه فایل‌ها کمک می‌کند. برای غیرفعال کردن Webcil، می‌توان از تنظیم زیر استفاده کرد:
<PropertyGroup>
  <WasmEnableWebcil>false</WasmEnableWebcil>
</PropertyGroup>
  • تغییر پسوند فایل‌ها: در برخی موارد، تغییر پسوند فایل‌های .dll به .bin با استفاده از اسکریپت‌های PowerShell یا خطوط لوله DevOps می‌تواند مشکلات مربوط به محدودیت‌های سرور را حل کند.
  • پیکربندی سرور و CDN: اطمینان از تنظیم صحیح هدرهای کش مانند Cache-Control و ETag برای جلوگیری از ارائه نسخه‌های قدیمی فایل‌ها توسط سرور یا CDN.
5. نکات پیشرفته برای توسعه‌دهندگان
برای توسعه‌دهندگانی که به دنبال بهبود بیشتر هستند، استفاده از تکنیک‌های زیر توصیه می‌شود:
  • بارگذاری تنبل (Lazy Loading): Blazor WASM امکان بارگذاری تنبل مجموعه‌ها (Assemblies) را فراهم می‌کند تا فقط مجموعه‌های مورد نیاز در زمان درخواست بارگذاری شوند. این روش می‌تواند زمان بارگذاری اولیه را کاهش دهد.
  • استفاده از سرورهای استاتیک: در استقرار مستقل (Standalone Deployment)، فایل‌های Blazor WASM می‌توانند روی سرورهای استاتیک مانند Nginx یا Apache میزبانی شوند، که نیاز به سرور .NET را حذف می‌کند.
  • بررسی ابزارهای توسعه مرورگر: برای عیب‌یابی، استفاده از تب Network در ابزارهای توسعه مرورگر برای بررسی کدهای وضعیت HTTP (مانند 200، 403 یا 500) ضروری است.

نتیجه‌گیری
Blazor WebAssembly با استفاده از فایل blazor.boot.json و بررسی یکپارچگی مبتنی بر هش SHA-256، اطمینان می‌دهد که فایل‌های برنامه به‌روز باقی می‌مانند و از مشکلات کش قدیمی جلوگیری می‌شود. توسعه‌دهندگان می‌توانند با استفاده از API loadBootResource فرآیند بارگذاری را سفارشی‌سازی کنند و با ابزارهایی مانند اسکریپت integrity.ps1 خطاهای احتمالی را تشخیص دهند. رعایت نکاتی مانند پیکربندی صحیح سرور، استفاده از فشرده‌سازی Brotli، و بهینه‌سازی استقرار، به بهبود عملکرد و پایداری برنامه‌های Blazor WASM کمک می‌کند. با درک این مکانیزم‌ها، توسعه‌دهندگان .NET می‌توانند برنامه‌های وب قدرتمند و قابل اعتمادی را طراحی و مستقر کنند.


مشاهده مطلب اصلی