设置子模块
将主题添加为子模块
开始前需要确认不存在 themes/volantis 文件夹, 如果有, 请自行删除.
1 | git submodule add git@github.com:volantis-x/hexo-theme-volantis.git themes/volantis |
1 | git submodule add https://github.com/volantis-x/hexo-theme-volantis.git themes/volantis |
多人协同
默认的作者信息在主题配置文件中设置:
1 | # 文章布局 |
Volantis 支持多个作者在一个站点发布文章,其他作者信息需要写在数据文件中,例如:
1 | Jon: |
在文章的 front-matter 中新增 author
即可:
1 | --- |
内容安全策略(CSP)
1 | # 内容安全策略( CSP ) meta 标签 http-equiv="Content-Security-Policy" |
设置 HTTP 响应标头
以 Cloudflare 为例, 在 规则 > 转换规则 > HTTP 响应头修改 中,可以添加以下设置:
- 内容安全策略( CSP )
1 | Content-Security-Policy: default-src 'self' https:; block-all-mixed-content; base-uri 'self' https:; form-action 'self' https:; worker-src 'self' https:; connect-src 'self' https: *; img-src 'self' data: https: *; media-src 'self' https: *; font-src 'self' data: https: *; frame-src 'self' https: *; manifest-src 'self' https: *; child-src https:; script-src 'self' https: 'unsafe-inline' *; style-src 'self' https: 'unsafe-inline' *; |
Doc for Content-Security-Policy
- 不允许在 frame 中展示
1 | x-frame-options: DENY |
为网站提速
加载速度
减少不必要的 js 插件,例如字数统计、动态背景。
查找并解决拖慢速度的资源,以 Chrome 浏览器为例:
- 页面中点击右键,选择「检查」。
- 在右边的窗口中「Network」选项卡,并勾选「Disable cache」。
- 刷新网页,查看加载速度慢的资源。
3.1. 加载缓慢的图片,建议使用 CDN。
3.2. 加载缓慢的可以不用的 js 插件,建议舍弃。
3.3. 加载缓慢却必须使用的 js 插件,建议下载并自己上传至 CDN。
运行速度
- 访问具有动态特效背景(如雪花、粒子等)的网站时,手机很快会发烫变卡,笔记本很快会风扇狂转并且浏览器提示建议关闭此页面。如果你希望网站有好的使用体验请尽量不要安装这类插件。
优化 SEO
Robots
1 | seo: |
在 front-matter 中,可以设置 keywords
、description
、robots
和 seo_title
。其中 seo_title
仅仅用作网页标题,优先级高于 title
。
文章内部不要使用 H1 标题。
通过死链检测工具检查并删除无法访问的链接。
安装 SEO 优化插件:
页面不要堆砌关键词,不要频繁更改路径。
Open Graph
1 | # https://ogp.me/ |
Structured Data
1 | # SEO 入门文档: https://developers.google.com/search/docs |
使用 CDN
对于大部分将博客 deploy 到 GitHub 的用户来说,直接加载本地资源速度比较慢,可以使用 jsdelivr 为开源项目提供的 CDN 服务。
开启方法
1 | cdn_system: |
如果你需要对样式进行 DIY,可以只关闭 style 文件的 CDN。
从V5版本开始,首屏样式采用硬编码的方式写在HTML中。首屏样式内含 cover navbar search 的样式,其他样式放入/css/style.css异步加载。
如果你需要对样式进行 DIY,请注意首屏渲染和异步延迟加载的差异。
自定义 CDN
如果你把对应的文件上传到自己的 CDN 服务器,可以把对应的链接改为自己的 CDN 链接。
尝试使用 gulp 压缩静态文件
安装压缩工具
1 | npm install -g gulp |
gulp 配置文件
参考文档: gulp gulp-html-minifier-terser gulp-htmlclean gulp-htmlmin gulp-clean-css gulp-terser gulp-sourcemaps
gulp 配置文件
https://github.com/volantis-x/community/blob/main/gulpfile.js
const gulp = require('gulp'); | |
const cleanCSS = require('gulp-clean-css'); | |
const htmlmin = require('gulp-html-minifier-terser'); | |
const htmlclean = require('gulp-htmlclean'); | |
const terser = require('gulp-terser'); | |
const sourcemaps = require('gulp-sourcemaps'); | |
// 压缩css文件 | |
const minify_css = () => ( | |
gulp.src(['./public/**/*.css','!./public/{lib,lib/**}','!./public/{libs,libs/**}','!./public/{media,media/**}']) | |
.pipe(sourcemaps.init()) | |
.pipe(cleanCSS({compatibility: 'ie8'})) | |
.pipe(sourcemaps.write('./maps')) | |
.pipe(gulp.dest('./public')) | |
); | |
// 压缩html文件 | |
const minify_html = () => ( | |
gulp.src(['./public/**/*.html','!./public/{lib,lib/**}','!./public/{libs,libs/**}','!./public/{media,media/**}']) | |
.pipe(htmlclean()) | |
.pipe(htmlmin({ | |
removeComments: true, | |
minifyJS: true, | |
minifyCSS: true, | |
minifyURLs: true, | |
})) | |
.pipe(gulp.dest('./public')) | |
) | |
// 压缩js文件 | |
const minify_js = () => ( | |
gulp.src(['./public/**/*.js', '!./public/**/*.min.js','!./public/{lib,lib/**}','!./public/{libs,libs/**}','!./public/{media,media/**}']) | |
.pipe(sourcemaps.init()) | |
.pipe(terser()) | |
.pipe(sourcemaps.write('./maps')) | |
.pipe(gulp.dest('./public')) | |
) | |
gulp.task('one', gulp.parallel( | |
minify_html, | |
minify_css, | |
minify_js | |
)) | |
gulp.task('default', gulp.series('one')); |
运行 gulp
1 | gulp |
尝试使用 babel 转换兼容 ES6
如果想要兼容旧版浏览器,可以尝试使用 gulp-babel 将 ES6 转换为 ES5。
安装 gulp-babel 工具
1 | npm install -g gulp |
gulp 配置文件
参考文档: gulp gulp-babel
gulp 配置文件
https://github.com/volantis-x/community/blob/main/gulpfile.js
1 | gulp.src(['./public/**/*.js', '!./public/**/*.min.js', '!./public/{lib,lib/**}', '!./public/{libs,libs/**}', '!./public/{media,media/**}']) |
运行 gulp
1 | gulp |
安装 Service Worker 服务
方案一 安装插件
安装 hexo-offline-popup 或者 hexo-offline 插件,初次加载速度不变,后期切换页面和刷新网页速度越来越快。
方案二 使用 workbox 自定义配置
step 1. 修改 blog/_config.yml 文件。
1 | # 全局导入 |
step 2. 在 blog/source 中创建 sw.js 文件。
https://gist.github.com/MHuiG/a423c0a953ed5645840a651c33dcd60c
importScripts('https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.3/workbox/workbox-sw.js'); | |
workbox.setConfig({ | |
modulePathPrefix: 'https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.3/workbox/' | |
}); | |
const { core, precaching, routing, strategies, expiration, cacheableResponse, backgroundSync } = workbox; | |
const { CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate } = strategies; | |
const { ExpirationPlugin } = expiration; | |
const { CacheableResponsePlugin } = cacheableResponse; | |
const cacheSuffixVersion = '-000010', // 缓存版本号 极端重要,修改静态文件后发布网页一定要修改缓存版本号 | |
maxEntries = 100; | |
self.addEventListener('activate', (event) => { | |
event.waitUntil( | |
caches.keys().then((keys) => { | |
return Promise.all(keys.map((key) => { | |
if (!key.includes(cacheSuffixVersion)) return caches.delete(key); | |
})); | |
}) | |
); | |
}); | |
core.setCacheNameDetails({ | |
prefix: 'volantis', // 极端重要 自己拟定一个名字 | |
suffix: cacheSuffixVersion | |
}); | |
core.skipWaiting(); | |
core.clientsClaim(); | |
precaching.cleanupOutdatedCaches(); | |
/* | |
* Precache | |
* - Static Assets | |
*/ | |
precaching.precacheAndRoute( // 极端重要 定义首次缓存的静态文件 如果开启CDN需要修改为CDN链接 | |
[ | |
{ url: '/css/first.css', revision: null }, | |
{ url: '/css/style.css', revision: null }, | |
{ url: '/js/app.js', revision: null }, | |
], | |
); | |
/* | |
* Cache File From CDN | |
* | |
* Method: CacheFirst | |
* cacheName: static-immutable | |
* cacheTime: 30d | |
*/ | |
// cdn.jsdelivr.net - cors enabled | |
routing.registerRoute( | |
/.*cdn\.jsdelivr\.net/, | |
new CacheFirst({ | |
cacheName: 'static-immutable' + cacheSuffixVersion, | |
fetchOptions: { | |
mode: 'cors', | |
credentials: 'omit' | |
}, | |
plugins: [ | |
new ExpirationPlugin({ | |
maxAgeSeconds: 30 * 24 * 60 * 60, | |
purgeOnQuotaError: true | |
}) | |
] | |
}) | |
); | |
// m7.music.126.net - cors enabled | |
routing.registerRoute( | |
/.*m7\.music\.126\.net/, | |
new CacheFirst({ | |
cacheName: 'static-immutable' + cacheSuffixVersion, | |
fetchOptions: { | |
mode: 'cors', | |
credentials: 'omit' | |
}, | |
plugins: [ | |
new ExpirationPlugin({ | |
maxAgeSeconds: 30 * 24 * 60 * 60, | |
purgeOnQuotaError: true | |
}) | |
] | |
}) | |
); | |
/* | |
* No Cache | |
* | |
* Method: networkOnly | |
*/ | |
routing.registerRoute( | |
/.*baidu\.com.*/, | |
new NetworkOnly() | |
); | |
/* | |
* Others img fonts | |
* Method: staleWhileRevalidate | |
*/ | |
routing.registerRoute( | |
// Cache image fonts files | |
/.*\.(?:png|jpg|jpeg|svg|gif|webp|ico|eot|ttf|woff|woff2|mp3)/, | |
new StaleWhileRevalidate() | |
); | |
/* | |
* Static Assets | |
* Method: staleWhileRevalidate | |
*/ | |
routing.registerRoute( | |
// Cache CSS files | |
/.*\.(css|js)/, | |
// Use cache but update in the background ASAP | |
new StaleWhileRevalidate() | |
); | |
/* | |
* sw.js - Revalidate every time | |
* staleWhileRevalidate | |
*/ | |
routing.registerRoute( | |
'/sw.js', // 本文件名 | |
new StaleWhileRevalidate() | |
); | |
/* | |
* Default - Serve as it is | |
* networkFirst | |
*/ | |
routing.setDefaultHandler( | |
new NetworkFirst({ | |
networkTimeoutSeconds: 3 | |
}) | |
); |
如果你使用了此方案,修改静态文件后发布网页一定要修改缓存版本号。
方案三 参考官网 volantis-sw.js
安装「相关文章」插件
安装插件
1
npm i -S hexo-related-popular-posts
插件的自定义配置方法:
如果您使用了头图,可以在站点配置文件中添加以下设置来让相关文章显示正确的文章头图:
1 | popularPosts: |
注意
需要升级到 5.0.1 及以上版本才可以支持自定义头图,详见 #29
分析与统计
数据统计
PV 和 UV
支持 不蒜子 的访问统计,在配置文件中设置。
1 | plugins: |
我们还支持以下评论系统提供的访问统计: waline、twikoo、discuss、artalk
如需使用它们,请开启对应评论系统的相关设置,此时将接管含评论页面的 PV 量统计。
推广:杜老师自建国内不蒜子统计平台:4H8G,60G,下行 500M,上行 50M,阿里 CDN。
字数和阅读时长
- 安装以下插件:
1
npm i --save hexo-wordcount
- 修改配置文件,将
wordcount
插件打开blog/_config.volantis.yml 1
2
3
4
5plugins:
...
# 文章字数统计、阅读时长,开启需要安装插件: npm i --save hexo-wordcount
wordcount:
enable: #true - 然后修改配置文件,将
wordcount
写入需要显示的 meta 位置:blog/_config.volantis.yml 1
2
3
4
5
6
7
8
9
10
11
12# 文章布局
article:
...
# 文章详情页面的文章卡片本体布局方案
body:
# 文章顶部信息
# 从 meta_library 中取
top_meta: [..., wordcount, ...]
...
# 文章底部信息
# 从 meta_library 中取
bottom_meta: [..., wordcount, ...]
数据分析
百度统计
1 | baidu_analytics_key: 百度统计的key |
Google Analytics
1 | google_analytics_key: Google Analytics Key |
腾讯前端性能监控
1 | tencent_aegis_id: 上报 id |
51LA统计
1 | v6_51_la: 应用id |
灵雀监控
1 | perf_51_la: 应用id |
CNZZ 统计
请参考 ZYMIN 的这篇教程:
更多进阶玩法
详见 @TRHX 的这篇博客:
内含卡片半透明、增加卡通人物、自定义鼠标样式、鼠标特效、烟花特效、彩色滚动字体、网站运行时间、动态浏览器标题、雪花飘落特效等多种详细教程。