perf(glass): complete phase three optimization (#580)

This commit is contained in:
InfinityPacer
2026-07-23 20:26:28 +08:00
committed by GitHub
parent 31caf8f5f8
commit 1bf6c1f1d8
12 changed files with 277 additions and 89 deletions
+8 -3
View File
@@ -22,15 +22,20 @@ describe('glass optics geometry', () => {
expect(getGlassCoverScale(900, 1600, 2400, 1600)).toEqual({ x: 0.375, y: 1 })
})
it('keeps high quality optics while reducing the media-dense recommendation budget', () => {
it('keeps the selected optical quality on every route', () => {
expect(getGlassOpticalRenderProfile('high', '/dashboard')).toEqual({
bufferQuality: 'high',
textureLimit: 3072,
textureSource: 'wallpaper',
})
expect(getGlassOpticalRenderProfile('high', '/recommend?source=tmdb')).toEqual({
bufferQuality: 'balanced',
textureLimit: 2048,
bufferQuality: 'high',
textureLimit: 3072,
textureSource: 'wallpaper',
})
expect(getGlassOpticalRenderProfile('high', '/subscribe/movie')).toEqual({
bufferQuality: 'high',
textureLimit: 3072,
textureSource: 'wallpaper',
})
expect(getGlassOpticalRenderProfile('balanced', '/dashboard')).toEqual({
+54
View File
@@ -0,0 +1,54 @@
import { findNearestScrollTarget, invalidateScrollTargetCache } from '@/utils/scrollTarget'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
describe('findNearestScrollTarget', () => {
beforeEach(() => {
invalidateScrollTargetCache()
document.body.innerHTML = ''
})
afterEach(() => {
vi.restoreAllMocks()
})
it('returns the nearest scrollable ancestor', () => {
const scrollable = document.createElement('div')
const wrapper = document.createElement('div')
const grid = document.createElement('div')
scrollable.style.overflowY = 'auto'
scrollable.append(wrapper)
wrapper.append(grid)
document.body.append(scrollable)
expect(findNearestScrollTarget(grid)).toBe(scrollable)
})
it('reuses ancestor results across sibling grids', () => {
const getComputedStyle = vi.spyOn(window, 'getComputedStyle')
const wrapper = document.createElement('div')
const firstGrid = document.createElement('div')
const secondGrid = document.createElement('div')
wrapper.append(firstGrid, secondGrid)
document.body.append(wrapper)
expect(findNearestScrollTarget(firstGrid)).toBe(window)
const callsAfterFirstGrid = getComputedStyle.mock.calls.length
expect(findNearestScrollTarget(secondGrid)).toBe(window)
expect(getComputedStyle).toHaveBeenCalledTimes(callsAfterFirstGrid)
})
it('recomputes targets after cache invalidation', () => {
const wrapper = document.createElement('div')
const grid = document.createElement('div')
wrapper.append(grid)
document.body.append(wrapper)
expect(findNearestScrollTarget(grid)).toBe(window)
wrapper.style.overflowY = 'auto'
invalidateScrollTargetCache()
expect(findNearestScrollTarget(grid)).toBe(wrapper)
})
})
+4 -6
View File
@@ -24,7 +24,7 @@ export interface GlassOpticalBufferSize {
}
export interface GlassOpticalRenderProfile {
/** 实际内部缓冲档位;媒体密集场景可保留高质量光学但降低合成分辨率。 */
/** 光学层内部缓冲使用的质量档位。 */
bufferQuality: GlassOpticalQuality
/** 活动壁纸进入 GPU 前的最长边限制。 */
textureLimit: number
@@ -32,16 +32,14 @@ export interface GlassOpticalRenderProfile {
textureSource: 'auto' | 'procedural' | 'wallpaper'
}
/** 质量与场景分配合成预算,避免推荐页海报解码与高分辨率光学层争抢资源。 */
/** 质量决定合成缓冲与纹理上限;路由只切换纹理来源,不改变质量档位。 */
export function getGlassOpticalRenderProfile(
quality: GlassOpticalQuality,
routeKey: string,
): GlassOpticalRenderProfile {
const mediaDenseRoute = routeKey.startsWith('/recommend')
return {
bufferQuality: quality === 'high' && !mediaDenseRoute ? 'high' : 'balanced',
textureLimit: quality === 'high' && !mediaDenseRoute ? 3072 : 2048,
bufferQuality: quality,
textureLimit: quality === 'high' ? 3072 : 2048,
textureSource: routeKey.startsWith('/login') ? 'auto' : 'wallpaper',
}
}
+46
View File
@@ -0,0 +1,46 @@
export type ScrollTarget = Window | HTMLElement
let targetCache = new WeakMap<HTMLElement, ScrollTarget>()
/**
* 清除祖先滚动容器缓存。响应式布局或 overlay 状态改变后必须重新解析。
*/
export function invalidateScrollTargetCache() {
targetCache = new WeakMap<HTMLElement, ScrollTarget>()
}
function isScrollableOverflow(overflowY: string) {
return overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay'
}
/**
* 解析元素最近的纵向滚动容器,并让同一祖先链上的网格复用样式查询结果。
*/
export function findNearestScrollTarget(element: HTMLElement | null): ScrollTarget {
if (!element) return window
let parent = element.parentElement
const visited: HTMLElement[] = []
let target: ScrollTarget = window
while (parent && parent !== document.body && parent !== document.documentElement) {
const cachedTarget = targetCache.get(parent)
if (cachedTarget) {
target = cachedTarget
break
}
visited.push(parent)
if (isScrollableOverflow(window.getComputedStyle(parent).overflowY)) {
target = parent
break
}
parent = parent.parentElement
}
visited.forEach(ancestor => targetCache.set(ancestor, target))
return target
}