0x00 前言
這幾天閒來無事,學習了下Hexo的博客速度優化,發現有好多方法。CDN加速、Coding部署、gulp壓縮、hexo-neat、InstantClick 黑科技等等。這裏記錄下我使用gulp壓縮進行Hexo速度優化和在此過程中遇到的問題,以及使用hexo-neat對Hexo進行速度優化。
這兩種方法都是靜態文件壓縮,靜態文件包括: html,css,js,images
0x01 優化之前
在博客速度優化之前,先來說說在瀏覽器輸入url到頁面打開,都做了些什麼?
,因爲沒怎麼了解過,所以參考了很多博客,具體參考的博客鏈接在文末。
當在瀏覽器地址欄輸入網址,如:www.baidu.com
後瀏覽器是怎麼把最終的頁面呈現出來的呢?這個過程可以大致分爲兩個部分:網絡通信和頁面渲染。
1、大致流程
URL 解析->DNS 查詢->TCP 連接->處理請求->接受響應->渲染頁面
簡單的來說,就是:
- 瀏覽器裏輸入網址
- 瀏覽器查找域名對應的IP地址
DNS具體的查找過程,包括:瀏覽器緩存->系統緩存->路由器緩存->ISP DNS緩存->根域名服務器 - 瀏覽器向web服務器發送一個HTTP請求
- 服務器的永久重定向響應(從
http://baidu.com
到http://www.baidu.com
)
爲什麼要重定向?其中一個原因跟搜索引擎排名有關。如果一個頁面有兩個地址,就像
http://baidu.com/
和http://www.baidu.com/
,搜索引擎會認爲它們是兩個網站,結果造成每一個的搜索鏈接都減少從而降低排名。所以要把帶www的和不帶www的地址歸到同一個網站排名下。還有一個原因是用不同的地址會造成緩存友好性變差
。
- 瀏覽器跟蹤重定向地址,發起GET請求
- 服務器”處理”請求,向瀏覽器發回一個HTML響應
- 瀏覽器解析顯示HTML
- 瀏覽器發送請求獲取嵌入在 HTML 中的資源(如圖片、音頻、視頻、CSS、JS等等)
- 瀏覽器發送異步請求(ajax請求等)
2、簡單分析
從上面的過程可以看出,大部分過程我們無法控制,所以只能從瀏覽器端入手來找一些可以做的事情。
少發送請求
把要加載的js文件(css文件同理)合併成一個(儘量少)文件,則可以向服務器少發送請求,從而減少等待時間。
壓縮文件
使用壓縮之後的js、css、img文件,同樣可以減少請求時間。
Css Sprite
這是css的一項技術,將圖片儘可能多的合併成一個圖片文件,第一次使用的時候加載這張圖片,然後瀏覽器會緩存下來,其他地方再使用的時候就不需要重新請求了。
js/css位置
css引用建議放在head標籤裏面;js腳本建議放到body內容的最後,原因:等待js加載或者腳本有錯誤的時候不會影響html頁面的展示。
那麼怎麼提高hexo這個靜態博客的頁面加載速度呢?可以從以下的幾個方面去入手:
- 將js文件儘可能放到body的閉合標籤之前,因爲在加載或者引入js文件時是阻塞式的,如果在頁面的最開始就引入這些js文件,而這些文件又比較大,會造成頁面在渲染時長時間處於白屏狀態。
- 儘量避免去引用訪問速度非常低下的cdn或者圖片,可改用訪問速度更快的cdn,或將難以迅速加載的圖片保存到自己的站點目錄下,以免在加載圖片時耗費大量時間,最後還加載失敗。
- 對頁面的靜態資源進行壓縮,包括css、js和html等文件。
我們自己添加的css和js文件爲了可讀性,往往會有很多換行和空格,這些對於瀏覽器來說並沒什麼用,甚至還會降低渲染頁面的速度。
至於html文件,由於Markdown轉成html的bug,會導致頁面存在大量的空白,查看下頁面的源代碼,會發現有大量的空白符,這也會造成頁面渲染的性能問題。
0x02 gulp4壓縮靜態文件
1、安裝gulp
在站點根目錄下安裝
1.安裝gulp工具
npm install gulp -g
2.安裝gulp插件
npm install gulp-minify-html gulp-minify-css gulp-uglify gulp-imagemin --save
# 解決【Gulp打包問題】 GulpUglifyError: unable to minify JavaScript
# 解決 gulp-uglify 壓縮JavaScript 不兼容 es5 語法的問題
#npm install [email protected] --save
#npm install [email protected] --save
#npm install [email protected] --save
# gulp-babel 取消嚴格模式方法("use strict")
#npm install gulp-remove-use-strict --save
#問題:如果安裝gulp-imagemin錯誤請執行以下語句
#sudo npm i gulp-imagemin --unsafe-perms
2、建立gulpfile.js文件
在站點根目錄下創建gulpfile.js
var gulp = require('gulp');
//Plugins模塊獲取
var minifycss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var minifyhtml = require('gulp-minify-html');
// 壓縮 public 目錄 css文件
gulp.task('minify-css', function () {
return gulp.src('./public/**/*.css')
.pipe(minifycss())
.pipe(gulp.dest('./public'));
});
// 壓縮 public 目錄 html文件
gulp.task('minify-html', function () {
return gulp.src('./public/**/*.html')
.pipe(minifyhtml())
.pipe(gulp.dest('./public'))
});
// 壓縮 public/js 目錄 js文件,忽略/public/lib/blog-encrypt.js
gulp.task('minify-js', function () {
//糾錯前:return gulp.src('./public/**/*.js')
return gulp.src(['./public/**/*.js', '!./public/lib/blog-encrypt.js'])
.pipe(uglify())
.pipe(gulp.dest('./public'))
});
// 壓縮圖片
//gulp.task('minify-images', function() {
// return gulp.src('./public/images/**/*.*')
// .pipe(imagemin(
// [imagemin.gifsicle({'optimizationLevel': 3}),
// imagemin.jpegtran({'progressive': true}),
// imagemin.optipng({'optimizationLevel': 7}),
// imagemin.svgo()],
// {'verbose': true}))
// .pipe(gulp.dest('./public/images'))
//});
//因爲我圖片用的第三方圖牀存放的,所以就沒壓縮圖片。(並且最後測試壓縮圖片時,發現有點權限問題,
//整了兩個多小時沒整好!@^@)
// 分別執行css、heml、js的壓縮任務
gulp.task('default', gulp.parallel('minify-css', 'minify-html', 'minify-js'));
注:
1.修改上面的各個目錄爲你的真實目錄, **
代表0或多個子目錄
2.在默認任務中,gulp.parallel()是gulp4中的新寫法:
gulp.series
用於串行(順序)執行
gulp.parallel
用於並行執行
3.部署執行
hexo clean && hexo g && gulp && hexo d
感覺命令有點多,也可以直接在package.json
文件裏添加
"scripts": {
"hexo": "hexo clean && hexo g && gulp && hexo d"
},
然後在博客根目錄執行npm run hexo
即可
3、遇到的問題
在使用gup4壓縮靜態文件時遇到一些問題,總結一下:
1.gulp4的默認任務執行問題
//4.0以前的寫法
//gulp.task('default', ['minify-html', 'minify-css', 'minify-js']);
//4.0以後的寫法
// 執行 gulp 命令時執行的任務
gulp.task('default', gulp.parallel('minify-css', 'minify-html', 'minify-js'));
2.TypeError: dest.on is not a function
先檢查gulpfile.js
若沒有問題,刪掉node_modules
,重裝一遍依賴npm install
3.GulpUglifyError: unable to minify JavaScript(Gulp打包問題)
錯誤原因有很多,如:有的文件不能打包、javascirpt語法問題等等。我遇到的問題是有的文件不能打包。
(1)解決方法1:
檢查哪一個文件中的哪一行有問題,安裝 gulp-util 模塊 用於打印日誌
npm install --save-dev gulp-util
在gulpfile.js
裏添加:
gulp.task('script', function() {
gulp.src(['public/**/*.js', 'public/lib/**/*.js'])
.pipe(uglify())
.on('error', function(err) {
gutil.log(gutil.colors.red('[Error]'), err.toString());
})
.pipe('dist/js')
})
執行gulp script
,這樣就可以精準的逐個排查文件了。這裏我排查到:
發現blog-encrypt.js
有問題,在gulpfile.js
忽略blog-encrypt.js
即可,即
// 壓縮 public/js 目錄 js文件
gulp.task('minify-js', function () {
//糾錯前:return gulp.src('./public/**/*.js')
return gulp.src(['./public/**/*.js', '!./public/lib/blog-encrypt.js'])
.pipe(uglify())
.pipe(gulp.dest('./public'))
});
(2)解決方法2:
繼續方法1 安裝 babel 模塊
gulp-babel
、babel-preset-es2015
npm install --save-dev gulp-babel babel-preset-es2015
gulp.task('script', function() {
gulp.src(['public/**/*.js', 'public/lib/**/*.js'])
.pipe(babel({
presets: ['es2015'] // es5檢查機制
}))
.pipe(uglify())
.on('error', function(err) {
gutil.log(gutil.colors.red('[Error]'), err.toString());
})
.pipe('dist/js')
})
這樣就解決 gulp-uglify
壓縮JavaScript 不兼容 es5 語法的問題了。
4.The following tasks did not complete: html Did you forget to signal async completion?
運行gulp
,出現下面報錯:
The following tasks did not complete: html
Did you forget to signal async completion?
解決辦法:在註冊的任務函數裏使用 async 和 await。
gulp.task("html",async()=>{
await gulp.src(folder.src + "html/*")
.pipe(htmlClean())
.pipe(gulp.dest(folder.build + "html"))
})
gulp4安裝使用過程中,我暫時就遇到上面這幾種錯誤。除了上述錯誤,還有很多可能會出錯的地方,這裏有個博客記錄了一些:gulp 錯誤集錦
0x03 hexo-neat壓縮靜態文件
hexo-neat
是由rozbo大佬開發的壓縮插件,配置簡單,無需額外命令,只要使用原本的調試三連或者部署三連就可以自動完成靜態資源的壓縮
1、安裝hexo-neat
在站點根目錄下
npm install hexo-neat --save
2、添加相關配置
在站點配置文件_config.yml
添加相關配置,直接添加到站點配置文件_config.yml
的末尾就可以。可以安裝自己的需求去自定義配置,不過有些注意事項
# hexo-neat
# 博文壓縮
neat_enable: true
# 壓縮html
neat_html:
enable: true
exclude:
# 壓縮css
neat_css:
enable: true
exclude:
- '**/*.min.css'
# 壓縮js
neat_js:
enable: true
mangle: true
output:
compress:
exclude:
- '**/*.min.js'
- '**/jquery.fancybox.pack.js'
- '**/index.js'
3、hexo-neat插件注意事項
在使用hexo-neat插件時,可以在命令窗口中看到各個文件的壓縮率,於是可以通過跳過一些文件讓效率更高。
1.跳過壓縮文件的正確配置方式
如果按照官方插件的文檔說明來配置exclude,會發現完全不起作用。這是因爲配置的文件路徑不對,壓縮時找不到你配置的文件,自然也就無法跳過了。於是需要給這些文件指定正確的路徑,萬能的配置方式如下:
neat_css:
enable: true
exclude:
- '**/*.min.css'
2.壓縮html時不要跳過.md
文件和.swig
文件
.md
文件就是markdown文件,如果跳過壓縮.md
文件,而又剛好在文章中使用到了tab標籤,那麼當hexo在生成靜態頁面時就會發生解析錯誤。這會導致使用到了tab標籤的頁面生成失敗而無法訪問。
.swig
文件是模板引擎文件,也就是hexo可以通過這些文件來生成對應的頁面。如果跳過這些文件,所有頁面完全沒有起到壓縮的效果,頁面源代碼裏依然存在着一大堆空白。
0x04 後記
對Hexo進行簡單的速度優化過程中,我主要學習了從輸入url到頁面打開的過程、使用gup4和hexo-neat進行速度優化,最好的速度優化方式應該是使用CDN加速,在下太窮,所以沒使用。同時在使用gup4速度優化過程中也培養了自己的糾錯改錯的能力,繼續加油!!!
參考博客:
在瀏覽器輸入 URL 回車之後發生了什麼(超詳細版)
從輸入URL到頁面加載的全過程
從輸入URL到頁面加載的過程?如何由一道題完善自己的前端知識體系!
從輸入URL到瀏覽器顯示頁面發生了什麼
網絡通信總結(TCP/IP協議、HTTP協議等)
Hexo折騰記——性能優化篇
加速 Hexo 博客
基於Hexo搭建個人博客優化(五)—壓縮篇(gulp4.0壓縮靜態資源)
hexo博客進階-性能優化
hexo優化之——使用gulp壓縮資源