91 lines
2.2 KiB
JavaScript
91 lines
2.2 KiB
JavaScript
const LOW_MEMORY_LIMIT_GB = 2
|
|
const LOW_CPU_LIMIT = 4
|
|
|
|
function getNavigator() {
|
|
if (typeof navigator === 'undefined') {
|
|
return null
|
|
}
|
|
|
|
return navigator
|
|
}
|
|
|
|
function getUserAgent() {
|
|
const nav = getNavigator()
|
|
return nav?.userAgent || ''
|
|
}
|
|
|
|
export function isLowEndDevice() {
|
|
const nav = getNavigator()
|
|
|
|
if (!nav) {
|
|
return false
|
|
}
|
|
|
|
const userAgent = getUserAgent()
|
|
const deviceMemory = Number(nav.deviceMemory || 0)
|
|
const hardwareConcurrency = Number(nav.hardwareConcurrency || 0)
|
|
const isAndroid = /Android/i.test(userAgent)
|
|
const androidVersionMatch = userAgent.match(/Android\s+(\d+)/i)
|
|
const androidMajorVersion = androidVersionMatch ? Number(androidVersionMatch[1]) : 0
|
|
|
|
return (
|
|
(deviceMemory > 0 && deviceMemory <= LOW_MEMORY_LIMIT_GB) ||
|
|
(isAndroid && hardwareConcurrency > 0 && hardwareConcurrency <= LOW_CPU_LIMIT) ||
|
|
(isAndroid &&
|
|
androidMajorVersion > 0 &&
|
|
androidMajorVersion <= 9 &&
|
|
hardwareConcurrency > 0 &&
|
|
hardwareConcurrency <= LOW_CPU_LIMIT)
|
|
)
|
|
}
|
|
|
|
export function prefersReducedMotion() {
|
|
if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
|
|
return false
|
|
}
|
|
|
|
return window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
}
|
|
|
|
export function shouldUseLiteAnimations() {
|
|
return isLowEndDevice() || prefersReducedMotion()
|
|
}
|
|
|
|
export function scheduleIdleTask(callback, timeout = 1200) {
|
|
if (typeof window === 'undefined') {
|
|
callback()
|
|
return null
|
|
}
|
|
|
|
if (typeof window.requestIdleCallback === 'function') {
|
|
return window.requestIdleCallback(callback, { timeout })
|
|
}
|
|
|
|
return window.setTimeout(callback, Math.min(timeout, 300))
|
|
}
|
|
|
|
export function cancelIdleTask(taskId) {
|
|
if (typeof window === 'undefined' || taskId == null) {
|
|
return
|
|
}
|
|
|
|
if (typeof window.cancelIdleCallback === 'function') {
|
|
window.cancelIdleCallback(taskId)
|
|
return
|
|
}
|
|
|
|
window.clearTimeout(taskId)
|
|
}
|
|
|
|
export function applyPerformanceModeClass(target) {
|
|
const classTarget =
|
|
target || (typeof document !== 'undefined' ? document.documentElement : null)
|
|
|
|
if (!classTarget) {
|
|
return
|
|
}
|
|
|
|
classTarget.classList.toggle('low-performance-mode', isLowEndDevice())
|
|
classTarget.classList.toggle('reduce-motion-mode', prefersReducedMotion())
|
|
}
|