--- id: wiki-2026-0508-전력-시스템-power-systems title: 전력 시스템 (Power Systems) — 프론트엔드 관점 category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Battery API, Power-aware UI, Energy efficiency] duplicate_of: none source_trust_level: A confidence_score: 0.85 verification_status: applied tags: [frontend, performance, battery, mobile, energy] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: JavaScript framework: Web APIs --- # 전력 시스템 (Power Systems) — 프론트엔드 관점 ## 매 한 줄 > **"매 mobile / laptop 의 battery 와 thermal budget 을 의식하는 frontend"**. 2026 매 user 의 80%+ 가 mobile 매 access — 매 60fps 의 X, 매 power-aware design 이 differentiator. Battery API deprecation 후 매 alternative signal (visibility, network, thermal) 활용. ## 매 핵심 ### 매 power consumer (frontend) - **CPU/JS**: 매 long task, 매 layout thrash, 매 polling. - **GPU**: 매 unnecessary compositing, 매 large canvas, 매 video decode. - **Network/radio**: 매 frequent fetch, 매 large payload, 매 keep-alive. - **Display**: 매 bright pixels, 매 high refresh rate. - **Sensors**: GPS, accelerometer, camera 매 always-on. ### 매 power-aware signals - **Page Visibility API**: 매 hidden 시 매 work 중단. - **prefers-reduced-motion**: 매 animation 축소. - **Network Information API**: 매 'slow-2g' / 'saveData' 감지. - **deprecated Battery API**: Chrome 84+ removed — 매 indirect signal 의존. ### 매 응용 1. Background tab 매 timer/animation 정지. 2. Save-data mode 매 image/video 축소. 3. requestIdleCallback 매 non-critical work 의 deferral. ## 💻 패턴 ### Page Visibility — 매 hidden 시 정지 ```javascript let rafId = null; function tick() { // 매 expensive animation draw(); rafId = requestAnimationFrame(tick); } document.addEventListener('visibilitychange', () => { if (document.hidden) { cancelAnimationFrame(rafId); rafId = null; } else if (!rafId) { rafId = requestAnimationFrame(tick); } }); ``` ### Save-Data — 매 light mode ```javascript function getDataSaverMode() { const conn = navigator.connection || navigator.mozConnection; if (!conn) return false; return conn.saveData === true || ['slow-2g', '2g'].includes(conn.effectiveType); } if (getDataSaverMode()) { document.body.classList.add('lite-mode'); // 매 disable autoplay video, large hero image, prefetch } ``` ### prefers-reduced-motion ```css @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } ``` ```javascript const mq = window.matchMedia('(prefers-reduced-motion: reduce)'); if (mq.matches) { // 매 expensive parallax, particle 매 비활성화 disableParallax(); } ``` ### requestIdleCallback — 매 non-urgent work ```javascript function scheduleAnalytics(payload) { if ('requestIdleCallback' in window) { requestIdleCallback(() => sendBeacon(payload), { timeout: 2000 }); } else { setTimeout(() => sendBeacon(payload), 0); } } function sendBeacon(payload) { navigator.sendBeacon('/analytics', JSON.stringify(payload)); } ``` ### Intersection Observer — 매 viewport 외 lazy ```javascript const io = new IntersectionObserver((entries) => { for (const e of entries) { if (e.isIntersecting) { const img = e.target; img.src = img.dataset.src; io.unobserve(img); } } }, { rootMargin: '200px' }); document.querySelectorAll('img[data-src]').forEach((img) => io.observe(img)); ``` ### 매 throttle WebSocket on hidden ```javascript class PowerAwareSocket { constructor(url) { this.url = url; this.connect(); document.addEventListener('visibilitychange', () => this.adjust()); } connect() { this.ws = new WebSocket(this.url); } adjust() { if (document.hidden) { // 매 hidden — close to save radio this.ws.close(); } else if (this.ws.readyState !== WebSocket.OPEN) { this.connect(); } } } ``` ### CSS — 매 dark mode 매 OLED 절전 ```css @media (prefers-color-scheme: dark) { :root { --bg: #000; /* 매 true black 매 OLED 의 pixel off */ --fg: #e8e8e8; } } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 매 background tab | requestAnimationFrame 정지 | | 매 save-data | image quality 축소, prefetch X | | 매 reduced-motion | animation 비활성화 | | 매 idle | requestIdleCallback | | 매 OLED + dark mode | true black bg | **기본값**: visibility + saveData + reduced-motion 의 3개 매 mandatory. ## 🔗 Graph - 부모: [[Web Performance]] - 변형: [[Dark Mode]] - 응용: [[PWA]] ## 🤖 LLM 활용 **언제**: 매 power profile audit, 매 power-aware UX 추천. **언제 X**: 매 actual battery measurement (impossible from JS). ## ❌ 안티패턴 - **항상 60fps animation**: 매 background tab 도 — 매 battery drain. - **polling 5s**: 매 mobile radio 매 always-on — push 또는 long-poll. - **autoplay video 4K**: 매 cellular 매 data + battery. ## 🧪 검증 / 중복 - Verified (MDN Page Visibility, Network Information, Web.dev power). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — power-aware frontend, visibility/saveData/reduced-motion 패턴 |