# 第1步:CSS加载策略优化实施方案 ## 📋 当前状态分析 ### CSS文件清单 - `normalize.css` - CSS重置(基础,必须首屏加载) - `remixicon.css` - 图标字体(必须首屏加载) - `uikit.min.css` - UIkit框架(必须首屏加载) - `nprogress.min.css` - 进度条(核心功能,首屏加载) - `message.min.css` - 消息提示(可延迟) - `main.css` - 主题样式(需要拆分) ### main.css 结构分析 #### 首屏关键CSS(约15-20KB) ```css 1. CSS变量定义(:root) 2. @font-face 字体声明 3. html/body 基础样式 4. .main 容器布局(居中、阴影、背景) 5. .header 头部布局 6. .header-menu 导航菜单 7. .header-avatar 头像 8. .header-social 社交链接 9. .header-bio 个人介绍 10. [data-theme="dark"] 深色模式基础变量 11. 基础排版(h1-h6, p, a, ul) 12. .footer 页脚 13. 滚动条样式 14. 基础图片样式 15. hr 分割线 ``` #### 非首屏CSS(可延迟加载,约35-40KB) ```css 1. 代码相关 - .code-fold-container - .code-expand-btn - pre, code 特殊样式 - 代码高亮主题 2. 文章详情页 - blockquote 样式 - 文章列表特殊样式 - 打赏按钮(.reward-container) - 相关文章(.related-posts) 3. 评论系统 - Artalk 相关样式(.atk-*) - 评论区布局 4. 友链页面 - .links-item - .link-active-badge - .link-dead-badge 5. 弹幕系统 - .barrage-container - 弹幕动画 6. 搜索功能 - .search-modal - .search-results 7. 其他功能 - 浮动工具(.floating-tools) - Toast 提示 - 图片灯箱 - 无限滚动加载提示 ``` --- ## 🎯 优化方案 ### 策略1:CSS代码拆分(推荐) 将 `main.css` 拆分为两个文件: - `critical.css` - 首屏关键CSS(内联到HTML) - `main.css` - 其余样式(异步加载) ### 策略2:CSS层级加载 保留单个 `main.css`,但使用Hugo的模板逻辑分层输出: - 首屏样式:内联 ` {{/* 2. 非首屏CSS - 预加载但不阻塞渲染 */}} {{ $normalize := resources.Get "css/libs/normalize.css" }} {{ $remixicon := resources.Get "css/libs/remixicon.css" }} {{ $uikit := resources.Get "css/libs/uikit.min.css" }} {{ $nprogress := resources.Get "css/libs/nprogress.min.css" }} {{ $message := resources.Get "css/libs/message.min.css" }} {{ $main := resources.Get "css/main.css" }} {{/* 合并非关键CSS */}} {{ $nonCritical := slice $normalize $remixicon $uikit $nprogress $message $main | resources.Concat "css/style.css" | resources.Minify | resources.Fingerprint }} {{/* 使用preload异步加载,不阻塞渲染 */}} ``` --- ### 步骤1.3:创建Hugo构建脚本(可选,用于自动化) **文件路径:** `themes/Ying/scripts/extract-critical-css.sh` ```bash #!/bin/bash # 从main.css提取关键CSS的辅助脚本 # 用法:./scripts/extract-critical-css.sh echo "正在分析main.css..." # 标记:以下选择器为首屏关键CSS CRITICAL_SELECTORS=( ":root" "html" "body" ".main" ".header" ".header-top" ".header-avatar" ".header-info" ".header-social" ".header-bio" ".header-menu" "h1" "h2" "h3" "h4" "h5" "h6" "a" "p" "ul" "img" "hr" ".meta" ".meta-item" ".footer" ".post-title" ".theme-toggle-button" "@media" "@font-face" ":root" "[data-theme" ) echo "请根据以上选择器手动提取CSS到critical.css" echo "或使用自动化CSS提取工具如:critical、penthouse" ``` --- ## 🧪 测试验证清单 ### 测试1:首屏渲染性能 - [ ] 使用Chrome DevTools的Network面板查看: - 首字节时间(TTFB)是否正常 - 首次内容绘制(FCP)是否提升 - 样式表是否正确加载 ### 测试2:视觉一致性 - [ ] 首页显示正常 - [ ] Header布局正确 - [ ] 导航菜单样式正确 - [ ] 头像显示正常 - [ ] 社交链接图标正确 - [ ] 深色模式切换正常 - [ ] 文章列表页显示正常 - [ ] 文章卡片样式正确 - [ ] 分页按钮正常 ### 测试3:深色模式 - [ ] 点击头像切换深色模式 - [ ] 所有文字颜色正确 - [ ] 背景颜色正确 - [ ] 阴影效果正确 - [ ] 链接颜色正确 ### 测试4:响应式布局 - [ ] 桌面端(>768px)显示正常 - [ ] 移动端(<768px)显示正常 - [ ] 菜单在移动端正确折叠 ### 测试5:资源加载 - [ ] 检查Console无错误 - [ ] 所有CSS文件加载成功 - [ ] 字体文件加载成功(Network面板) - [ ] 无404错误 --- ## 📊 预期收益 ### 性能指标提升(预估) | 指标 | 优化前 | 优化后 | 提升 | |------|--------|--------|------| | 首屏CSS大小 | ~500KB | ~20KB(内联) | ⚡ -96% | | CSS阻塞时间 | ~800ms | ~0ms | ⚡ -100% | | FCP | ~1.8s | ~1.2s | ⚡ -33% | | Speed Index | ~2.5s | ~1.8s | ⚡ -28% | ### 用户体验提升 - ✅ 页面立即开始渲染(无需等待CSS下载) - ✅ 深色模式无闪烁(CSS变量立即生效) - ✅ 字体加载更平滑(font-display: swap生效) - ✅ 首屏内容更快可见 --- ## ⚠️ 注意事项 ### 1. 背景图片的base64数据 当前body的background-image使用了很长的base64数据。这个数据应该: - 保持在critical.css中(确保首屏背景显示) - 或者移至单独文件并使用preload 建议:将base64数据移至单独的CSS文件 `background.css`,使用 `fetchpriority="high"` 优先加载 ### 2. Remixicon字体文件 `remixicon.css` 引用了字体文件(.woff2, .woff)。确保: - 字体文件路径正确 - 使用 `font-display: swap` 避免FOIT ### 3. UIkit依赖 UIkit的CSS可能包含一些组件样式(如grid、modal等)。检查: - 深色模式是否正确覆盖UIkit默认样式 - 是否有样式冲突 ### 4. 浏览器兼容性 `` 技术需要测试: - Chrome/Edge:✅ 完全支持 - Firefox:✅ 支持 - Safari:✅ 支持(11.1+) - IE11:❌ 不支持(需要polyfill或fallback) --- ## 🔄 回滚方案 如果出现问题,快速回滚到原始方案: ```gohtml {{/* 回滚到原始CSS加载方式 */}} {{ $normalize := resources.Get "css/libs/normalize.css" }} {{ $remixicon := resources.Get "css/libs/remixicon.css" }} {{ $uikit := resources.Get "css/libs/uikit.min.css" }} {{ $nprogress := resources.Get "css/libs/nprogress.min.css" }} {{ $message := resources.Get "css/libs/message.min.css" }} {{ $main := resources.Get "css/main.css" }} {{ $style := slice $normalize $remixicon $uikit $nprogress $message $main | resources.Concat "css/style.css" | resources.Minify | resources.Fingerprint }} ``` --- ## 📚 扩展阅读 1. **Critical CSS最佳实践** - https://web.dev/extract-critical-css/ - https://github.com/addyosmani/critical 2. **CSS加载策略** - https://web.dev/preload-responsive-stylesheets/ - https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload 3. **性能优化工具** - Lighthouse:https://developers.google.com/web/tools/lighthouse - WebPageTest:https://www.webpagetest.org/ --- ## ✅ 实施清单 - [ ] 创建 `themes/Ying/assets/css/critical.css` - [ ] 修改 `themes/Ying/layouts/partials/head.html` - [ ] 测试首页显示 - [ ] 测试深色模式 - [ ] 测试移动端 - [ ] 使用Lighthouse验证性能提升 - [ ] 提交代码 --- **预计耗时:** 1-2小时 **风险等级:** 低(有完整回滚方案)