aslan-h5/src/utils/performanceMode.js

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())
}