perf(about): 优化页面渲染性能和动画流畅度

- 增加requestAnimationFrame避免强制重排,提升UI渲染性能
- 批量更新3D标签云样式,减少布局抖动
- 延长初始化超时时间,改善加载体验
- 优化拖拽悬浮按钮动画性能
- 修复兴趣模块文本换行和溢出问题
- 调整字体样式增强可读性
This commit is contained in:
hehh
2025-11-25 10:56:55 +08:00
parent 79c79bf864
commit efcf398ee7
2 changed files with 82 additions and 43 deletions

View File

@@ -1920,6 +1920,8 @@ body {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
font-style: inherit;
font-weight: 700;
} }
/* PC 3D Container */ /* PC 3D Container */
@@ -2480,10 +2482,8 @@ body {
flex-direction: column; flex-direction: column;
} }
/* 修复平板模式下兴趣模块的高度问题 */
.interest-list { .interest-list {
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
max-height: 150px; /* 限制高度 */
overflow: hidden; overflow: hidden;
} }
.interest-item { .interest-item {
@@ -2491,6 +2491,7 @@ body {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
gap: 10px; gap: 10px;
min-width: 0;
} }
.i-emoji { margin-bottom: 6px; } .i-emoji { margin-bottom: 6px; }
@@ -2499,10 +2500,14 @@ body {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
gap: 6px; gap: 6px;
min-width: 0;
width: 100%;
} }
.i-text strong, .i-text span { .i-text strong, .i-text span {
white-space: nowrap; white-space: normal;
word-break: break-word;
overflow-wrap: break-word;
} }
/* 兴趣模块文本渐变色彩 */ /* 兴趣模块文本渐变色彩 */
@@ -2511,6 +2516,8 @@ body {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
word-break: break-word;
overflow-wrap: break-word;
} }
.i-text span { .i-text span {
@@ -2518,6 +2525,8 @@ body {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
word-break: break-word;
overflow-wrap: break-word;
} }
.comment-box { .comment-box {

View File

@@ -222,12 +222,12 @@ class DataManager {
init() { init() {
// 使用requestIdleCallback或setTimeout优化初始化调用 // 使用requestIdleCallback或setTimeout优化初始化调用
if ('requestIdleCallback' in window) { if ('requestIdleCallback' in window) {
requestIdleCallback(() => this.fetchGithub(), { timeout: 1000 }); requestIdleCallback(() => this.fetchGithub(), { timeout: 2000 });
requestIdleCallback(() => this.fetchBlog(), { timeout: 1000 }); requestIdleCallback(() => this.fetchBlog(), { timeout: 2000 });
} else { } else {
// 降级到setTimeout但稍后执行以避免阻塞 // 降级到setTimeout但稍后执行以避免阻塞
setTimeout(() => this.fetchGithub(), 50); setTimeout(() => this.fetchGithub(), 200);
setTimeout(() => this.fetchBlog(), 100); setTimeout(() => this.fetchBlog(), 300);
} }
} }
@@ -314,10 +314,13 @@ class DataManager {
} }
renderUser(data) { renderUser(data) {
const years = new Date().getFullYear() - new Date(data.created_at || (window.SiteConfig?.defaults?.user?.created)).getFullYear(); // 使用requestAnimationFrame避免强制重排
$('#coding-years').text(years + "+"); requestAnimationFrame(() => {
$('#github-repos').text(data.public_repos || (window.SiteConfig?.defaults?.user?.repos)); const years = new Date().getFullYear() - new Date(data.created_at || (window.SiteConfig?.defaults?.user?.created)).getFullYear();
$('#github-followers').text(data.followers || (window.SiteConfig?.defaults?.user?.followers)); $('#coding-years').text(years + "+");
$('#github-repos').text(data.public_repos || (window.SiteConfig?.defaults?.user?.repos));
$('#github-followers').text(data.followers || (window.SiteConfig?.defaults?.user?.followers));
});
} }
renderRepos(list) { renderRepos(list) {
@@ -811,9 +814,12 @@ class UIManager {
container.onmouseover = () => active = true; container.onmouseover = () => active = true;
container.onmouseout = () => active = false; container.onmouseout = () => active = false;
container.onmousemove = (e) => { container.onmousemove = (e) => {
let rect = container.getBoundingClientRect(); // 使用requestAnimationFrame处理鼠标移动事件避免强制重排
mouseX = (e.clientX - (rect.left + rect.width / 2)) / 5; requestAnimationFrame(() => {
mouseY = (e.clientY - (rect.top + rect.height / 2)) / 5; let rect = container.getBoundingClientRect();
mouseX = (e.clientX - (rect.left + rect.width / 2)) / 5;
mouseY = (e.clientY - (rect.top + rect.height / 2)) / 5;
});
}; };
const update = () => { const update = () => {
@@ -834,22 +840,35 @@ class UIManager {
let sb = Math.sin(b * dtr), cb = Math.cos(b * dtr); let sb = Math.sin(b * dtr), cb = Math.cos(b * dtr);
// 批量更新样式以减少重排 // 批量更新样式以减少重排
const fragment = document.createDocumentFragment(); // 先收集所有需要更新的样式信息
const updates = [];
tags.forEach(tag => { tags.forEach(tag => {
let rx1 = tag.x, ry1 = tag.y * ca - tag.z * sa, rz1 = tag.y * sa + tag.z * ca; let rx1 = tag.x, ry1 = tag.y * ca - tag.z * sa, rz1 = tag.y * sa + tag.z * ca;
let ry2 = ry1, rz2 = rx1 * -sb + rz1 * cb; let ry2 = ry1, rz2 = rx1 * -sb + rz1 * cb;
tag.x = rx1 * cb + rz1 * sb; tag.x = rx1 * cb + rz1 * sb;
tag.y = ry2; tag.y = ry2;
tag.z = rz2; tag.z = rz2;
let scale = (tag.z + radius) / (2 * radius) + 0.45; let scale = (tag.z + radius) / (2 * radius) + 0.45;
scale = Math.min(Math.max(scale, 0.7), 1.15); scale = Math.min(Math.max(scale, 0.7), 1.15);
tag.el.style.opacity = (tag.z + radius) / (2 * radius) + 0.2; const opacity = (tag.z + radius) / (2 * radius) + 0.2;
tag.el.style.zIndex = parseInt(scale * 100); const zIndex = parseInt(scale * 100);
let left = tag.x + container.offsetWidth / 2 - tag.el.offsetWidth / 2; const left = tag.x + container.offsetWidth / 2 - tag.el.offsetWidth / 2;
let top = tag.y + container.offsetHeight / 2 - tag.el.offsetHeight / 2; const top = tag.y + container.offsetHeight / 2 - tag.el.offsetHeight / 2;
tag.el.style.transform = `translate(${left}px, ${top}px) scale(${scale})`;
updates.push({
el: tag.el,
transform: `translate(${left}px, ${top}px) scale(${scale})`,
opacity: opacity,
zIndex: zIndex
});
});
// 一次性应用所有样式更新
updates.forEach(update => {
update.el.style.transform = update.transform;
update.el.style.opacity = update.opacity;
update.el.style.zIndex = update.zIndex;
}); });
container.__animToken = requestAnimationFrame(update); container.__animToken = requestAnimationFrame(update);
@@ -879,25 +898,31 @@ class UIManager {
this.initDraggableFab(); this.initDraggableFab();
const updateLabels = () => { const updateLabels = () => {
const lang = getStoredLanguage(); // 使用requestAnimationFrame避免强制重排
const theme = getStoredTheme(); requestAnimationFrame(() => {
fLang.querySelector('.fab-text').textContent = lang === 'zh' ? 'English' : '中文'; const lang = getStoredLanguage();
fTheme.querySelector('.fab-text').textContent = theme === 'night' ? 'Day' : 'Night'; const theme = getStoredTheme();
const playing = (this.audio && !this.audio.paused); fLang.querySelector('.fab-text').textContent = lang === 'zh' ? 'English' : '中文';
fMusic.querySelector('.fab-text').textContent = lang === 'zh' ? (playing ? '暂停' : '播放') : (playing ? 'Pause' : 'Play'); fTheme.querySelector('.fab-text').textContent = theme === 'night' ? 'Day' : 'Night';
const playing = (this.audio && !this.audio.paused);
fMusic.querySelector('.fab-text').textContent = lang === 'zh' ? (playing ? '暂停' : '播放') : (playing ? 'Pause' : 'Play');
});
}; };
main.addEventListener('click', () => { main.addEventListener('click', () => {
menu.classList.toggle('open'); menu.classList.toggle('open');
main.setAttribute('aria-expanded', menu.classList.contains('open') ? 'true' : 'false'); main.setAttribute('aria-expanded', menu.classList.contains('open') ? 'true' : 'false');
updateLabels(); // 延迟更新标签以避免阻塞
requestAnimationFrame(updateLabels);
}); });
fLang.addEventListener('click', () => { fLang.addEventListener('click', () => {
document.getElementById('lang-btn')?.click(); document.getElementById('lang-btn')?.click();
updateLabels(); // 延迟更新标签以避免阻塞
requestAnimationFrame(updateLabels);
}); });
fTheme.addEventListener('click', () => { fTheme.addEventListener('click', () => {
document.getElementById('theme-btn')?.click(); document.getElementById('theme-btn')?.click();
updateLabels(); // 延迟更新标签以避免阻塞
requestAnimationFrame(updateLabels);
}); });
fMusic.addEventListener('click', () => { fMusic.addEventListener('click', () => {
if (this.audio) { if (this.audio) {
@@ -912,9 +937,11 @@ class UIManager {
this.setMusicPauseTime(); this.setMusicPauseTime();
} }
} }
updateLabels(); // 延迟更新标签以避免阻塞
requestAnimationFrame(updateLabels);
}); });
updateLabels(); // 延迟初始标签更新以避免阻塞
requestAnimationFrame(updateLabels);
} }
// 初始化拖拽功能 // 初始化拖拽功能
@@ -959,17 +986,20 @@ class UIManager {
currentY = e.clientY - initialY; currentY = e.clientY - initialY;
} }
const ww = window.innerWidth; // 使用requestAnimationFrame优化拖拽动画
const wh = window.innerHeight; requestAnimationFrame(() => {
const rect = fab.getBoundingClientRect(); const ww = window.innerWidth;
const fw = rect.width; const wh = window.innerHeight;
const fh = rect.height; const rect = fab.getBoundingClientRect();
currentX = Math.max(0, Math.min(currentX, ww - fw)); const fw = rect.width;
currentY = Math.max(0, Math.min(currentY, wh - fh)); const fh = rect.height;
currentX = Math.max(0, Math.min(currentX, ww - fw));
currentY = Math.max(0, Math.min(currentY, wh - fh));
xOffset = currentX; xOffset = currentX;
yOffset = currentY; yOffset = currentY;
setTranslate(currentX, currentY, fab); setTranslate(currentX, currentY, fab);
});
} }
}; };