性能优化
本页讲解博客的性能优化手段:图片懒加载、资源压缩、CDN 加速、图片格式优化,以及 LCP(首屏最大内容)优化原则。多数优化开箱即用,重点是理解分层策略,新增资源时不要破坏它。
阅读方式:每项优化先给效果(产物/网络/渲染上能观察到什么变化,尽量可量化),再给产生该效果的对应配置/源码与验证命令。
1. 懒加载(lazyload)
用途:页面可见范围外的图片与评论插件不提前加载,减少首屏请求与流量。配置在主题配置(正式改
userConfig/_config.tmp.yml)。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
1.1 如何启用
效果:首屏之外的 <img> 在页面加载时不发图片请求,滚动到距视口 offset_factor × 视口高度 时才发;加载期间显示占位图(亮/暗两套),因此首屏并发请求数下降。
对应配置(主题配置):
lazyload:
enable: true # true | false
loading_img: /medias_webp/loading2.svg # 加载占位图(亮色)
loading_img_dark: /medias_webp/loading2-dark.svg # 占位图(暗色)
onlypost: false # true 时懒加载仅在文章页生效
offset_factor: 2 # 触发加载的偏移倍数(基数是视窗高度)输出:构建后图片标签带 loading="lazy" lazyload、指向占位图的 data-lazy-src-light/dark,实测:
<img src="/medias_webp/cover/hexo.webp" width="1064" height="560"
data-lazy-src-light="/medias_webp/loading2.svg" loading="lazy" lazyload ...>1.2 常用选项
① 跳过首屏图
效果:带 no-lazy 类的图片立即加载,不显示占位图——适合 Banner、logo 这类首屏元素。
对应源码(Markdown 里直接加类):
<img src="/medias_webp/banner.webp" class="no-lazy">② 只在文章页懒加载
效果:onlypost: true 时首页/独立页不懒加载,只有文章页生效;自定义页要单独开启就在 front-matter 写 lazyload: true。
对应配置:
lazyload:
onlypost: true③ 调节触发距离
效果:offset_factor 越大越早加载(离底部还有很远就开始请求),越小越晚加载、越省流量;2 表示提前两个视口高度。
对应配置:
lazyload:
offset_factor: 31.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
lazyload.enable | bool | true | true / false | 懒加载总开关 |
lazyload.loading_img | string | /medias_webp/loading2.svg | 图片路径 | 亮色占位图 |
lazyload.loading_img_dark | string | /medias_webp/loading2-dark.svg | 图片路径 | 暗色占位图 |
lazyload.onlypost | bool | false | true / false | 仅文章页生效 |
lazyload.offset_factor | number | 2 | 正数(视口高度倍数) | 提前触发距离 |
1.4 边界与冲突
- 元素加
no-lazy类可跳过懒加载(如首屏 Banner)。 onlypost: false时全站生效;自定义页面想单独开启,可在 front-matter 写lazyload: true。offset_factor按部署环境请求速度调节:越大越早加载(越接近底部才懒加载)。
1.5 小结
- 最小可用:
enable: true - 首屏闪占位图:给首屏图加
no-lazy - 流量太费:调小
offset_factor(更晚加载)
2. 资源压缩(hexo-minify)
用途:构建时压缩 JS/CSS/HTML,减小体积。根配置
_config.yml。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
2.1 如何启用
效果:public/ 下的 .js/.css/.html 去掉注释与多余空白、缩短属性引号,单文件体积下降;本地 hexo server 因 preview: false 不压缩,对比需看 npm run build 的产物。
对应配置(根 _config.yml):
minify:
preview: false ## 本地预览时是否压缩(false = 生产压缩)
exclude: ['*.min.*'] # 已压缩文件跳过
js: { enable: true } # JS 压缩
css: { enable: true } # CSS 压缩
html:
enable: true
options:
minifyJS: true # HTML 内联 JS 压缩
minifyCSS: true # HTML 内联 CSS 压缩
removeComments: true # 去注释
collapseWhitespace: true # 去多余空白
removeAttributeQuotes: true
image:
enable: false # 图片压缩默认关闭(图片走独立优化,见第 4 节)输出:产物 HTML 中注释消失、连续空白折叠;对比同一文件压缩前后可用 wc -c。
2.2 常用选项
① 本地也压缩(调试用)
效果:hexo server 输出压缩版页面,便于验证压缩后样式/脚本是否损坏;代价是本地调试变难读。
对应配置:
minify:
preview: true② 排除已压缩库
效果:*.min.* 不再二次压缩,避免破坏已压缩文件、节省构建时间。
对应配置:
minify:
exclude: ['*.min.*']③ 只压缩 HTML
效果:只折叠 HTML 空白与注释,JS/CSS 文件原样输出(便于对照排查)。
对应配置:
minify:
js: { enable: false }
css: { enable: false }
html:
enable: true2.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
minify.preview | bool | false | true / false | 本地预览是否压缩 |
minify.exclude | array | ['*.min.*'] | glob 列表 | 跳过的文件 |
minify.js.enable | bool | true | true / false | JS 压缩 |
minify.css.enable | bool | true | true / false | CSS 压缩 |
minify.html.enable | bool | true | true / false | HTML 压缩 |
minify.html.options.* | 对象 | 见上 | html-minifier 选项 | HTML 压缩细节 |
minify.image.enable | bool | false | true / false | 图片压缩(本项目关闭) |
2.4 边界与冲突
preview: false意味着本地hexo server不压缩,想验证压缩效果需npm run build(见「部署」篇)。- 压缩开关由根
_config.yml的# minify-switch标记行控制,tools/cicd.sh按构建模式 sed 切换(-d关闭压缩,-r/-c/-t开启压缩),构建后自动还原。 - 关闭 HTML 压缩会影响内联脚本的空白,若页面依赖内联脚本格式,先单独关
html.minifyJS。
2.5 小结
- 最小可用:保持默认(
js/css/html全开、preview: false) - 调试样式:
preview: true或直接看未压缩产物 - 只想减 HTML:关掉 js/css 两项
3. CDN 加速
用途:静态资源走 jsDelivr 全球节点,用户就近取资源。机制是占位符注入:模板写
{cdnPathVersion},CI 构建时替换为真实 CDN 地址(详见「全局配置」篇 CDN 一节)。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
3.1 如何启用
效果:-r 构建后,HTML 里主题资源的 URL 从站内相对路径变成 https://cdn.jsdelivr.net/gh/...@<版本>/...,用户从就近节点取 JS/CSS;-d(调试)构建则把 CDN 占位符清空,仍走站内域名。
对应配置(模板 userConfig/_config.tmp.yml,构建时注入主题配置):
# 主题配置
jsDelivr:
url: {cdnPathVersion} # 带版本号的 CDN 路径(构建时替换)
latesturl: #{cdnPathLatest} # latest 路径(被注释,未启用)
cdn:
url: "{cdnUrl}" # JS/CSS CDN URL
mediaUrl: "{mediaUrl}" # 图片/媒体 CDN URL
resUrl: "{resUrl}" # 资源 CDN URL输出:tools/cicd.sh -r 后 themes/matery/_config.yml 中 cdn.url 已是真实域名,产物 HTML 的 <script src> 指向 CDN;-d 后同一位置为站内路径。
3.2 常用选项
① 版本号(缓存的关键)
效果:-r 递增 tools/.VERSION 并注入 {urlVersion}(如 ?v={urlVersion}),CDN 与浏览器缓存才能拿到新文件;仅改内容 -c 不递增,CDN 命中旧版本但内容不变没问题。
对应命令:
tools/cicd.sh -r "特性" # 递增版本 + CDN 路径
tools/purge-cdn.sh -a # 刷新 CDN 缓存(release 模式自动调用)输出:tools/.VERSION 数值变大;产物 URL 的 ?v= 随之变化。
② 图片走独立 CDN 域
效果:图片请求走 {mediaUrl} 域,与 JS/CSS 分离,便于分别控制缓存策略。
对应配置:
cdn:
mediaUrl: "{mediaUrl}"3.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
jsDelivr.url | string | {cdnPathVersion} | 占位符 | 带版本号的 CDN 路径 |
jsDelivr.latesturl | string | 注释 | 占位符 | latest 路径(未启用) |
cdn.url | string | {cdnUrl} | 占位符/URL | JS/CSS CDN |
cdn.mediaUrl | string | {mediaUrl} | 占位符/URL | 图片/媒体 CDN |
cdn.resUrl | string | {resUrl} | 占位符/URL | 资源 CDN |
-r 版本注入 | 命令 | — | — | {urlVersion} 递增 |
3.4 边界与冲突
- 版本号是关键:只改内容用
-c不递增版本,若同时改了 CDN 上的静态资源(非文章内容),缓存不会更新——这种情况要用-r。 {cdnPathLatest}在模板中被注释,实际未启用;引用latest会让缓存失效策略失效。-d构建会清空 CDN 配置,因此本地预览看不到 CDN 效果,验证 CDN 要用-r/-c/-t的产物。
3.5 小结
- 最小可用:
-r发布,CDN 自动注入 - 改了没更新:确认版本号有没有递增
- 本地看不到 CDN:正常,
-d会清空
4. 图片优化(webp)
用途:图片是本博客体积大头。站内图片统一为 webp 格式,体积远小于 jpg/png,并配合 CDN 分发。webp 文件在主题源码
themes/matery/source/medias_webp/(构建时复制到public/medias_webp/,URL 用/medias_webp/...)。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
4.1 如何启用
效果:站内图片请求全部落在 /medias_webp/*.webp(或 .svg 占位图),相比同尺寸 jpg/png 传输字节更少;浏览器直接解码 webp,无需额外 JS。
对应源码(现有图库路径示例):
# 示例:featureimages 图库均为 webp
/medias_webp/featureimages/0.webp
/medias_webp/avatar.webp
/medias_webp/loading2.svg # SVG 占位图(矢量,体积极小)输出:构建后 public/medias_webp/ 下是这些文件;HTML 里的 src 指向它们。
4.2 常用选项
① 新增配图转 webp 再入仓库
效果:新图与站内其他图一致,体积小、可被懒加载与 CDN 正常处理。
对应命令(cwebp 未随仓库安装,示例未验证;参数按实际图片调整):
cwebp -q 82 input.jpg -o output.webp输出:生成 output.webp,放入图片仓库后构建即被复制。
② 图片仓库同步
效果:图片仓库(子模块)里的图片在构建前被同步,imgurl.sh 处理 URL 后页面引用正确。
对应命令:
tools/processRepo.sh # LFS checkout + 同步 cloudimg/cloudmedia输出:userConfig/cloudimg/、userConfig/cloudmedia/ 内容为最新;构建日志无 LFS 报错。
4.3 全部可调项
| 项 | 位置 | 作用 |
|---|---|---|
/medias_webp/ | 主题 source/ | 站内图片统一路径 |
userConfig/cloudimg/ | 子模块 | 图片仓库(processRepo.sh 同步) |
userConfig/cloudmedia/ | 子模块 | 媒体仓库 |
minify.image.enable | 根 _config.yml | 本项目关闭(webp 已是最终形态) |
4.4 边界与冲突
- 新增配图建议转 webp 再入仓库:图片仓库是子模块
userConfig/cloudimg/(tools/processRepo.sh同步),构建时imgurl.sh处理 URL。 - 图片加载遵循第 1 节懒加载 + 第 3 节 CDN 分发,两层叠加生效。
hexo-minify的image.enable默认关闭——站内 webp 已是最终形态,不需要二次压缩。- 旧版
medias/(jpg)已废弃,不要在新内容里引用.jpg路径。
4.5 小结
- 最小可用:新图先转 webp 再放进图片仓库
- 体积对比:同尺寸 webp < jpg/png
- 别开图片压缩:
minify.image.enable保持false
5. LCP 优化原则(JS 分层)
用途:LCP(Largest Contentful Paint)是首屏核心指标。2026-08-11 完成一轮 JS 加载策略分层重构,原则是首屏必需同步、其余 defer、重型按需。
学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
5.1 如何启用
效果:首屏只同步加载 utils + colorSchema,其余脚本 defer 并行下载不阻塞解析,重型库(mermaid/mathjax/echarts)只在需要的页面注入。实测 LCP 从 4.2s 降至 1.8s(降幅 57%)。
对应源码(layout/_partial/common/scripts.ejs + head.ejs):分层表见下。
| 层级 | JS | 加载方式 | 理由 |
|---|---|---|---|
| L0 关键同步 | utils + colorSchema(+ export_config() / 语言内联注入) | 同步(head 内) | 全局命名空间/配置依赖,首屏必需;已去 jQuery |
| L1 defer | materialize/masonry/imagesloaded/aos/events/plugins/lightgallery/搜索引擎 | defer | 并行下载不阻塞解析,defer 保执行顺序 |
| L2 按需动态 | typed/mermaid/mathjax/echarts/tocbot | 条件触发动态注入 | 首屏零开销 |
| L3 异步 | umami/busuanzi 等分析脚本 | async | 不阻塞渲染 |
5.2 常用选项
① 自己加 JS 时的三条纪律
效果:新增脚本不拖慢首屏——不阻塞解析、不动全局基石、重型库不进入全站 bundle。
对应源码:
- 默认
defer:<script src="..." defer></script>,不要同步阻塞 - 别动 L0 的 utils/colorSchema:它们是全局命名空间基石,同步加载是设计决策
- 重型库按需加载:mermaid/mathjax/echarts 这类只在特定页面出现的库,不该出现在全站脚本里——条件触发时再注入
② 验证 defer 是否生效
效果:产物 HTML 里的主题脚本标签带 defer,说明没退回同步阻塞。
对应命令:
grep -o '<script[^>]*defer[^>]*>' public/index.html | head -3输出(实测):
<script defer src="/js/wiki.js?v=13.27" >
<script defer src="/js/search.js?v=13.27" >5.2.1 去 jQuery 与脚本分层细节(2026-09-05 P4/P5 全站完成)
主题已全站去 jQuery,改用原生 DOM API(querySelector / addEventListener / classList / getComputedStyle 等)。themes/matery/_config.yml 的 libs.js.* 中 jQuery 相关项现状(源:themes/matery/_config.yml、themes/matery/layout/_partial/common/scripts.ejs):
| 配置项 | 状态 | 依据 |
|---|---|---|
libs.js.jquery | 已停用(注释) | 注释「2026-09-05 停用:P4/P5 全站去 jQuery 完成」 |
libs.js.jqueryUI | 配置键保留(_config.yml 未注释),scripts.ejs 中对应 <script> 已注释 → 实际未加载 | _config.yml 该键仍存在 |
libs.js.jqueryBarrager | 已停用(注释) | contact 页删除(jQuery 弹幕废弃)后停用 |
libs.js.jqueryPjax | 配置项保留 | layout/、scripts/、source/js/ 中已无引用 |
因此第 5 节表格的 L0 层不再含 jquery——同步层只有
utils.js+color-schema.js。
关键内联脚本必须先于 defer(源:head.ejs、scripts.ejs):
head.ejs同步加载utils+colorSchema,并同步执行export_config()(注入window.CONFIG)——它们必须先于所有defer脚本,供其读取全局命名空间/配置。scripts.ejs中多语言配置MATERY_LANG、i18n 文案MATERY_I18N为同步内联<script>,刻意排在wiki.js(defer)之前;源码注释即为「注入为同步 script,保证先于所有 defer 脚本执行」。
加载方式归类:
defer:materialize / masonry / imagesloaded / aos / events / plugins / search / scrollProgress / lightgallery / boot;instantpage为type="module"(module 本身即 defer 语义,未再加defer属性)。async:umami / busuanzi / tagCommon(统计与评论辅助,不阻塞渲染)。- 条件触发(仅特定页面/布局):typed / mermaid / mathjax / echarts / tocbot。
5.3 全部可调项
| 项 | 位置 | 可选值 | 作用 |
|---|---|---|---|
| 脚本加载方式 | scripts.ejs / head.ejs | 同步 / defer / async / 动态注入 | 决定是否阻塞首屏解析 |
libs.js.jquery | themes/matery/_config.yml | 注释(停用) | 已去 jQuery |
libs.js.instantpage | 同上 | type="module" | module 自带 defer 语义 |
| 条件触发列表 | 对应模板 | 仅特定页面 | typed/mermaid/mathjax/echarts/tocbot |
5.4 边界与冲突
JS 兼容性坑(2026-09-22):classList.add('a b') 传入含空格的多类名会抛 InvalidCharacterError(DOMTokenList 拒绝空格分隔)——需 classList.add('a', 'b') 或 split 后逐个添加。首页曾因此报错。
- 把 L0 脚本改成
defer会导致其他脚本读不到window.CONFIG,首屏白屏或报undefined。 - 新增第三方库若同步引入,LCP 会回退——优先按需注入。
5.5 小结
- 最小可用:新脚本一律
defer - 要改 L0:先确认依赖
window.CONFIG的脚本 - 重型库:条件触发注入,不进全站 bundle
- 多类名:
classList.add('a','b'),不要空格
6. 网页预加载(instantpage)
用途:用户 hover 链接时提前预加载目标页面,点击几乎瞬时打开。
学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
6.1 如何启用
效果:鼠标悬停在站内链接上约几十毫秒后,Network 面板出现目标页面的预取请求;点击时页面从缓存渲染,感知更快。移动端无 hover,自动不预加载。
对应配置(主题配置):
instantpage:
enable: true输出:页面加载 instantpage 脚本(type="module",等效 defer),产物中可见该 <script>。
6.2 常用选项
① 关闭
效果:不再有 hover 预取请求,节省流量;点击时正常加载目标页。
对应配置:
instantpage:
enable: false6.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
instantpage.enable | bool | true | true / false | hover 预加载开关 |
6.4 边界与冲突
- 基于 instant.page 实现,
enable: true时全站生效;对移动端(无 hover)自动降级不预加载。 - 预取只发生在站内链接,外链不受影响。
6.5 小结
- 最小可用:
enable: true - 流量敏感:关掉它,点击时再加载
7. 暗色特色图(darkFeatureImages)
用途:暗色模式下的特色图库——
featureimages的暗色版本,暗色模式下随机取图用。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
7.1 如何启用
效果:暗色模式下 Banner/封面取 dark/ 目录里的图片,切回亮色则取原图库;同一标题仍按 hash 稳定取图。
对应配置(主题配置):
darkFeatureImages:
- /medias_webp/featureimages/dark/0.webp
- /medias_webp/featureimages/dark/1.webp
- /medias_webp/featureimages/dark/2.webp
# ... 更多暗色图输出:暗色模式页面 img/背景的地址变为 /medias_webp/featureimages/dark/N.webp。
7.2 常用选项
① 增加暗色图
效果:暗色图库候选变多,不同文章更容易分到不同图。
对应配置:在列表追加路径即可(图片放 themes/matery/source/medias_webp/featureimages/dark/)。
7.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
darkFeatureImages | array | — | 图片路径列表 | 暗色模式随机取图池 |
7.4 边界与冲突
- 与亮色
featureimages图库对应,暗色模式下 Banner/封面随机取图时从本列表选取;图片放themes/matery/source/medias_webp/featureimages/dark/。 - 文件缺失时暗色图请求 404,页面回落到占位图/默认图。
7.5 小结
- 最小可用:列出若干
dark/N.webp - 图不对:确认文件真的在
dark/目录
8. 图片尺寸插件(image_size_plugin)
用途:构建时自动为图片补
width/height属性,防止布局偏移(CLS);支持本地图片映射到线上 CDN 路径。学习路径:如何启用 → 常用选项 → 全部可调项 → 边界与冲突
8.1 如何启用
效果:产物 <img> 多出 width="1064" height="560"(实测首页封面图),浏览器在图片下载前就预留空间,CLS 下降。
对应配置(主题配置):
image_size_plugin:
enable: true
proxy_url: # 图片代理地址(如 http://xray:10089)
debug: true # true | false 打印开关
onlypost: false # true 时仅处理文章页图片
# 本地图片保存路径(数组:主题资源 + 站点文章图片都查)
local_path:
- themes/matery/source
- source
# 本地图片路径映射到线上路径 本地路径索引
map_paths:
- userConfig/cloudmedia
- userConfig/cloudimg
- themes/matery/source
# 本地图片路径映射到线上路径
map_paths_web_root:
userConfig/cloudmedia: https://cdn.17lai.site
userConfig/cloudimg: https://cimg1.17lai.site输出:构建后 <img> 带 width/height;debug: true 时构建日志打印处理过的图片。
8.2 常用选项
① 跳过处理
效果:带 no-size 类、或已带 width/height 属性的图片原样输出,不被改写。
对应源码(Markdown):
<img src="/medias_webp/xxx.webp" class="no-size">② 本地路径映射到 CDN
效果:命中 map_paths 的本地图片路径被替换成 map_paths_web_root 里配的线上地址,产物里不出现本地路径。
对应配置:
image_size_plugin:
map_paths:
- userConfig/cloudimg
map_paths_web_root:
userConfig/cloudimg: https://cimg1.17lai.site8.3 全部可调项
| 键 | 类型 | 默认 | 可选值/范围 | 作用 |
|---|---|---|---|---|
image_size_plugin.enable | bool | true | true / false | 补尺寸总开关 |
image_size_plugin.proxy_url | string | 空 | 代理地址 | 远程图片探测代理 |
image_size_plugin.debug | bool | true | true / false | 打印处理日志 |
image_size_plugin.onlypost | bool | false | true / false | 仅文章页处理 |
image_size_plugin.local_path | array | 见上 | 目录列表 | 本地图片查找根 |
image_size_plugin.map_paths | array | 见上 | 目录列表 | 本地路径映射来源 |
image_size_plugin.map_paths_web_root | map | 见上 | 目录 → URL | 线上地址映射 |
8.4 边界与冲突
- 会跳过含
no-size类、或已带width/height属性的图片;map_paths+map_paths_web_root把本地图片路径替换为线上 CDN 地址(图片仓库子模块userConfig/cloudimg、userConfig/cloudmedia的图片走此映射)。 - 远程图片需要
proxy_url才能探测尺寸,否则跳过(不加width/height)。
8.5 小结
- 最小可用:
enable: true - 验证:产物
grep -o '<img[^>]*width="[0-9]*"' public/index.html | head - 不想处理某图:加
no-size
9. CSS 异步 + SEO(2026-09-07)
用途:消除渲染阻塞的 CSS,并补齐搜索/分享所需的元数据。
学习路径:如何启用 → 非首屏 CSS → 结构化数据 → 分享图 → LCP 元素 → 全部可调项 → 边界与冲突
9.1 如何启用
效果:动画库 CSS 以非阻塞方式加载,首屏渲染不被它卡住;页面 head 同时出现 JSON-LD 结构化数据与 og:image,搜索引擎与社交平台能读到标题/描述/封面。
对应配置/源码:四项实现分别见 9.2–9.5,全部主题内置、默认生效。
输出:产物 HTML 中可同时 grep 到 media="print"、application/ld+json、<meta property="og:image">(实测均存在)。
9.2 非首屏 CSS 异步加载
效果:页面 head 里出现 media="print" onload="this.media='all'" 的 <link>,CSS 下载完才切回 all,因此不阻塞首屏渲染;禁用 JS 时由 <noscript> 兜底。
对应源码(layout/_partial/common/css.ejs):
<link rel="stylesheet" href="..." media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="..."></noscript>输出:产物中该 <link> 带 media="print" 与 onload;aos/animate.css 不再出现在阻塞渲染的 CSS 列表里。
注意:rel="stylesheet preload" 与普通 stylesheet 同 URL 时浏览器自动去重(不重复下载),无需双删。
9.3 SEO 结构化数据(JSON-LD)
效果:产物 HTML 出现 application/ld+json(实测存在),包含站点名、文章标题/描述/日期/作者/封面与 SearchAction,Google 可据此生成富结果。
对应源码(主题内置 layout/_partial/common/structured-data.ejs,自动注入):
- WebSite(全站):站点名 + SearchAction(站内搜索框富结果)
- BlogPosting(文章页):标题/描述/日期/作者/封面/关键词/分类
- Person + Organization:
@id互相引用(避免重复数据)
输出:grep -o 'application/ld+json' public/index.html 有命中。
9.4 社交分享图(og:image)
效果:文章页 og:image 为文章封面,首页/列表页回退到默认图(实测首页输出 /medias_webp/featureimages/0.webp)。
对应配置:
# 主题配置(需同步 userConfig/_config.tmp.yml)
open_graph:
default_og_image: /medias_webp/featureimages/15.webp输出:<meta property="og:image" content="...">。
优先级:page.img(文章图)→ theme.default_og_image(默认图)→ theme.featureImages[0]。文章页用文章封面,首页/列表页用默认图。
9.5 LCP 元素优先级
效果:logo 等首屏图片带 fetchpriority="high",浏览器优先下载,LCP 提前。
对应源码:header/mobile-nav 已内置。
注意:首页 banner 背景图是 JS 动态注入(随机换图功能),不可改为 CSS 直出——会破坏随机换图。
9.6 全部可调项
| 项 | 位置 | 可选值 | 作用 |
|---|---|---|---|
media="print" onload | css.ejs | 开启/关闭 | 非首屏 CSS 异步 |
| JSON-LD 注入 | structured-data.ejs | 内置 | 搜索引擎富结果 |
open_graph.default_og_image | 主题配置 | 图片路径 | 无文章图时的分享图 |
fetchpriority="high" | header/mobile-nav | 内置 | 首屏图优先下载 |
9.7 边界与冲突
rel="stylesheet preload"与普通stylesheet同 URL 会被浏览器自动去重;重复声明不会重复下载,但会多一个标签。- JSON-LD 数据来源全部为已有变量(
config.title/url/author/language+page.*),无需手动维护;验证用 Google Rich Results Test(生产部署后)。 - 首页 banner 背景图必须保持 JS 注入,改成 CSS 直出会破坏随机换图。
9.8 小结
- 最小可用:四项都是主题内置,默认生效
- 验证结构化数据:
grep -o 'application/ld+json' public/index.html - 分享没图:配
default_og_image - 别动 banner:随机换图依赖 JS 注入
附:性能优化速查表
| 手段 | 配置位置 | 关键点 |
|---|---|---|
| 懒加载 | 主题配置 lazyload | no-lazy 类跳过;onlypost 控制范围 |
| 资源压缩 | 根 _config.yml minify | 本地预览不压缩;-d 关闭压缩 |
| CDN | 主题配置 jsDelivr/cdn | -r 递增版本号才刷新缓存 |
| 图片 | /medias_webp/ + CDN | 统一 webp;图片仓库是子模块 |
| LCP 分层 | layout/_partial/common/scripts.ejs | L0 同步 / L1 defer / L2 按需 / L3 async |
| CSS 异步 | layout/_partial/common/css.ejs | aos/animate 用 media="print" onload 异步 |
| SEO 结构化 | layout/_partial/common/structured-data.ejs | JSON-LD WebSite + BlogPosting 自动生成 |
| 社交分享图 | 主题配置 default_og_image | 首页/列表页回退默认图(改配置需同步 userConfig/_config.tmp.yml) |
| LCP 元素 | header/mobile-nav logo img | fetchpriority="high" |