@paulirish/trace_engine 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/PAUL.readme.md ADDED
@@ -0,0 +1,5 @@
1
+ # see readme for cmds
2
+
3
+ # some types thing that might work
4
+
5
+ node out/Typed/../../third_party/typescript/../../node_modules/typescript/bin/tsc -p out/Typed/gen/front_end/models/trace/trace-tsconfig.json # this then has js/map/d.ts. should be able to use for typs
package/README.md CHANGED
@@ -18,19 +18,39 @@ console.log(processor.data)
18
18
 
19
19
  See the included `analyze-trace.mjs` a runnable invocation.
20
20
 
21
- ## Building standalone
21
+ ## Maintainer cheatsheet
22
22
 
23
- ```sh
24
- # parent doc: go/btlax
23
+ See also http://go/btlax
25
24
 
26
- # these in no particular order..
25
+ #### Build, run, extract
27
26
 
27
+ ```sh
28
+ # build bundle with esbuild
28
29
  front_end/models/trace/build-trace-engine-lib.sh
29
30
 
31
+ # run
32
+ node scripts/analyze-trace.mjs test/unittests/fixtures/traces/web-dev.json.gz
33
+
34
+ # test
35
+ node scripts/test/test-trace-engine.mjs
36
+
37
+ # copy built files to $HOME/code/trace_engine
30
38
  front_end/models/trace/copy-build-trace-engine-for-publish.sh
39
+ ```
40
+
41
+ #### Test and publish
42
+
43
+ ```sh
44
+ # switch to standalone
45
+ cd $HOME/code/trace_engine
31
46
 
32
- node out/Typed/../../third_party/typescript/../../node_modules/typescript/bin/tsc -p out/Typed/gen/front_end/models/trace/trace-tsconfig.json # this then has js/map/d.ts. should be able to use for typs
47
+ # test
48
+ node test/test-trace-engine.mjs
33
49
 
50
+ # bump and publish
51
+ npm version v0.0.XXX # Manually determine next version
52
+ npm publish --access public --dry-run
53
+ npm publish --access public
34
54
  ```
35
55
 
36
56
  ## High level architecture
package/analyze-trace.mjs CHANGED
@@ -5,26 +5,35 @@
5
5
  // Run this first:
6
6
  // front_end/models/trace/build-trace-engine-lib.sh
7
7
 
8
- import fs from 'fs';
9
- import zlib from 'zlib';
8
+ import fs from 'node:fs';
9
+ import zlib from 'node:zlib';
10
10
  // eslint-disable-next-line rulesdir/es_modules_import
11
11
  import * as TraceModel from './trace.mjs';
12
12
 
13
13
  polyfillDOMRect();
14
14
 
15
- // If run as CLI, parse the argv trace (or a fallback)
16
- if (import.meta.url.endsWith(process.argv[1])) {
17
- const filename = process.argv.at(2) ?? './test/invalid-animation-events.json.gz';
15
+
16
+ export async function analyzeTrace(filename) {
18
17
  const traceEvents = loadTraceEventsFromFile(filename);
19
18
 
20
19
  // Primary usage:
21
20
  const processor = TraceModel.Processor.TraceProcessor.createWithAllHandlers(); // aka `fullTraceEngine`
22
21
  await processor.parse(traceEvents);
22
+ return processor.data;
23
+ }
23
24
 
24
- console.log(processor.data);
25
- console.assert(processor.data.Renderer.allRendererEvents.length);
25
+ // If run as CLI, parse the argv trace (or a fallback)
26
+ if (import.meta.url.endsWith(process?.argv[1])) {
27
+ cli();
26
28
  }
27
29
 
30
+ async function cli() {
31
+ const filename = process.argv.at(2);
32
+ const traceModel = await analyzeTrace(filename);
33
+ console.log(traceModel);
34
+ }
35
+
36
+
28
37
  /**
29
38
  * @param {string=} filename
30
39
  * @returns TraceEvent[]
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@paulirish/trace_engine",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "",
5
5
  "main": "trace.mjs",
6
6
  "scripts": {
7
- "test": "node analyze-trace.mjs"
7
+ "test": "node test/test-trace-engine.mjs",
8
+ "prepublishOnly": "npm test"
8
9
  },
9
10
  "type": "module",
10
11
  "keywords": [],
@@ -0,0 +1,52 @@
1
+ // Copyright 2023 The Chromium Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import test from 'node:test';
6
+ import {strict as assert} from 'assert';
7
+
8
+ import {analyzeTrace} from '../analyze-trace.mjs';
9
+
10
+ const filename = './test/invalid-animation-events.json.gz';
11
+ const data = await analyzeTrace(filename);
12
+
13
+ test('key values are populated', t => {
14
+ assert.equal(data.Renderer.allRendererEvents.length > 90_000, true);
15
+ assert.equal(data.Screenshots.length > 2, true);
16
+ assert.equal(data.Meta.threadsInProcess.size > 2, true);
17
+ assert.equal(data.Meta.mainFrameNavigations.length > 0, true);
18
+ });
19
+
20
+ test('numeric values are set and look legit', t => {
21
+ const shouldBeNumbers = [
22
+ data.Meta.traceBounds.min,
23
+ data.Meta.traceBounds.max,
24
+ data.Meta.traceBounds.range,
25
+ data.Meta.browserProcessId,
26
+ data.Meta.browserThreadId,
27
+ data.Meta.gpuProcessId,
28
+ data.Meta.gpuThreadId,
29
+ Array.from(data.Meta.topLevelRendererIds.values()).at(0),
30
+ Array.from(data.Meta.frameByProcessId.keys()).at(0),
31
+ ];
32
+ for (const datum of shouldBeNumbers) {
33
+ assert.equal(isNaN(datum), false);
34
+ assert.equal(typeof datum, 'number');
35
+ assert.equal(datum > 10, true);
36
+ }
37
+ });
38
+
39
+ test('string values are set and look legit', t => {
40
+ const shouldBeStrings = [
41
+ data.Meta.mainFrameId,
42
+ data.Meta.mainFrameURL,
43
+ Array.from(data.Meta.navigationsByFrameId.keys()).at(0),
44
+ Array.from(data.Meta.navigationsByNavigationId.keys()).at(0),
45
+ data.Meta.mainFrameId,
46
+ ];
47
+
48
+ for (const datum of shouldBeStrings) {
49
+ assert.equal(typeof datum, 'string');
50
+ assert.equal(datum.length > 10, true);
51
+ }
52
+ });
package/trace.mjs CHANGED
@@ -2040,18 +2040,34 @@ function walkTreeFromEntry(entryToNode3, rootEntry, onEntryStart, onEntryEnd) {
2040
2040
  }
2041
2041
  walkTreeByNode(entryToNode3, startNode, onEntryStart, onEntryEnd);
2042
2042
  }
2043
- function walkEntireTree(entryToNode3, tree, onEntryStart, onEntryEnd) {
2043
+ function walkEntireTree(entryToNode3, tree, onEntryStart, onEntryEnd, traceWindowToInclude) {
2044
2044
  for (const rootNode of tree.roots) {
2045
- walkTreeByNode(entryToNode3, rootNode, onEntryStart, onEntryEnd);
2045
+ walkTreeByNode(entryToNode3, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude);
2046
2046
  }
2047
2047
  }
2048
- function walkTreeByNode(entryToNode3, rootNode, onEntryStart, onEntryEnd) {
2048
+ function walkTreeByNode(entryToNode3, rootNode, onEntryStart, onEntryEnd, traceWindowToInclude) {
2049
+ if (traceWindowToInclude && !treeNodeIsInWindow(rootNode, traceWindowToInclude)) {
2050
+ return;
2051
+ }
2049
2052
  onEntryStart(rootNode.entry);
2050
2053
  for (const child of rootNode.children) {
2051
- walkTreeByNode(entryToNode3, child, onEntryStart, onEntryEnd);
2054
+ walkTreeByNode(entryToNode3, child, onEntryStart, onEntryEnd, traceWindowToInclude);
2052
2055
  }
2053
2056
  onEntryEnd(rootNode.entry);
2054
2057
  }
2058
+ function treeNodeIsInWindow(node, traceWindow) {
2059
+ const { startTime, endTime } = eventTimingsMicroSeconds(node.entry);
2060
+ if (startTime >= traceWindow.min && startTime < traceWindow.max) {
2061
+ return true;
2062
+ }
2063
+ if (endTime > traceWindow.min && endTime <= traceWindow.max) {
2064
+ return true;
2065
+ }
2066
+ if (startTime <= traceWindow.min && endTime >= traceWindow.max) {
2067
+ return true;
2068
+ }
2069
+ return false;
2070
+ }
2055
2071
 
2056
2072
  // front_end/models/trace/handlers/GPUHandler.ts
2057
2073
  var handlerState3 = 1 /* UNINITIALIZED */;
@@ -3303,6 +3319,8 @@ __export(WarningsHandler_exports, {
3303
3319
  FORCED_LAYOUT_AND_STYLES_THRESHOLD: () => FORCED_LAYOUT_AND_STYLES_THRESHOLD,
3304
3320
  LONG_MAIN_THREAD_TASK_THRESHOLD: () => LONG_MAIN_THREAD_TASK_THRESHOLD,
3305
3321
  data: () => data12,
3322
+ deps: () => deps6,
3323
+ finalize: () => finalize11,
3306
3324
  handleEvent: () => handleEvent12,
3307
3325
  reset: () => reset12
3308
3326
  });
@@ -3350,6 +3368,15 @@ function handleEvent12(event) {
3350
3368
  return;
3351
3369
  }
3352
3370
  }
3371
+ function deps6() {
3372
+ return ["UserInteractions"];
3373
+ }
3374
+ async function finalize11() {
3375
+ const longInteractions = data10().interactionsOverThreshold;
3376
+ for (const interaction of longInteractions) {
3377
+ storeWarning(interaction, "LONG_INTERACTION");
3378
+ }
3379
+ }
3353
3380
  function data12() {
3354
3381
  return {
3355
3382
  perEvent: new Map(warningsPerEvent),
@@ -3361,7 +3388,7 @@ function data12() {
3361
3388
  var WorkersHandler_exports = {};
3362
3389
  __export(WorkersHandler_exports, {
3363
3390
  data: () => data13,
3364
- finalize: () => finalize11,
3391
+ finalize: () => finalize12,
3365
3392
  handleEvent: () => handleEvent13,
3366
3393
  initialize: () => initialize5,
3367
3394
  reset: () => reset13
@@ -3389,7 +3416,7 @@ function handleEvent13(event) {
3389
3416
  sessionIdEvents.push(event);
3390
3417
  }
3391
3418
  }
3392
- async function finalize11() {
3419
+ async function finalize12() {
3393
3420
  if (handlerState8 !== 2 /* INITIALIZED */) {
3394
3421
  throw new Error("Handler is not initialized");
3395
3422
  }
@@ -3508,8 +3535,8 @@ __export(RendererHandler_exports, {
3508
3535
  assignThreadName: () => assignThreadName,
3509
3536
  buildHierarchy: () => buildHierarchy,
3510
3537
  data: () => data17,
3511
- deps: () => deps6,
3512
- finalize: () => finalize13,
3538
+ deps: () => deps7,
3539
+ finalize: () => finalize14,
3513
3540
  handleEvent: () => handleEvent17,
3514
3541
  handleUserConfig: () => handleUserConfig,
3515
3542
  initialize: () => initialize7,
@@ -3523,7 +3550,7 @@ __export(RendererHandler_exports, {
3523
3550
  var SamplesHandler_exports = {};
3524
3551
  __export(SamplesHandler_exports, {
3525
3552
  data: () => data16,
3526
- finalize: () => finalize12,
3553
+ finalize: () => finalize13,
3527
3554
  getProfileCallFunctionName: () => getProfileCallFunctionName,
3528
3555
  handleEvent: () => handleEvent16,
3529
3556
  initialize: () => initialize6,
@@ -3682,7 +3709,7 @@ var CPUProfileDataModel = class extends ProfileTreeModel {
3682
3709
  this.profileHead = this.translateProfileTree(profile.nodes);
3683
3710
  this.initialize(this.profileHead);
3684
3711
  this.extractMetaNodes();
3685
- if (this.samples) {
3712
+ if (this.samples?.length) {
3686
3713
  this.sortSamples();
3687
3714
  this.normalizeTimestamps();
3688
3715
  this.fixMissingSamples();
@@ -4138,7 +4165,7 @@ function handleEvent16(event) {
4138
4165
  return;
4139
4166
  }
4140
4167
  }
4141
- async function finalize12() {
4168
+ async function finalize13() {
4142
4169
  if (handlerState9 !== 2 /* INITIALIZED */) {
4143
4170
  throw new Error("Samples Handler is not initialized");
4144
4171
  }
@@ -4245,7 +4272,7 @@ function handleEvent17(event) {
4245
4272
  allRendererEvents.push(event);
4246
4273
  }
4247
4274
  }
4248
- async function finalize13() {
4275
+ async function finalize14() {
4249
4276
  if (handlerState10 !== 2 /* INITIALIZED */) {
4250
4277
  throw new Error("Renderer Handler is not initialized");
4251
4278
  }
@@ -4389,7 +4416,7 @@ function makeCompleteEvent(event) {
4389
4416
  completeEventStack.push(syntheticComplete);
4390
4417
  return syntheticComplete;
4391
4418
  }
4392
- function deps6() {
4419
+ function deps7() {
4393
4420
  return ["Meta", "Samples", "AuctionWorklets"];
4394
4421
  }
4395
4422
 
@@ -5281,9 +5308,9 @@ function sortHandlers(traceHandlers) {
5281
5308
  if (!handler) {
5282
5309
  return;
5283
5310
  }
5284
- const deps7 = handler.deps?.();
5285
- if (deps7) {
5286
- deps7.forEach(visitHandler);
5311
+ const deps8 = handler.deps?.();
5312
+ if (deps8) {
5313
+ deps8.forEach(visitHandler);
5287
5314
  }
5288
5315
  sortedMap.set(handlerName, handler);
5289
5316
  };