歡迎光臨
每天分享高質量文章

[小技巧]ASP.NET Core中如何預壓縮靜態檔案

原文地址:Pre-compressed static files with ASP.NET Core

作者:Gunnar Peipman

譯者:Lamond Lu

譯文:https://www.cnblogs.com/lwqlun/p/10552131.html

示例代碼:https://github.com/lamondlu/CompressedStaticFileSample

Web應用程式的優化是非常重要,因為使用更少的CPU,占用更少的帶寬可以減少專案的費用。 在ASP.NET Core中我們可以很容易的啟用響應壓縮,但是針對預壓縮檔案,就需要做一些額外的功能了。 這篇博客文章展示瞭如何在ASP.NET Core中預壓縮靜態檔案。

為什麼需要預壓縮檔案?

雖然在從服務器請求檔案時, 我們可以動態壓縮檔案,但這意味這Web服務器需要做更多的額外工作。 其實只有在新的應用程式部署時才會更改要壓縮的檔案。 越好的壓縮效果需要CPU做的工作就越多。

這個事實讓我們產生一個疑問:是否有可能在不對其進行反覆壓縮的情況下提供這些檔案? 幸運的是,這個問題答案是肯定的 – 是的,我們可以在ASP.NET Core中通過擴展靜態檔案中間件來做到這一點。

創建預壓縮檔案

為了讓整個演示儘量簡單,我們可以使用7-Zip來壓縮磁盤上的靜態檔案。 以下是壓縮預設ASP.NET Core MVC應用程式的site.css檔案時7-Zip的對話框視窗。

這裡你可能註意到我啟用了 Ultra壓縮。這顯然不是我們希望在Web服務器上動態壓縮的方法,因為它太消耗CPU了。

正常情況下,這裡可以使用Gulp來完成檔案捆綁和收縮的功能,本文中暫時不會介紹這個。

提供壓縮檔案

這裡我參考了Stack Overflow上的一個簡單解決方案(How to gzip static content in ASP.NET Core in a self host environment. )。它處理了Javascript和CSS檔案。

  1. app.UseStaticFiles(new StaticFileOptions
  2. {
  3. OnPrepareResponse = context =>
  4. {
  5. IHeaderDictionary essay-headers = context.Context.Response.Headers;
  6. string contentType = essay-headers["Content-Type"];
  7. if (contentType == "application/x-gzip")
  8. {
  9. if (context.File.Name.EndsWith("js.gz"))
  10. {
  11. contentType = "application/javascript";
  12. }
  13. else if (context.File.Name.EndsWith("css.gz"))
  14. {
  15. contentType = "text/css";
  16. }
  17. essay-headers.Add("Content-Encoding", "gzip");
  18. essay-headers["Content-Type"] = contentType;
  19. }
  20. }
  21. });

當然Javascript和CSS檔案並不是唯一需要壓縮的檔案型別。所以這裡我們不能把contentType寫死。這裡我採用了.NET Core Tutorials站點中提供的一個解決方案( Getting A Mime Type From A File Name In .NET Core)。對我來說這個方案已經足夠簡單。

  1. var provider = new FileExtensionContentTypeProvider();
  2. string contentType;
  3. if (!provider.TryGetContentType(fileName, out contentType))
  4. {
  5. contentType = "application/octet-stream";
  6. }

這裡我把2個方案合併在里一起,產生了最終解決方案。

  1. var mimeTypeProvider = new FileExtensionContentTypeProvider();
  2.  
  3. app.UseStaticFiles(new StaticFileOptions
  4. {
  5. OnPrepareResponse = context =>
  6. {
  7. var essay-headers = context.Context.Response.Headers;
  8. var contentType = essay-headers["Content-Type"];
  9.  
  10. if (contentType != "application/x-gzip" && !context.File.Name.EndsWith(".gz"))
  11. {
  12. return;
  13. }
  14.  
  15. var fileNameToTry = context.File.Name.Substring(0, context.File.Name.Length - 3);
  16.  
  17. if (mimeTypeProvider.TryGetContentType(fileNameToTry, out var mimeType))
  18. {
  19. essay-headers.Add("Content-Encoding", "gzip");
  20. essay-headers["Content-Type"] = mimeType;
  21. }
  22. }
  23. });

至此,使用以上的代碼,本文的主題就被解決了。

針對那些想直接使用現成庫的開發人員,可以使用Nuget直接下載Peter Andersson做好的中間件。

Install-Package CompressedStaticFiles -Version 1.0.4

總結

雖然使用預壓縮檔案不是Web開發的主流,但它仍然可以節省CPU和帶寬。 壓縮靜態檔案可以作為ASP.NET Core應用程式構建的一個步驟。 儘管ASP.NET Core開箱即不支持預壓縮檔案,但我們依然可以通過擴展靜態檔案中間件,使其支持預壓縮檔案。

 

    赞(0)

    分享創造快樂