<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>

Loading

基于.NetCore開發博客項目 StarBlog - (20) 圖片顯示優化

前言

我的服務器帶寬比較高,博客部署在上面訪問的時候幾乎沒感覺有加載延遲,就沒做圖片這塊的優化,不過最近有小伙伴說博客的圖片加載比較慢,那就來把圖片優化完善一下吧~

目前有兩個地方需要完善

  • 圖片瀑布流
  • 圖片縮略圖

圖片瀑布流

關于瀑布流之前的文章有介紹: 基于.NetCore開發博客項目 StarBlog - (10) 圖片瀑布流

不過當時直接套用的 Bootstrap5 例子代碼,有偶爾顯示錯位的bug

我又去看了一下 masonry-layout 的官網,找到這個bug的原因:瀑布流在圖片還沒加載完成就渲染好了,而圖片的大小不一,造成了最終顯示錯位。

解決方法也很簡單,用 imagesLoaded 這個庫,它有個事件,在全部圖片加載完成后觸發,在事件響應里面再渲染一次瀑布流,就搞定了~

masonry-layout 這個庫里面不附帶 imagesLoaded ,要用必須自己安裝。

我用的版本是 5.0.0

yarn add imagesloaded

StarBlog.Webgulpfile.js 里配置一下路徑

// 使用 npm 下載的前端組件,自定義存放位置
const customLibs = [
  // ...
  {name: 'imagesloaded', dist: './node_modules/imagesloaded/*.js'},
]

然后執行 gulp move

接著,修改一下圖片頁面 StarBlog.Web/Views/Photography/Index.cshtml

引入 js 依賴,我這里還用了 environment tag helper,可以根據不同的環境引入不同的文件。在開發環境引入完整 js 文件,生產環境引入 ``*.min` 文件。

@section bottom {
    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/masonry-layout/dist/masonry.pkgd.js"></script>
        <script src="~/lib/imagesloaded/imagesloaded.pkgd.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script src="~/lib/masonry-layout/dist/masonry.pkgd.min.js"></script>
        <script src="~/lib/imagesloaded/imagesloaded.pkgd.min.js"></script>
    </environment>
    <script src="~/js/photo.js"></script>
}

把圖片列表部分的代碼改一下

<div id="photo-grid" class="row">
  @foreach (var photo in Model.Photos) {
    <div class="col-sm-6 col-lg-4 mb-4 grid-item">
      <partial name="Widgets/PhotoCard" model="photo"/>
    </div>
  }
</div>

然后是 js/photo.js里的 js 代碼

// init Masonry
let $grid = $('#photo-grid').masonry({
    itemSelector: '.grid-item',
    percentPosition: true,
})
// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
    $grid.masonry('layout');
});

搞定~

圖片縮略圖

一開始我用的是 SixLabors.ImageSharp.Web 這個庫

挺方便的,以中間件的形式使用

通過 Nuget 安裝之后,在 program.cs 里配置一下

// 注冊服務
builder.Services.AddImageSharp();
// 添加中間件
app.UseImageSharp();

之后就可以在任意圖片文件的地址后面加上 width=xxx&format=xxx 這樣的參數來實現調整大小和轉換格式了~

圖片列表的每個圖片我做成了一個 partial view 組件,在 StarBlog.Web/Views/Shared/Widgets/PhotoCard.cshtml 這個文件

要把這個改成縮略圖,只需要修改一下 img 元素

現在每個圖片縮略圖寬度300(寬度自適應),格式轉換成 webp

<img class="bd-placeholder-img card-img-top" src="/media/@Model.FilePath?width=300&format=webp" alt="">

這個中間件還有很多其他參數可以設置,我只用到兩個,詳情可以看文檔: https://docs.sixlabors.com/articles/imagesharp.web/processingcommands.html

Progressive JPEG

本來用 ImageSharp.Web 中間件已經夠好了

但還有一點美中不足,就是它不支持生成 progressive JPEG 圖片,這樣就沒辦法在加載圖片的時候先顯示一個模糊的輪廓,再逐漸變清晰,而是從上到下一行一行加載,不好看~

所以,我用了 Magick.NET 這個庫來實現生成 progressive JPEG 格式的圖片。

這個庫有三種版本:Q8, Q16, Q16-HDRI

根據官網文檔,我選擇了它推薦的 Q8 版本,性能最好 (圖片質量無所謂了)

使用 nuget 安裝 Magick.NET-Q8-AnyCPU 這個庫

修改 StarBlog.Web/Services/PhotoService.cs

現在我要來寫一個生成縮略圖的方法

/// <summary>
/// 生成Progressive JPEG縮略圖 (使用 MagickImage)
/// </summary>
public async Task<byte[]> GetThumb(string id, int width=300) {
  var photo = await _photoRepo.Where(a => a.Id == id).FirstAsync();
  using (var image = new MagickImage(GetPhotoFilePath(photo))) {
    image.Format = MagickFormat.Pjpeg;
    image.Resize(width,0);
    return image.ToByteArray();
  }
}

接著再寫個接口

編輯 StarBlog.Web/Apis/PhotoController.cs

[HttpGet("{id}/Thumb")]
public async Task<IActionResult> GetThumb(string id, [FromQuery] int width = 300) {
  var data = await _photoService.GetThumb(id, width);
  return new FileContentResult(data, "image/jpeg");
}

搞定。

現在只需要訪問 /Api/Photo/{圖片ID}/Thumb?width=300 這個地址,就可以生成 progressive JPEG 格式的縮略圖了~

最后再來改造一下 StarBlog.Web/Views/Shared/Widgets/PhotoCard.cshtml 組件

<img class="bd-placeholder-img card-img-top" alt=""
         src="@Url.Action("GetThumb", "Photo", new {id = Model.Id, width = 300})">

okk~

小結

相比起 ImageSharp.Web 中間件自帶緩存的特性,我這個自己寫的縮略圖方法是比較粗糙的,而且每次請求都是動態生成,會給服務器帶來一定壓力。

不過它沒有 Progressive JPEG 呀,這個功能缺失真的太難受了,只能期待它早日實現這個功能吧~

不然就只能我自己來實現緩存功能提高性能了~

系列文章

參考資料

posted @ 2022-11-27 14:47  程序設計實驗室  閱讀(447)  評論(7編輯  收藏  舉報
人碰人摸人爱免费视频播放

<xmp id="63nn9"><video id="63nn9"></video></xmp>

<xmp id="63nn9"></xmp>

<wbr id="63nn9"><ins id="63nn9"></ins></wbr>

<wbr id="63nn9"></wbr><video id="63nn9"><ins id="63nn9"><table id="63nn9"></table></ins></video>