Hexo+Github博客搭建之博客优化篇

图片懒加载

知识小课堂:图片加载方式有两种,一个是预加载,另一个就是懒加载,那你了解什么是预加载和懒加载吗?下面来学习一下。
参考:图片预加载与图片懒加载(缓载)的区别与实现

  • 图片预加载:顾名思义,图片预加载就是在网页全部加载之前,提前加载图片。当用户需要查看时可直接从本地缓存中渲染,以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,这样浏览者可能以为图片预览慢而没兴趣浏览,把网页关掉,这时,就需要图片预加载。当然这种做法实际上牺牲了服务器的性能换取了更好的用户体验。
  • 图片懒加载(缓载):延迟加载图片或符合某些条件时才加载某些图片。这样做的好处是减少不必要的访问数据库或延迟访问数据库的次数,因为每次访问数据库都是比较耗时的即只有真正使用该对象的数据时才会创建。懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

预加载与懒加载的区别之处:

两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预载则会增加服务器前端压力。


使用图片懒加载需要安装插件:链接如下:

在站点根目录执行下面的命令:

1
npm install hexo-lazyload-image --save

之后在站点配置文件下添加下面的代码:

1
2
3
4
lazyload:
enable: true # 是否开启图片懒加载
onlypost: false # 是否只对文章的图片做懒加载
loadingImg: # eg ./images/loading.gif

最后执行hexo clean && hexo g && hexo s就可以看到效果了。

注意,以下几个小问题针对matery主题而言,其他主题是否会出现以下情况目前我也不清楚,如果出现,你在尝试下以下解决方法。(暴力解决法,而不是直接修改懒加载插件😂😂😂)

  • 问题1:查看大图,发现全部为loading加载图,原因是因为懒加载插件与lightgallery插件冲突,解决办法如下:

修改主题文件下的matery.js,在108行左右添加以下代码:

1
2
3
$(document).find('img[data-original]').each(function(){
$(this).parent().attr("href", $(this).attr("data-original"));
});
  • 问题2:点击首页logo不是跳转到首页,而是查看logo图片,解决办法如下:

修改主题的header.ejs文件,原代码为:

1
2
3
4
5
6
7
8
<div class="brand-logo">
<a href="<%- url_for() %>" class="waves-effect waves-light">
<% if (theme.logo !== undefined && theme.logo.length > 0) { %>
<img src="<%= theme.logo %>" class="logo-img" alt="LOGO">
<% } %>
<span class="logo-span"><%- config.title %></span>
</a>
</div>

修改为:

1
2
3
4
5
6
7
8
9
10
<div class="brand-logo">
<a href="<%- url_for() %>" class="waves-effect waves-light">
<div>
<% if (theme.logo !== undefined && theme.logo.length > 0) { %>
<img src="<%= theme.logo %>" class="logo-img" alt="LOGO">
<% } %>
<span class="logo-span"><%- config.title %></span>
</div>
</a>
</div>

懒加载优化

经过以上操作就已经很完美了,以下内容可做可不做

  • 其实第一次加载后本地都是有缓存的,如果每次都把loading显示出来就不那么好看

  • 所以我们需要对插件进行魔改,让图片稍微提前加载,避开加载动画

  • 打开 Hexo根目录>node_modules > hexo-lazyload-image > lib > simple-lazyload.js 文件

  • 第9行修改为:

    1
    && rect.top <= (window.innerHeight +240 || document.documentElement.clientHeight +240)
  • 作用:提前240个像素加载图片;当然这个值也可以根据自己情况修改

代码压缩

gulp代码压缩

因为hexo生成的html、css、js等都有很多的空格或者换行,而空格和换行也是占用字节的,所以需要将空格换行去掉也就是我要进行的“压缩”。

有人说空格换行能占多少字节?确实占不了多少,但是一个人访问是这么多字节,那么一百人,一万人呢?加起来这量就不少了吧,这都是流量啊!这也是很多css/js文件的后缀为*.min.js或*.min.css的原因。虽然我们可能没那么多访问量,但是能减小一点资源文件的大小也是对访问速度有那么一点提升的。

我们采用gulp代码压缩方式。

使用方法:

  1. 进入站点根目录下依次执行下面的命令:
1
2
3
4
5
6
# 全局安装gulp模块
npm install gulp -g
# 安装各种小功能模块 执行这步的时候,可能会提示权限的问题,最好以管理员模式执行
npm install gulp gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save
# 额外的功能模块
npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del @babel/core --save
  1. 在Hexo根目录新建文件 gulpfile.js,并复制以下内容到文件中,有中文注释,可以根据自己需求修改。(注意:文件名不能错,一定为gulpfile.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
var gulp = require("gulp");
var debug = require("gulp-debug");
var cleancss = require("gulp-clean-css"); //css压缩组件
var uglify = require("gulp-uglify"); //js压缩组件
var htmlmin = require("gulp-htmlmin"); //html压缩组件
var htmlclean = require("gulp-htmlclean"); //html清理组件
var imagemin = require("gulp-imagemin"); //图片压缩组件
var changed = require("gulp-changed"); //文件更改校验组件
var gulpif = require("gulp-if"); //任务 帮助调用组件
var plumber = require("gulp-plumber"); //容错组件(发生错误不跳出任务,并报出错误内容)
var isScriptAll = true; //是否处理所有文件,(true|处理所有文件)(false|只处理有更改的文件)
var isDebug = true; //是否调试显示 编译通过的文件
var gulpBabel = require("gulp-babel");
var es2015Preset = require("babel-preset-es2015");
var del = require("del");
var Hexo = require("hexo");
var hexo = new Hexo(process.cwd(), {}); // 初始化一个hexo对象

// 清除public文件夹
gulp.task("clean", function () {
return del(["public/**/*"]);
});

// 下面几个跟hexo有关的操作,主要通过hexo.call()去执行,注意return
// 创建静态页面 (等同 hexo generate)
gulp.task("generate", function () {
return hexo.init().then(function () {
return hexo
.call("generate", {
watch: false
})
.then(function () {
return hexo.exit();
})
.catch(function (err) {
return hexo.exit(err);
});
});
});

// 启动Hexo服务器
gulp.task("server", function () {
return hexo
.init()
.then(function () {
return hexo.call("server", {});
})
.catch(function (err) {
console.log(err);
});
});

// 部署到服务器
gulp.task("deploy", function () {
return hexo.init().then(function () {
return hexo
.call("deploy", {
watch: false
})
.then(function () {
return hexo.exit();
})
.catch(function (err) {
return hexo.exit(err);
});
});
});

// 压缩public目录下的js文件
gulp.task("compressJs", function () {
return gulp
.src(["./public/**/*.js", "!./public/libs/**"]) //排除的js
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress JS:" })))
.pipe(plumber())
.pipe(
gulpBabel({
presets: [es2015Preset] // es5检查机制
})
)
.pipe(uglify()) //调用压缩组件方法uglify(),对合并的文件进行压缩
.pipe(gulp.dest("./public")); //输出到目标目录
});

// 压缩public目录下的css文件
gulp.task("compressCss", function () {
var option = {
rebase: false,
//advanced: true, //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]
compatibility: "ie7" //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
//keepBreaks: true, //类型:Boolean 默认:false [是否保留换行]
//keepSpecialComments: '*' //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
};
return gulp
.src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress CSS:" })))
.pipe(plumber())
.pipe(cleancss(option))
.pipe(gulp.dest("./public"));
});

// 压缩public目录下的html文件
gulp.task("compressHtml", function () {
var cleanOptions = {
protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理
unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊处理
};
var minOption = {
collapseWhitespace: true, //压缩HTML
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
removeComments: true, //清除HTML注释
minifyJS: true, //压缩页面JS
minifyCSS: true, //压缩页面CSS
minifyURLs: true //替换页面URL
};
return gulp
.src("./public/**/*.html")
.pipe(gulpif(isDebug, debug({ title: "Compress HTML:" })))
.pipe(plumber())
.pipe(htmlclean(cleanOptions))
.pipe(htmlmin(minOption))
.pipe(gulp.dest("./public"));
});

// 压缩 public/medias 目录内图片
gulp.task("compressImage", function () {
var option = {
optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
interlaced: false, //类型:Boolean 默认:false 隔行扫描gif进行渲染
multipass: false //类型:Boolean 默认:false 多次优化svg直到完全优化
};
return gulp
.src("./public/medias/**/*.*")
.pipe(gulpif(!isScriptAll, changed("./public/medias")))
.pipe(gulpif(isDebug, debug({ title: "Compress Images:" })))
.pipe(plumber())
.pipe(imagemin(option))
.pipe(gulp.dest("./public"));
});
// 执行顺序: 清除public目录 -> 产生原始博客内容 -> 执行压缩混淆 -> 部署到服务器
gulp.task(
"build",
gulp.series(
"clean",
"generate",
"compressHtml",
"compressCss",
"compressJs",
"compressImage",
gulp.parallel("deploy")
)
);

// 默认任务
gulp.task(
"default",
gulp.series(
"clean",
"generate",
gulp.parallel("compressHtml", "compressCss", "compressJs","compressImage")
)
);
//Gulp4最大的一个改变就是gulp.task函数现在只支持两个参数,分别是任务名和运行任务的函数
  1. 以后的执行方式有两种:

    • 直接在Hexo根目录执行 gulp或者 gulp default ,这个命令相当于 hexo cl&&hexo g 并且再把代码和图片压缩。

    • 在Hexo根目录执行 gulp build ,这个命令与第1种相比是:在最后又加了个 hexo d ,等于说生成、压缩文件后又帮你自动部署了。

值得注意的是:这个加入了图片压缩,如果不想用图片压缩可以把第154行的 "compressImage", 和第165行的 ,"compressImage" 去掉即可

hexo-neat插件实现代码压缩

可能以上方法比较复杂,来介绍个简单的,hexo-neat插件也是用来压缩代码的,底层也是通过gulp来实现的。

但是这个插件是有Bug的:

  • 压缩 md 文件会使 markdown 语法的代码块消失
  • 会删除全角空格

在博客站点根目录执行安装代码:

1
npm install hexo-neat --save

紧接着在站点根目录下的配置文件添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
neat_enable: true
neat_html:
enable: true
exclude:
neat_css:
enable: true
exclude:
- '*.min.css'
neat_js:
enable: true
mangle: true
output:
compress:
exclude:
- '*.min.js'

然后直接 hexo cl&&hexo g 就可以了,会自动压缩文件 。

补充:为了解决以上Bug,对于matery主题(其他主题自行解决)需要将以上默认配置修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#hexo-neat 优化提速插件(去掉HTML、css、js的blank字符)
neat_enable: true
neat_html:
enable: true
exclude:
- '**/*.md'
neat_css:
enable: true
exclude:
- '**/*.min.css'
neat_js:
enable: true
mangle: true
output:
compress:
exclude:
- '**/*.min.js'
- '**/**/instantpage.js'
- '**/matery.js'

CDN加速

请看我的另一篇博客文章:https://yafine-blog.cn/posts/ee35.html

打造稳定快速、高效免费图床

请移步另两篇博文:
GitHub图床:https://yafine-blog.cn/posts/eb3a.html
Gitee图床:https://yafine-blog.cn/posts/15cb.html

SEO优化