chore(tracing): remove proactive snapshotSizes caching (#8126)

This commit is contained in:
Pavel Feldman 2021-08-10 17:06:14 -07:00 committed by GitHub
parent 362aed4cce
commit 76150f1bcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 37 deletions

View file

@ -33,6 +33,10 @@ export class SnapshotRenderer {
return this._snapshots[this._index];
}
viewport(): { width: number, height: number } {
return this._snapshots[this._index].viewport;
}
render(): RenderedFrameSnapshot {
const visit = (n: NodeSnapshot, snapshotIndex: number): string => {
// Text node.

View file

@ -28,6 +28,7 @@ export class SnapshotServer {
this._snapshotStorage = snapshotStorage;
server.routePrefix('/snapshot/', this._serveSnapshot.bind(this));
server.routePrefix('/snapshotSize/', this._serveSnapshotSize.bind(this));
server.routePrefix('/resources/', this._serveResource.bind(this));
}
@ -152,16 +153,28 @@ export class SnapshotServer {
return this._serveSnapshotRoot(request, response);
if (request.url!.endsWith('/snapshot/service-worker.js'))
return this._serveServiceWorker(request, response);
const snapshot = this._snapshot(request.url!.substring('/snapshot/'.length));
this._respondWithJson(response, snapshot ? snapshot.render() : { html: '' });
return true;
}
private _serveSnapshotSize(request: http.IncomingMessage, response: http.ServerResponse): boolean {
const snapshot = this._snapshot(request.url!.substring('/snapshotSize/'.length));
this._respondWithJson(response, snapshot ? snapshot.viewport() : {});
return true;
}
private _snapshot(uri: string) {
const [ pageOrFrameId, query ] = uri.split('?');
const parsed: any = querystring.parse(query);
return this._snapshotStorage.snapshotByName(pageOrFrameId, parsed.name);
}
private _respondWithJson(response: http.ServerResponse, object: any) {
response.statusCode = 200;
response.setHeader('Cache-Control', 'public, max-age=31536000');
response.setHeader('Content-Type', 'application/json');
const [ pageOrFrameId, query ] = request.url!.substring('/snapshot/'.length).split('?');
const parsed: any = querystring.parse(query);
const snapshot = this._snapshotStorage.snapshotByName(pageOrFrameId, parsed.name);
const snapshotData: any = snapshot ? snapshot.render() : { html: '' };
response.end(JSON.stringify(snapshotData));
return true;
response.end(JSON.stringify(object));
}
private _serveResource(request: http.IncomingMessage, response: http.ServerResponse): boolean {

View file

@ -38,7 +38,6 @@ export class TraceModel {
options: { sdkLanguage: '' },
pages: [],
resources: [],
snapshotSizes: {},
};
}
@ -98,8 +97,6 @@ export class TraceModel {
break;
case 'frame-snapshot':
this._snapshotStorage.addFrameSnapshot(event.snapshot);
if (event.snapshot.snapshotName && event.snapshot.isMainFrame)
this.contextEntry.snapshotSizes[event.snapshot.snapshotName] = event.snapshot.viewport;
break;
}
if (event.type === 'action' || event.type === 'event') {
@ -142,7 +139,6 @@ export type ContextEntry = {
options: BrowserContextOptions;
pages: PageEntry[];
resources: ResourceSnapshot[];
snapshotSizes: { [snapshotName: string]: { width: number, height: number } };
};
export type PageEntry = {

View file

@ -19,14 +19,12 @@ import './snapshotTab.css';
import './tabbedPane.css';
import * as React from 'react';
import { useMeasure } from './helpers';
import type { Point } from '../../../common/types';
import { ActionTraceEvent } from '../../../server/trace/common/traceEvents';
export const SnapshotTab: React.FunctionComponent<{
action: ActionTraceEvent | undefined,
snapshotSizes: { [snapshotName: string]: Size },
defaultSnapshotSize: Size,
}> = ({ action, snapshotSizes, defaultSnapshotSize }) => {
}> = ({ action, defaultSnapshotSize }) => {
const [measure, ref] = useMeasure<HTMLDivElement>();
const [snapshotIndex, setSnapshotIndex] = React.useState(0);
@ -36,35 +34,44 @@ export const SnapshotTab: React.FunctionComponent<{
const actionSnapshot = snapshotMap.get('action') || snapshotMap.get('after');
const snapshots = [actionSnapshot ? { ...actionSnapshot, title: 'action' } : undefined, snapshotMap.get('before'), snapshotMap.get('after')].filter(Boolean) as { title: string, snapshotName: string }[];
let snapshotUrl = 'data:text/html,<body style="background: #ddd"></body>';
let snapshotSizeUrl: string | undefined;
let pointX: number | undefined;
let pointY: number | undefined;
if (action) {
const snapshot = snapshots[snapshotIndex];
if (snapshot && snapshot.snapshotName) {
snapshotUrl = `${window.location.origin}/snapshot/${action.metadata.pageId}?name=${snapshot.snapshotName}`;
snapshotSizeUrl = `${window.location.origin}/snapshotSize/${action.metadata.pageId}?name=${snapshot.snapshotName}`;
if (snapshot.snapshotName.includes('action')) {
pointX = action.metadata.point?.x;
pointY = action.metadata.point?.y;
}
}
}
React.useEffect(() => {
if (snapshots.length >= 1 && snapshotIndex >= snapshots.length)
setSnapshotIndex(snapshots.length - 1);
}, [snapshotIndex, snapshots]);
const iframeRef = React.createRef<HTMLIFrameElement>();
const iframeRef = React.useRef<HTMLIFrameElement>(null);
const [snapshotSize, setSnapshotSize] = React.useState(defaultSnapshotSize);
React.useEffect(() => {
if (!iframeRef.current)
return;
let snapshotUri = undefined;
let point: Point | undefined = undefined;
if (action) {
const snapshot = snapshots[snapshotIndex];
if (snapshot && snapshot.snapshotName) {
snapshotUri = `${action.metadata.pageId}?name=${snapshot.snapshotName}`;
if (snapshot.snapshotName.includes('action'))
point = action.metadata.point;
(async () => {
if (snapshotSizeUrl) {
const response = await fetch(snapshotSizeUrl);
setSnapshotSize(await response.json());
}
}
const snapshotUrl = snapshotUri ? `${window.location.origin}/snapshot/${snapshotUri}` : 'data:text/html,<body style="background: #ddd"></body>';
try {
(iframeRef.current.contentWindow as any).showSnapshot(snapshotUrl, { point });
} catch (e) {
}
}, [action, snapshotIndex, iframeRef, snapshots]);
let snapshotSize = defaultSnapshotSize;
if (snapshots[snapshotIndex] && snapshots[snapshotIndex].snapshotName)
snapshotSize = snapshotSizes[snapshots[snapshotIndex].snapshotName] || defaultSnapshotSize;
if (!iframeRef.current)
return;
try {
const point = pointX === undefined ? undefined : { x: pointX, y: pointY };
(iframeRef.current.contentWindow as any).showSnapshot(snapshotUrl, { point });
} catch (e) {
}
})();
}, [iframeRef, snapshotUrl, snapshotSizeUrl, pointX, pointY]);
const scale = Math.min(measure.width / snapshotSize.width, measure.height / snapshotSize.height);
const scaledSize = {

View file

@ -89,7 +89,7 @@ export const Workbench: React.FunctionComponent<{
</div>
<SplitView sidebarSize={300} orientation='horizontal' sidebarIsFirst={true}>
<SplitView sidebarSize={300} orientation='horizontal'>
<SnapshotTab action={selectedAction} snapshotSizes={context.snapshotSizes} defaultSnapshotSize={defaultSnapshotSize} />
<SnapshotTab action={selectedAction} defaultSnapshotSize={defaultSnapshotSize} />
<TabbedPane tabs={[
{ id: 'logs', title: 'Call', count: 0, render: () => <CallTab action={selectedAction} /> },
{ id: 'console', title: 'Console', count: consoleCount, render: () => <ConsoleTab action={selectedAction} /> },
@ -125,5 +125,4 @@ const emptyContext: ContextEntry = {
},
pages: [],
resources: [],
snapshotSizes: {},
};