前言

我的服务器带宽比较高,博客部署在上面访问的时候几乎没感觉有加载延迟,就没做图片这块的优化,不过最近有小伙伴说博客的图片加载比较慢,那就来把图片优化完善一下吧~

目前有两个地方需要完善

  • 图片瀑布流
  • 图片缩略图

图片瀑布流

关于瀑布流之前的文章有介绍: 基于.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 呀,这个功能缺失真的太难受了,只能期待它早日实现这个功能吧~

不然就只能我自己来实现缓存功能提高性能了~

系列文章

参考资料

基于.NetCore开发博客项目 StarBlog - (20) 图片显示优化的更多相关文章

  1. 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  2. 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  3. 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  4. 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  5. 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  6. 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  7. 基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  8. 基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  9. 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  10. 基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传

    前言 九月太忙,只更新了三篇文章,本来这个功能是从九月初就开始做的,结果一直拖到现在国庆假期才有时间完善并且写文章~ 之前我更新了几篇关于 Python 的文章,有朋友留言问是不是不更新 .Net 了 ...

随机推荐

  1. 利用 Gitea Doctor自助诊断工具帮助管理员排查问题

    ​我常常在Gitea论坛或者Hostea为网友解答Gitea版本升级方面的问题,但发现少有人知道利用 gitea doctor 命令行工具排查问题,因此这篇博文将给大家带来通俗易懂的介绍. 你知道吗? ...

  2. 如何在JavaScript中使用高阶函数

    将另一个函数作为参数的函数,或者定义一个函数作为返回值的函数,被称为高阶函数. JavaScript可以接受高阶函数.这种处理高阶函数的能力以及其他特点,使JavaScript成为非常适合函数式编程的 ...

  3. Java中关键的知识点

    JVM,运行是内存模型 Java 反射 Java 注解 函数式接口 lambda表达式/流式计算 动态代理

  4. ProxySQL SQL 注入引擎

    ProxySQL 2.0.9 引入了 libsqlinjection 作为识别可能的 SQL 注入攻击的机制. 启用 S​​QL 注入检测 要启用 SQL 注入检测,只需要启用变量 mysql-aut ...

  5. Traefik2.3.x 使用大全(更新版)

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247488793&idx=1&sn=bb2b0ad1 ...

  6. win10系统恢复默认的照片查看器

    新建一个TXT文本文档,把以下代码复制粘贴到其中: 注:你可以根据需要按同样的格式增减或修改其中的图片格式代码 Windows Registry Editor Version 5.00 ; Chang ...

  7. 秋初 WAMP 集成环境 v2.1

    基于QT的PHP集成开发环境v2.1 https://gitee.com/xiaqiuchu/wamp-integrated-environment 界面预览 已实现功能 服务的启动.关闭.重启. p ...

  8. 多云容器编排 Karmada-Operator 实践

    作者:vivo 互联网服务器团队-Zhang Rong Karmada作为开源的云原生多云容器编排项目,吸引了众多企业共同参与项目开发,并运行于生产环境中.同时多云也逐步成为数据中心建设的基础架构,多 ...

  9. Java开发学习(三十七)----SpringBoot多环境配置及配置文件分类

    一.多环境配置 在工作中,对于开发环境.测试环境.生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要该配 ...

  10. Hbase之API基本操作

    API之框架 private static Admin admin = null; private static Connection connection = null; private stati ...