起因
刚搭好博客后觉得还不错,很好,很精致。但久了之后就发现其中还存在的问题(访问加载速度太慢了),而这还是通过别人的提醒后才真正着手去处理的。
一般人的做法都是先通过搜索引擎看看有没有人解决过类似的问题,但我经过一番折腾后发现,这些都比较旧,而且只是适应他们自己的网站优化的,所以通过各种比较,悉知共性后,自己查找资料文档来逐步解决。
问题分析
先在Firefox中输入我的博客网址,然后点击分析(一个时钟图标)按钮即可。
我这里使用了一个很好用的工具
Firefox性能分析工具
打开网络监视器有几种不同的方法:
- 按 Ctrl+ Shift+ E(Mac上为Command+ Option+ E)。
- 从Web Developer菜单中选择“Network”(这是OS X和Linux上Tools菜单的子菜单)。
- 按F12后点击上面的“网络”菜单
刚开始我是用chrome的Network工具,结果(极度失望):
当时没认真截图,但这张图也充分反映出了核心的问题:图片分辨率太大,就17.jpg这张图就耗费了1分钟,加载时间主要花费在图片上了。
解决办法:
- 少发送请求
把要加载的js文件(css文件同理)合并成一个(尽量少)文件,则可以向服务器少发送请求,从而减少等待时间。
- 压缩文件
使用压缩之后的js、css、img文件,同样可以减少请求时间。
- Css Sprite
这是css的一项技术,将图片尽可能多的合并成一个图片文件(例如:如果用到很多图标的话),第一次使用的时候加载这张图片,然后浏览器会缓存下来,其他地方再使用的时候就不需要重新请求了。
- js/css位置
css引用建议放在head标签里面;js脚本建议放到body内容的最后,原因:等待js加载或者脚本有错误的时候不会影响html页面的展示。
GULP自动化构建工具
简介
- gulp是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能对网站资源进行优化,而且在开发过程中很多重复的任务能够使用正确的工具自动完成;使用她,我们不仅可以很愉快的编写代码,而且大大提高我们的工作效率。
gulp是基于Nodejs的自动任务运行器, 她能自动化地完成 javascript/coffee/sass/less/html/image/css 等文件的的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤。在实现上,她借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入,使得在操作上非常简单。通过本文,我们将学习如何使用Gulp来改变开发流程,从而使开发更加快速高效。
gulp 和 grunt 非常类似,但相比于 grunt 的频繁 IO 操作,gulp 的流操作,能更快地更便捷地完成构建工作。
开始使用
这个使用需要用到两个文件:gulpfile.js和package.json文件,它们都放在项目的根目录下。
gulpfile.js:
var gulp = require('gulp');
var cleanCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
var pipeline = require('readable-stream').pipeline;
var htmlmin = require('gulp-htmlmin');
var imagemin = require('gulp-imagemin');
// 压缩 /public/css 目录中的css文件
gulp.task('compress-css', () => {
return gulp.src('./public/css/*.css')
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(gulp.dest('./public/css'));
});
// 压缩 /public/2018 目录中的html文件
gulp.task('compress-html2018', () => {
return gulp.src('./public/2018/**/*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('./public/2018'));
});
// 压缩 /public/2019 目录中的html文件
gulp.task('compress-html2019', () => {
return gulp.src('./public/2019/**/*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('./public/2019'));
});
// 压缩 /public/js 目录中的js文件
gulp.task('compress-js', function () {
return pipeline(
gulp.src(['./public/js/*.js', '!./public/js/search.js']),
uglify(),
gulp.dest('./public/js')
);
});
// 压缩 /public/img 目录中的图片
gulp.task('compress-images', function() {
var stream = gulp.src('./public/img/**/*.*')
.pipe(imagemin([
imagemin.gifsicle({interlaced: false}),
imagemin.jpegtran({progressive: true}),
imagemin.optipng({optimizationLevel: 6}),
imagemin.svgo({
plugins: [
{removeViewBox: true},
{cleanupIDs: false}
]
})
]))
.pipe(gulp.dest('./public/img'));
return stream;
});
// 默认任务 gulp 4.0 适用的方式
gulp.task('default', gulp.series(gulp.parallel('compress-js', 'compress-html2018', 'compress-html2019'
//build the website
)));
以上文件中的用法,需根据自己的项目来配置,底部的参考文献中有详细的解释,因此不再赘述。
温馨提示:**为匹配当前所有目录。
异步执行task
有时候执行完会遇到Did you forget to ….等字样的信息,是因为你没有使用异步的方式执行task中的function。这里给出官方提供的三种方式:
- 接受一个 callback
// 在 shell 中执行一个命令
var exec = require('child_process').exec;
gulp.task('jekyll', function(cb) {
// 编译 Jekyll
exec('jekyll build', function(err) {
if (err) return cb(err); // 返回 error
cb(); // 完成 task
});
});
- 返回一个 stream
gulp.task('somename', function() {
var stream = gulp.src('client/**/*.js')
.pipe(minify())
.pipe(gulp.dest('build'));
return stream;
});
- 返回一个 promise
var Q = require('q');
gulp.task('somename', function() {
var deferred = Q.defer();
// 执行异步的操作
setTimeout(function() {
deferred.resolve();
}, 1);
return deferred.promise;
});
package.json:
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"hexo": {
"version": "3.8.0"
},
"dependencies": {
"braces": "^2.3.1",
"clean-css": "^4.1.11",
"gulp-minify-css": "^1.2.4",
"hexo": "^3.7.0",
"hexo-deployer-git": "^1.0.0",
"hexo-generator-archive": "^0.1.5",
"hexo-generator-category": "^0.1.3",
"hexo-generator-feed": "^1.2.2",
"hexo-generator-index": "^0.2.1",
"hexo-generator-search-zip": "0.0.1",
"hexo-generator-tag": "^0.2.0",
"hexo-prism-plugin": "^2.3.0",
"hexo-renderer-ejs": "^0.3.1",
"hexo-renderer-marked": "^0.3.2",
"hexo-renderer-stylus": "^0.3.3",
"hexo-server": "^0.3.1",
"marked": "^0.6.2"
},
"devDependencies": {
"gulp": "^4.0.1",
"gulp-clean-css": "^4.2.0",
"gulp-htmlclean": "^2.7.22",
"gulp-htmlmin": "^5.0.1",
"gulp-imagemin": "^5.0.3",
"gulp-rename": "^1.4.0",
"gulp-uglify": "^3.0.2",
"pump": "^3.0.0",
"readable-stream": "^3.3.0",
"uglify-js": "^3.5.9"
}
}
这个文件中主要得区分dependencies和devDependencies,前者为全局依赖,后者为此项目开发下的依赖。安装时的区别为:
全局安装 gulp
$ npm install –global gulp作为项目的开发依赖(devDependencies)安装:
$ npm install –save-dev gulp
在Git Bash下进入博客根目录下,然后键入上述命令之后还得安装如下插件:(注意最好用–save-dev)
gulp-clean-css
gulp-htmlclean
gulp-htmlmin
gulp-imagemin
gulp-rename
gulp-uglify
readable-stream
之后只要按顺序输入以下命令即可:
hexo clean
hexo g
gulp
hexo d
其中的gulp执行结果显示:
$ gulp
[11:51:49] Using gulpfile F:\blog\blog\gulpfile.js
[11:51:49] Starting 'default'...
[11:51:49] Starting 'compress-images'...
[11:51:49] Starting 'compress-js'...
[11:51:49] Starting 'compress-html2018'...
[11:51:49] Starting 'compress-html2019'...
[11:51:52] Finished 'compress-html2018' after 2.69 s
[11:51:53] Finished 'compress-js' after 3.58 s
[11:51:53] Finished 'compress-html2019' after 3.63 s
[11:53:03] gulp-imagemin: Minified 81 images (saved 2.87 MB - 13.1%)
[11:53:03] Finished 'compress-images' after 1.22 min
[11:53:03] Finished 'default' after 1.22 min
压缩后的结果:
img原来大小:121MB 压缩后大小:113MB(其中有很多没用到的图片,后面已移除)
js原来大小:468KB 压缩后大小:222KB
css原来大小:46.3KB 压缩后大小:67.5KB(这个压缩后反而更大。。暂时搞不清楚,所以就不压缩了)
重新访问后速度没提升多少,图片还是太大,而且我还发现其中还存在一个问题,就是有部分访问响应结果为404之类的错误,严重拖慢了加载的速度,然后我根据问题的来源,(就是一些时间脚本,还有leancloud评论功能加载错误导致的)解决后,我意外获得了一个jpg图片压缩工具。
经本人测试,效果与原图保持相同的最低图片压缩比就30了,低于30图片会失真,工具应该网上都有。
21张jpg,总共13.9MB,压缩后为4MB
再次测试结果:
为了确保由于网速问题,先检查一下(前几次很可能是网速问题:T):
然后再次测试:
到这里可以看出,还是图片的问题,我只能说美观得有代价。除非把图片都改成分辨率为800x300的那种(我这些都是1920x990以上的),如今只能将图片大小尽量控制在200KB一下会好一点。以上测试每次都是清除了缓存后再测的,第二次访问加载还是很快的。(尴尬的微笑~)
最终结果:
错误解决办法:
如果gulp命令出现err,说是找不到某某模块,则可键入命令npm install来重新构建所需模块,若此命令还出现如下问题:
npm WARN checkPermissions Missing write access to F:\blog\blog\node_modules\
则直接将你的node_modules目录删除,然后重新以管理员身份重新npm install即可。
若安装出现什么npm audit fix等之类的,则可以先键入命令npm audit来进行所有插件的审阅,分析出所需插件的特定版本号,然后根据版本号和所需插件名,在package.json中的dependencies添加即可(^这个符号意思是不小于大版本号)
前面的解决办法只是治标不治本
的,要想显著提升访问速度,根源还是在服务器
上。我这个服务器是借助于 Github 的,外国的服务器,访问有一定速度限制和固定 ip 段的约束(Google为例吧),一般都很慢。最好的做法是将站点
放在国内的云服务器上,然后申请个域名
,这个暂时不搞,一没钱二没时间 emmm~。