Skip to content

Commit 31b235b

Browse files
JeanMechepkozlowski-opensource
authored andcommitted
refactor(platform-server): Add private profiler. (angular#56274)
The commit adds a private profiler to investigate SSR performance. PR Close angular#56274
1 parent 0beba0d commit 31b235b

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

packages/platform-server/src/private_export.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ export {
1111
SERVER_RENDER_PROVIDERS as ɵSERVER_RENDER_PROVIDERS,
1212
} from './server';
1313
export {SERVER_CONTEXT as ɵSERVER_CONTEXT} from './utils';
14+
export {
15+
enableSsrProfiling as ɵenableSsrProfiling,
16+
disableSsrProfiling as ɵdisableSsrProfiling,
17+
} from './profiler';
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
const PERFORMANCE_MARK_PREFIX = '🅰️';
10+
11+
let enablePerfLogging = false;
12+
13+
export function runAndMeasurePerf<T>(label: string, method: () => T): T {
14+
if (!enablePerfLogging) {
15+
return method();
16+
}
17+
18+
const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;
19+
const startLabel = `start:${labelName}`;
20+
const endLabel = `end:${labelName}`;
21+
22+
const end = () => {
23+
/* tslint:disable:ban */
24+
performance.mark(endLabel);
25+
performance.measure(labelName, startLabel, endLabel);
26+
performance.clearMarks(startLabel);
27+
performance.clearMarks(endLabel);
28+
/* tslint:enable:ban */
29+
};
30+
31+
/* tslint:disable:ban */
32+
performance.mark(startLabel);
33+
/* tslint:enable:ban */
34+
35+
const returnValue = method();
36+
if (returnValue instanceof Promise) {
37+
return returnValue.finally(() => end()) as T;
38+
} else {
39+
end();
40+
return returnValue;
41+
}
42+
}
43+
44+
let warningLogged = false;
45+
/**
46+
* This enables an internal performance profiler for SSR apps
47+
*
48+
* It should not be imported in application code
49+
*/
50+
export function enableSsrProfiling() {
51+
if (
52+
!warningLogged &&
53+
(typeof performance === 'undefined' || !performance.mark || !performance.measure)
54+
) {
55+
warningLogged = true;
56+
console.warn('Performance API is not supported on this platform');
57+
return;
58+
}
59+
60+
enablePerfLogging = true;
61+
}
62+
export function disableSsrProfiling() {
63+
enablePerfLogging = false;
64+
}

packages/platform-server/src/utils.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {PlatformState} from './platform_state';
2626
import {platformServer} from './server';
2727
import {BEFORE_APP_SERIALIZED, INITIAL_CONFIG} from './tokens';
2828
import {createScript} from './transfer_state';
29+
import {runAndMeasurePerf} from './profiler';
2930

3031
/**
3132
* Event dispatch (JSAction) script is inlined into the HTML by the build
@@ -145,7 +146,9 @@ function insertEventRecordScript(
145146
// This is defined in packages/core/primitives/event-dispatch/contract_binary.ts
146147
const replayScriptContents = `window.__jsaction_bootstrap('ngContracts', document.body, ${JSON.stringify(
147148
appId,
148-
)}, ${JSON.stringify(Array.from(regular))}${capture.size ? ',' + JSON.stringify(Array.from(capture)) : ''});`;
149+
)}, ${JSON.stringify(Array.from(regular))}${
150+
capture.size ? ',' + JSON.stringify(Array.from(capture)) : ''
151+
});`;
149152

150153
const replayScript = createScript(doc, replayScriptContents, nonce);
151154

@@ -272,7 +275,10 @@ export async function renderApplication<T>(
272275
bootstrap: () => Promise<ApplicationRef>,
273276
options: {document?: string | Document; url?: string; platformProviders?: Provider[]},
274277
): Promise<string> {
275-
const platformRef = createServerPlatform(options);
276-
const applicationRef = await bootstrap();
277-
return _render(platformRef, applicationRef);
278+
return runAndMeasurePerf('renderApplication', async () => {
279+
const platformRef = createServerPlatform(options);
280+
281+
const applicationRef = await bootstrap();
282+
return _render(platformRef, applicationRef);
283+
});
278284
}

0 commit comments

Comments
 (0)