perf(about): 优化页面渲染性能和动画流畅度
- 增加requestAnimationFrame避免强制重排,提升UI渲染性能 - 批量更新3D标签云样式,减少布局抖动 - 延长初始化超时时间,改善加载体验 - 优化拖拽悬浮按钮动画性能 - 修复兴趣模块文本换行和溢出问题 - 调整字体样式增强可读性
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
62
js/about.js
62
js/about.js
@@ -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) {
|
||||||
|
// 使用requestAnimationFrame避免强制重排
|
||||||
|
requestAnimationFrame(() => {
|
||||||
const years = new Date().getFullYear() - new Date(data.created_at || (window.SiteConfig?.defaults?.user?.created)).getFullYear();
|
const years = new Date().getFullYear() - new Date(data.created_at || (window.SiteConfig?.defaults?.user?.created)).getFullYear();
|
||||||
$('#coding-years').text(years + "+");
|
$('#coding-years').text(years + "+");
|
||||||
$('#github-repos').text(data.public_repos || (window.SiteConfig?.defaults?.user?.repos));
|
$('#github-repos').text(data.public_repos || (window.SiteConfig?.defaults?.user?.repos));
|
||||||
$('#github-followers').text(data.followers || (window.SiteConfig?.defaults?.user?.followers));
|
$('#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) => {
|
||||||
|
// 使用requestAnimationFrame处理鼠标移动事件,避免强制重排
|
||||||
|
requestAnimationFrame(() => {
|
||||||
let rect = container.getBoundingClientRect();
|
let rect = container.getBoundingClientRect();
|
||||||
mouseX = (e.clientX - (rect.left + rect.width / 2)) / 5;
|
mouseX = (e.clientX - (rect.left + rect.width / 2)) / 5;
|
||||||
mouseY = (e.clientY - (rect.top + rect.height / 2)) / 5;
|
mouseY = (e.clientY - (rect.top + rect.height / 2)) / 5;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
@@ -834,8 +840,8 @@ 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;
|
||||||
@@ -845,11 +851,24 @@ class UIManager {
|
|||||||
|
|
||||||
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 = () => {
|
||||||
|
// 使用requestAnimationFrame避免强制重排
|
||||||
|
requestAnimationFrame(() => {
|
||||||
const lang = getStoredLanguage();
|
const lang = getStoredLanguage();
|
||||||
const theme = getStoredTheme();
|
const theme = getStoredTheme();
|
||||||
fLang.querySelector('.fab-text').textContent = lang === 'zh' ? 'English' : '中文';
|
fLang.querySelector('.fab-text').textContent = lang === 'zh' ? 'English' : '中文';
|
||||||
fTheme.querySelector('.fab-text').textContent = theme === 'night' ? 'Day' : 'Night';
|
fTheme.querySelector('.fab-text').textContent = theme === 'night' ? 'Day' : 'Night';
|
||||||
const playing = (this.audio && !this.audio.paused);
|
const playing = (this.audio && !this.audio.paused);
|
||||||
fMusic.querySelector('.fab-text').textContent = lang === 'zh' ? (playing ? '暂停' : '播放') : (playing ? 'Pause' : 'Play');
|
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,6 +986,8 @@ class UIManager {
|
|||||||
currentY = e.clientY - initialY;
|
currentY = e.clientY - initialY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用requestAnimationFrame优化拖拽动画
|
||||||
|
requestAnimationFrame(() => {
|
||||||
const ww = window.innerWidth;
|
const ww = window.innerWidth;
|
||||||
const wh = window.innerHeight;
|
const wh = window.innerHeight;
|
||||||
const rect = fab.getBoundingClientRect();
|
const rect = fab.getBoundingClientRect();
|
||||||
@@ -970,6 +999,7 @@ class UIManager {
|
|||||||
xOffset = currentX;
|
xOffset = currentX;
|
||||||
yOffset = currentY;
|
yOffset = currentY;
|
||||||
setTranslate(currentX, currentY, fab);
|
setTranslate(currentX, currentY, fab);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user