chore: address api review for page.forceGarbageCollection (#32824)
- Renamed to `page.requestGC`. - Added a useful snippet to the docs. References #32278. --------- Signed-off-by: Dmitry Gozman <dgozman@gmail.com> Co-authored-by: Max Schmitt <max@schmitt.mx>
This commit is contained in:
parent
6c20318e5c
commit
a9d5c39d40
|
|
@ -2333,10 +2333,57 @@ last redirect. If cannot go forward, returns `null`.
|
||||||
|
|
||||||
Navigate to the next page in history.
|
Navigate to the next page in history.
|
||||||
|
|
||||||
## async method: Page.forceGarbageCollection
|
## async method: Page.requestGC
|
||||||
* since: v1.47
|
* since: v1.48
|
||||||
|
|
||||||
Force the browser to perform garbage collection.
|
Request the page to perform garbage collection. Note that there is no guarantee that all unreachable objects will be collected.
|
||||||
|
|
||||||
|
This is useful to help detect memory leaks. For example, if your page has a large object `'suspect'` that might be leaked, you can check that it does not leak by using a [`WeakRef`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef).
|
||||||
|
|
||||||
|
```js
|
||||||
|
// 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
await page.evaluate(() => globalThis.suspectWeakRef = new WeakRef(suspect));
|
||||||
|
// 2. Request garbage collection.
|
||||||
|
await page.requestGC();
|
||||||
|
// 3. Check that weak ref does not deref to the original object.
|
||||||
|
expect(await page.evaluate(() => !globalThis.suspectWeakRef.deref())).toBe(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)");
|
||||||
|
// 2. Request garbage collection.
|
||||||
|
page.requestGC();
|
||||||
|
// 3. Check that weak ref does not deref to the original object.
|
||||||
|
assertTrue(page.evaluate("!globalThis.suspectWeakRef.deref()"));
|
||||||
|
```
|
||||||
|
|
||||||
|
```python async
|
||||||
|
# 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
await page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)")
|
||||||
|
# 2. Request garbage collection.
|
||||||
|
await page.request_gc()
|
||||||
|
# 3. Check that weak ref does not deref to the original object.
|
||||||
|
assert await page.evaluate("!globalThis.suspectWeakRef.deref()")
|
||||||
|
```
|
||||||
|
|
||||||
|
```python sync
|
||||||
|
# 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
page.evaluate("globalThis.suspectWeakRef = new WeakRef(suspect)")
|
||||||
|
# 2. Request garbage collection.
|
||||||
|
page.request_gc()
|
||||||
|
# 3. Check that weak ref does not deref to the original object.
|
||||||
|
assert page.evaluate("!globalThis.suspectWeakRef.deref()")
|
||||||
|
```
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
await Page.EvaluateAsync("globalThis.suspectWeakRef = new WeakRef(suspect)");
|
||||||
|
// 2. Request garbage collection.
|
||||||
|
await Page.RequestGCAsync();
|
||||||
|
// 3. Check that weak ref does not deref to the original object.
|
||||||
|
Assert.True(await Page.EvaluateAsync("!globalThis.suspectWeakRef.deref()"));
|
||||||
|
```
|
||||||
|
|
||||||
### option: Page.goForward.waitUntil = %%-navigation-wait-until-%%
|
### option: Page.goForward.waitUntil = %%-navigation-wait-until-%%
|
||||||
* since: v1.8
|
* since: v1.8
|
||||||
|
|
|
||||||
|
|
@ -478,8 +478,8 @@ export class Page extends ChannelOwner<channels.PageChannel> implements api.Page
|
||||||
return Response.fromNullable((await this._channel.goForward({ ...options, waitUntil })).response);
|
return Response.fromNullable((await this._channel.goForward({ ...options, waitUntil })).response);
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection() {
|
async requestGC() {
|
||||||
await this._channel.forceGarbageCollection();
|
await this._channel.requestGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
async emulateMedia(options: { media?: 'screen' | 'print' | null, colorScheme?: 'dark' | 'light' | 'no-preference' | null, reducedMotion?: 'reduce' | 'no-preference' | null, forcedColors?: 'active' | 'none' | null } = {}) {
|
async emulateMedia(options: { media?: 'screen' | 'print' | null, colorScheme?: 'dark' | 'light' | 'no-preference' | null, reducedMotion?: 'reduce' | 'no-preference' | null, forcedColors?: 'active' | 'none' | null } = {}) {
|
||||||
|
|
|
||||||
|
|
@ -1137,8 +1137,8 @@ scheme.PageGoForwardParams = tObject({
|
||||||
scheme.PageGoForwardResult = tObject({
|
scheme.PageGoForwardResult = tObject({
|
||||||
response: tOptional(tChannel(['Response'])),
|
response: tOptional(tChannel(['Response'])),
|
||||||
});
|
});
|
||||||
scheme.PageForceGarbageCollectionParams = tOptional(tObject({}));
|
scheme.PageRequestGCParams = tOptional(tObject({}));
|
||||||
scheme.PageForceGarbageCollectionResult = tOptional(tObject({}));
|
scheme.PageRequestGCResult = tOptional(tObject({}));
|
||||||
scheme.PageRegisterLocatorHandlerParams = tObject({
|
scheme.PageRegisterLocatorHandlerParams = tObject({
|
||||||
selector: tString,
|
selector: tString,
|
||||||
noWaitAfter: tOptional(tBoolean),
|
noWaitAfter: tOptional(tBoolean),
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ export class BidiPage implements PageDelegate {
|
||||||
}).then(() => true).catch(() => false);
|
}).then(() => true).catch(() => false);
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection(): Promise<void> {
|
async requestGC(): Promise<void> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,7 @@ export class CRPage implements PageDelegate {
|
||||||
return this._go(+1);
|
return this._go(+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection(): Promise<void> {
|
async requestGC(): Promise<void> {
|
||||||
await this._mainFrameSession._client.send('HeapProfiler.collectGarbage');
|
await this._mainFrameSession._client.send('HeapProfiler.collectGarbage');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,8 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
||||||
return { response: ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goForward(metadata, params)) };
|
return { response: ResponseDispatcher.fromNullable(this.parentScope(), await this._page.goForward(metadata, params)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection(params: channels.PageForceGarbageCollectionParams, metadata: CallMetadata): Promise<channels.PageForceGarbageCollectionResult> {
|
async requestGC(params: channels.PageRequestGCParams, metadata: CallMetadata): Promise<channels.PageRequestGCResult> {
|
||||||
await this._page.forceGarbageCollection();
|
await this._page.requestGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerLocatorHandler(params: channels.PageRegisterLocatorHandlerParams, metadata: CallMetadata): Promise<channels.PageRegisterLocatorHandlerResult> {
|
async registerLocatorHandler(params: channels.PageRegisterLocatorHandlerParams, metadata: CallMetadata): Promise<channels.PageRegisterLocatorHandlerResult> {
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ export class FFPage implements PageDelegate {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection(): Promise<void> {
|
async requestGC(): Promise<void> {
|
||||||
await this._session.send('Heap.collectGarbage');
|
await this._session.send('Heap.collectGarbage');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export interface PageDelegate {
|
||||||
reload(): Promise<void>;
|
reload(): Promise<void>;
|
||||||
goBack(): Promise<boolean>;
|
goBack(): Promise<boolean>;
|
||||||
goForward(): Promise<boolean>;
|
goForward(): Promise<boolean>;
|
||||||
forceGarbageCollection(): Promise<void>;
|
requestGC(): Promise<void>;
|
||||||
addInitScript(initScript: InitScript): Promise<void>;
|
addInitScript(initScript: InitScript): Promise<void>;
|
||||||
removeNonInternalInitScripts(): Promise<void>;
|
removeNonInternalInitScripts(): Promise<void>;
|
||||||
closePage(runBeforeUnload: boolean): Promise<void>;
|
closePage(runBeforeUnload: boolean): Promise<void>;
|
||||||
|
|
@ -431,8 +431,8 @@ export class Page extends SdkObject {
|
||||||
}), this._timeoutSettings.navigationTimeout(options));
|
}), this._timeoutSettings.navigationTimeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
forceGarbageCollection(): Promise<void> {
|
requestGC(): Promise<void> {
|
||||||
return this._delegate.forceGarbageCollection();
|
return this._delegate.requestGC();
|
||||||
}
|
}
|
||||||
|
|
||||||
registerLocatorHandler(selector: string, noWaitAfter: boolean | undefined) {
|
registerLocatorHandler(selector: string, noWaitAfter: boolean | undefined) {
|
||||||
|
|
|
||||||
|
|
@ -767,7 +767,7 @@ export class WKPage implements PageDelegate {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async forceGarbageCollection(): Promise<void> {
|
async requestGC(): Promise<void> {
|
||||||
await this._session.send('Heap.gc');
|
await this._session.send('Heap.gc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
25
packages/playwright-core/types/types.d.ts
vendored
25
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -2558,11 +2558,6 @@ export interface Page {
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Force the browser to perform garbage collection.
|
|
||||||
*/
|
|
||||||
forceGarbageCollection(): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns frame matching the specified criteria. Either `name` or `url` must be specified.
|
* Returns frame matching the specified criteria. Either `name` or `url` must be specified.
|
||||||
*
|
*
|
||||||
|
|
@ -3712,6 +3707,26 @@ export interface Page {
|
||||||
*/
|
*/
|
||||||
removeLocatorHandler(locator: Locator): Promise<void>;
|
removeLocatorHandler(locator: Locator): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the page to perform garbage collection. Note that there is no guarantee that all unreachable objects will
|
||||||
|
* be collected.
|
||||||
|
*
|
||||||
|
* This is useful to help detect memory leaks. For example, if your page has a large object `'suspect'` that might be
|
||||||
|
* leaked, you can check that it does not leak by using a
|
||||||
|
* [`WeakRef`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef).
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* // 1. In your page, save a WeakRef for the "suspect".
|
||||||
|
* await page.evaluate(() => globalThis.suspectWeakRef = new WeakRef(suspect));
|
||||||
|
* // 2. Request garbage collection.
|
||||||
|
* await page.requestGC();
|
||||||
|
* // 3. Check that weak ref does not deref to the original object.
|
||||||
|
* expect(await page.evaluate(() => !globalThis.suspectWeakRef.deref())).toBe(true);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
requestGC(): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routing provides the capability to modify network requests that are made by a page.
|
* Routing provides the capability to modify network requests that are made by a page.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1956,7 +1956,7 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel {
|
||||||
exposeBinding(params: PageExposeBindingParams, metadata?: CallMetadata): Promise<PageExposeBindingResult>;
|
exposeBinding(params: PageExposeBindingParams, metadata?: CallMetadata): Promise<PageExposeBindingResult>;
|
||||||
goBack(params: PageGoBackParams, metadata?: CallMetadata): Promise<PageGoBackResult>;
|
goBack(params: PageGoBackParams, metadata?: CallMetadata): Promise<PageGoBackResult>;
|
||||||
goForward(params: PageGoForwardParams, metadata?: CallMetadata): Promise<PageGoForwardResult>;
|
goForward(params: PageGoForwardParams, metadata?: CallMetadata): Promise<PageGoForwardResult>;
|
||||||
forceGarbageCollection(params?: PageForceGarbageCollectionParams, metadata?: CallMetadata): Promise<PageForceGarbageCollectionResult>;
|
requestGC(params?: PageRequestGCParams, metadata?: CallMetadata): Promise<PageRequestGCResult>;
|
||||||
registerLocatorHandler(params: PageRegisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageRegisterLocatorHandlerResult>;
|
registerLocatorHandler(params: PageRegisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageRegisterLocatorHandlerResult>;
|
||||||
resolveLocatorHandlerNoReply(params: PageResolveLocatorHandlerNoReplyParams, metadata?: CallMetadata): Promise<PageResolveLocatorHandlerNoReplyResult>;
|
resolveLocatorHandlerNoReply(params: PageResolveLocatorHandlerNoReplyParams, metadata?: CallMetadata): Promise<PageResolveLocatorHandlerNoReplyResult>;
|
||||||
unregisterLocatorHandler(params: PageUnregisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageUnregisterLocatorHandlerResult>;
|
unregisterLocatorHandler(params: PageUnregisterLocatorHandlerParams, metadata?: CallMetadata): Promise<PageUnregisterLocatorHandlerResult>;
|
||||||
|
|
@ -2098,9 +2098,9 @@ export type PageGoForwardOptions = {
|
||||||
export type PageGoForwardResult = {
|
export type PageGoForwardResult = {
|
||||||
response?: ResponseChannel,
|
response?: ResponseChannel,
|
||||||
};
|
};
|
||||||
export type PageForceGarbageCollectionParams = {};
|
export type PageRequestGCParams = {};
|
||||||
export type PageForceGarbageCollectionOptions = {};
|
export type PageRequestGCOptions = {};
|
||||||
export type PageForceGarbageCollectionResult = void;
|
export type PageRequestGCResult = void;
|
||||||
export type PageRegisterLocatorHandlerParams = {
|
export type PageRegisterLocatorHandlerParams = {
|
||||||
selector: string,
|
selector: string,
|
||||||
noWaitAfter?: boolean,
|
noWaitAfter?: boolean,
|
||||||
|
|
|
||||||
|
|
@ -1450,7 +1450,7 @@ Page:
|
||||||
slowMo: true
|
slowMo: true
|
||||||
snapshot: true
|
snapshot: true
|
||||||
|
|
||||||
forceGarbageCollection:
|
requestGC:
|
||||||
|
|
||||||
registerLocatorHandler:
|
registerLocatorHandler:
|
||||||
parameters:
|
parameters:
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,17 @@ import { test, expect } from './pageTest';
|
||||||
|
|
||||||
test('should work', async ({ page }) => {
|
test('should work', async ({ page }) => {
|
||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
globalThis.objectToDestroy = {};
|
globalThis.objectToDestroy = { hello: 'world' };
|
||||||
globalThis.weakRef = new WeakRef(globalThis.objectToDestroy);
|
globalThis.weakRef = new WeakRef(globalThis.objectToDestroy);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await page.requestGC();
|
||||||
|
expect(await page.evaluate(() => globalThis.weakRef.deref())).toEqual({ hello: 'world' });
|
||||||
|
|
||||||
|
await page.requestGC();
|
||||||
|
expect(await page.evaluate(() => globalThis.weakRef.deref())).toEqual({ hello: 'world' });
|
||||||
|
|
||||||
await page.evaluate(() => globalThis.objectToDestroy = null);
|
await page.evaluate(() => globalThis.objectToDestroy = null);
|
||||||
await page.forceGarbageCollection();
|
await page.requestGC();
|
||||||
expect(await page.evaluate(() => globalThis.weakRef.deref())).toBe(undefined);
|
expect(await page.evaluate(() => globalThis.weakRef.deref())).toBe(undefined);
|
||||||
});
|
});
|
||||||
Loading…
Reference in a new issue