diff --git a/gluon.d.ts b/gluon.d.ts index 4debfb5..5a609a5 100644 --- a/gluon.d.ts +++ b/gluon.d.ts @@ -137,14 +137,24 @@ type IdleAutoOptions = { }; type IdleApi = { - /** Put the window into hibernation. */ + /** + * Put the window into hibernation. + * Internally kills the browser to save the most resources possible. Loses page state. + */ hibernate(): Promise, /** * Put the window to sleep. + * Uses a screenshot of the page instead of the actual page. Loses page state. */ sleep(): Promise, + /** + * Freeze the window. + * Keeps the page but halts most execution and background work. Keeps page state. + */ + freeze(): Promise, + /** Wake up the window from hibernation or sleep. */ wake(): Promise, diff --git a/src/api/idle.js b/src/api/idle.js index 7cbd065..78dd198 100644 --- a/src/api/idle.js +++ b/src/api/idle.js @@ -42,7 +42,7 @@ export default async (CDP, { browserType, closeHandlers }) => { }; - let wakeUrl, hibernating = false; + let wakeUrl, hibernating = false, frozen = false; const hibernate = async () => { // hibernate - crashing chromium internally to save max memory. users will see a crash/gone wrong page but we hopefully "reload" quick enough once visible again for not much notice. if (hibernating) return; // if (process.platform !== 'win32') return sleep(); // sleep instead - full hibernation is windows only for now due to needing to do native things @@ -79,10 +79,39 @@ export default async (CDP, { browserType, closeHandlers }) => { log(`slept in ${(performance.now() - startTime).toFixed(2)}ms`); }; + const freeze = async () => { + if (frozen) return; + frozen = true; + + const startTime = performance.now(); + + wakeUrl = await getLastUrl(); + + // use web lifecycle state to freeze page + await CDP.send(`Page.setWebLifecycleState`, { + state: 'frozen' + }); + + purgeMemory(); + + log(`froze in ${(performance.now() - startTime).toFixed(2)}ms`); + }; + + + const wake = async () => { + if (frozen) { + // update web lifecycle state to unfreeze + await CDP.send(`Page.setWebLifecycleState`, { + state: 'active' + }); + + frozen = false; + return; + } - const wake = async () => { // wake up from hibernation/sleep by navigating to the original page if (!hibernating) return; + // wake up from hibernation/sleep by navigating to the original page const startTime = performance.now(); await CDP.send('Page.navigate', { @@ -155,6 +184,7 @@ export default async (CDP, { browserType, closeHandlers }) => { hibernate, sleep, wake, + freeze, auto: (enabled, options) => { autoEnabled = enabled;