前言

修改博客时觉得主页大图加载太慢,而且为了加载快一点已经把图片弄得很糊了,效果还是不好
正好发现了这位大佬的文章,首页背景图渐进式加载,解决卡顿难题
正好解决了加载过慢和图片不能太清晰的问题
但夜间模式下的深色遮罩又没了,
所以分享一下解决方法
安知鱼和butterfly主题适用

首页背景图渐进式加载(转载)

新建文件

新建文件source/js/imgloaded.js新增以下内容,并按照注释调整图片路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// 首页头图加载优化
/**
* @description 实现medium的渐进加载背景的效果
*/
class ProgressiveLoad {
constructor(smallSrc, largeSrc) {
this.smallSrc = smallSrc;
this.largeSrc = largeSrc;
this.initTpl();
}

/**
* @description 生成ui模板
*/
initTpl() {
this.container = document.createElement('div');
this.smallStage = document.createElement('div');
this.largeStage = document.createElement('div');
this.smallImg = new Image();
this.largeImg = new Image();
this.container.className = 'pl-container';
this.smallStage.className = 'pl-img pl-blur';
this.largeStage.className = 'pl-img';
this.container.appendChild(this.smallStage);
this.container.appendChild(this.largeStage);
this.smallImg.onload = this._onSmallLoaded.bind(this);
this.largeImg.onload = this._onLargeLoaded.bind(this);
}

/**
* @description 加载背景
*/
progressiveLoad() {
this.smallImg.src = this.smallSrc;
this.largeImg.src = this.largeSrc;
}

/**
* @description 大图加载完成
*/
_onLargeLoaded() {
this.largeStage.classList.add('pl-visible');
this.largeStage.style.backgroundImage = `url('${this.largeSrc}')`;
}

/**
* @description 小图加载完成
*/
_onSmallLoaded() {
this.smallStage.classList.add('pl-visible');
this.smallStage.style.backgroundImage = `url('${this.smallSrc}')`;
}
}

const executeLoad = (config, target) => {
console.log('执行渐进背景替换');
const isMobile = window.matchMedia('(max-width: 767px)').matches;
const loader = new ProgressiveLoad(
isMobile ? config.mobileSmallSrc : config.smallSrc,
isMobile ? config.mobileLargeSrc : config.largeSrc
);
// 和背景图颜色保持一致,防止高斯模糊后差异较大
if (target.children[0]) {
target.insertBefore(loader.container, target.children[0]);
}
loader.progressiveLoad();
};

const config = {
smallSrc: '/img/xiaotu.jpg', // 小图链接 尽可能配置小于100k的图片
largeSrc: '/img/tu.jpg', // 大图链接 最终显示的图片
mobileSmallSrc: '/img/sjxt.jpg', // 手机端小图链接 尽可能配置小于100k的图片
mobileLargeSrc: '/img/sjdt.jpg', // 手机端大图链接 最终显示的图片
enableRoutes: ['/'],
};

function initProgressiveLoad(config) {
const target = document.getElementById('page-header');
if (target && target.classList.contains('full_page')) {
executeLoad(config, target);
}
}

function onPJAXComplete(config) {
const target = document.getElementById('page-header');
if (target && target.classList.contains('full_page')) {
initProgressiveLoad(config);
}
}

document.addEventListener("DOMContentLoaded", function() {
initProgressiveLoad(config);
});

document.addEventListener("pjax:complete", function() {
onPJAXComplete(config);
});

新建文件source/css/imgloaded.css新增以下内容,并按照注释自行决定调整内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/* 首页头图加载 */
.pl-container {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
will-change: transform; /* 添加性能优化 */
animation: blur-to-clear 2s cubic-bezier(.62,.21,.25,1) 0s 1 normal backwards running, scale 1.5s cubic-bezier(.62,.21,.25,1) 0s 1 both;
}
.pl-img {
width: 100%;
height: 100%;
position: absolute;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 1s;
}

@keyframes blur-to-clear {
0% {
filter: blur(50px);
opacity: 1;
}
100% {
filter: blur(0);
opacity: 1;
}
}

@keyframes scale {
0% {
transform: scale(1.5) translateZ(0);
opacity: 0;
}
to {
transform: scale(1) translateZ(0);
opacity: 1;
}
}

.pl-visible {
opacity: 1;
}

.pl-blur {
/* 小图锯齿多,增加高斯模糊 */
filter: blur(50px);
}

引入文件

在inject里引入即可

1
2
3
4
5
6
7
inject:
head:
- <link rel="stylesheet" href="/css/imgloaded.css?1">

bottom:
- <script async data-pjax src="/js/imgloaded.js?1"></script> # 首页图片渐进式加载

夜间模式深色遮罩

也很简单,在css里加入这一段即可

1
2
3
4
5
6
7
8
9
10
11
/* 深色模式遮罩 */
[data-theme="dark"] .pl-container::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3); /* 30%透明度的黑色遮罩 */
z-index: 1;
}

回到终端,执行hexo三连就完成了!