Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: investigate profiling match #6

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@testing-library/react": "^13.1.1",
"@testing-library/user-event": "^14.1.1",
"@types/chai": "^4.3.1",
"@types/chrome-remote-interface": "^0.31.4",
"@types/eslint": "^8.4.1",
"@types/lodash.throttle": "^4.1.7",
"@types/mocha": "^9.1.0",
Expand All @@ -56,6 +57,7 @@
"@web/test-runner": "^0.13.27",
"@web/test-runner-playwright": "^0.8.8",
"chai": "^4.3.6",
"chrome-remote-interface": "^0.31.2",
"concurrently": "^7.1.0",
"dotenv": "^16.0.0",
"esbuild": "^0.14.36",
Expand Down
2 changes: 1 addition & 1 deletion packages/annotate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"clean": "rm -rf src/*.js src/**/*.js src/*.d.ts src/**/*.d.ts build report",
"emit": "tsc -p tsconfig-notestfiles.json --declaration --emitDeclarationOnly --declarationMap --outDir build",
"build": "node .esbuildrc.js",
"test": "mocha-esbuild **/*.small.test.ts",
"test": "mocha-esbuild **/*.test.ts",
"eslint": "eslint --ignore-path .gitignore --ext .ts --fix .",
"types": "tsc --noEmit",
"prettier": "prettier --ignore-path .gitignore --write .",
Expand Down
2 changes: 2 additions & 0 deletions packages/e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
remote-profile
*.js
67 changes: 63 additions & 4 deletions packages/e2e/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,9 @@ <h6>Non igitur bene.</h6>
nos admirabilia dicamus.
</p>
</div>
<script type="module">
import { TextNodesFromDOM, Match, annotateDOM } from '../annotate/build';

const insensitive = new Map([
<script type="module">
import { TextNodesFromDOM, Match, annotateDOM } from '../annotate/build/index.js';
const ipsumCI = new Map([
['123', ['Quamquam', 'Quonam, inquit, modo']],
['456', ['Moriatur', 'arbitrantur', 'Ut pulsi recurrant']],
['789', ['vacuitatem doloris non propter utilitatem solum']],
Expand All @@ -358,6 +357,66 @@ <h6>Non igitur bene.</h6>
textNodesFromDOM.watchDOM((ns) => annotateDOM(ns, match));
textNodesFromDOM.watchScroll((ns) => annotateDOM(ns, match));
</script>
<!-- use the below to explore profiling and memory in the chrome devtools - change the type to 'module' and disable the above script-->
<script type="text/plain">
import { TextNodesFromDOM, Match, annotateDOM } from '../annotate/build/index.js';
function getRandomInt(min, max) {
return Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min)) + Math.ceil(min)); //The maximum is exclusive and the minimum is inclusive
}

function getRndString(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 -';
const charactersLength = characters.length;
for ( let i = 0; i < length; i++ ) {
result += characters[Math.floor(Math.random() * charactersLength)];
}
return result;
}

function createListForMap(len){
return Array(len).fill('').map((v, i) => [i.toString(10), [getRndString(getRandomInt(4, 15))]])
}

// cs5+ci5 = retained size 10972 bytes
// const ipsumCS = new Map(createListForMap(5))
// const ipsumCI = new Map(createListForMap(5))

// cs50+ci50 = retained size 84924 bytes
// const ipsumCS = new Map(createListForMap(50))
// const ipsumCI = new Map(createListForMap(50))

// cs500+ci500 = retained size 790872 bytes
// const ipsumCS = new Map(createListForMap(500))
// const ipsumCI = new Map(createListForMap(500))

// cs5000+ci5000 = retained size 7118240 bytes
// const ipsumCS = new Map(createListForMap(5000))
// const ipsumCI = new Map(createListForMap(5000))

// cs9999+ci1 = retained size 6844308 bytes
const ipsumCS = new Map(createListForMap(9999))
const ipsumCI = new Map(createListForMap(1))

// cs5000+ci5000 is (7118240 - 6844308)*100/6844308 larger than cs9999+ci1

setTimeout(() => {
// const ipsumCI = new Map([
// ['123', ['Quamquam', 'Quonam, inquit, modo']],
// ['456', ['Moriatur', 'arbitrantur', 'Ut pulsi recurrant']],
// ['789', ['vacuitatem doloris non propter utilitatem solum']],
// ['101112', ['pain', 'dolori']]
// ]);
// const ipsumCS = new Map([['321', ['Aristonem']], ['654', ['Chryippo']], ['978', ['Socratica']], ['121110', ['Platonis']]]);
const opts = { tag: 'x-annotate' };
const match = new Match(ipsumCI, ipsumCS, opts);
const textNodesFromDOM = new TextNodesFromDOM(document.body, [opts.tag.toUpperCase()]);

annotateDOM(textNodesFromDOM.walk(document.body), match);
textNodesFromDOM.watchDOM((ns) => annotateDOM(ns, match));
textNodesFromDOM.watchScroll((ns) => annotateDOM(ns, match));
}, 10000)
</script>
<script>
// This is to test the mutation observer works
setTimeout(() => {
Expand Down
9 changes: 9 additions & 0 deletions packages/e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "module",
"scripts": {
"start": "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=9222 --user-data-dir=remote-profile",
"run": "cd .. && python3 -m http.server 9222",
"test": "node index.mjs",
"perf": "tsc && node perf.js"
}
}
86 changes: 86 additions & 0 deletions packages/e2e/perf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import CDP from "chrome-remote-interface";
import ProtocolApi from "devtools-protocol/types/protocol-proxy-api";

// workaround for type declaration issues in cdp lib
type ForceClientT = {
Profiler: ProtocolApi.ProfilerApi;
Page: ProtocolApi.PageApi;
Tracing: ProtocolApi.TracingApi;
Network: ProtocolApi.NetworkApi;
};

async function trace(url: string) {
let client: ForceClientT;
const response: any[] = [];
let profile: any;
try {
/**
* Establish a client to the chrome devtools opened with remote debugging port
* http://127.0.0.1:9222/
*/
client = (await CDP({ port: 9222 })) as unknown as ForceClientT;
const { Network, Page, Profiler } = client;
await Promise.all([
Network.enable({}),
Page.enable(),
Profiler.enable(),
Profiler.setSamplingInterval({ interval: 100 }),
]);
await Profiler.start();
/**
* Register a callback to intercept all the requests
*/
Network.on("responseReceived", (params) => response.push(params.response));

//Navigate to the url
await Page.navigate({ url });

//Wait for the page to load
await Page.on("loadEventFired", (params) => {});
profile = await Profiler.stop().then((p) => p.profile);
} catch (err) {
console.error(err);
}
// finally {
// if (client) {
// await client.close();
// }
// }
// @ts-ignore
client.close();
return { response, profile };
}

function groupBy(arr, key) {
return arr.reduce((groups, item) => {
const val = item[key];
groups[val] = groups[val] || [];
groups[val].push(item);
return groups;
}, {});
}

/**
* Get all the response, group and count them by mime-type.
*/
const fn = async () => {
const { response } = await trace("https://github.com");
const groupedByType = groupBy(response, "mimeType");
const countByType = Object.keys(groupedByType).map((k) => {
const count = groupedByType[k].length;
return {
type: k,
count,
};
});

console.log(countByType);
};

const getProfile = async () => {
const { profile } = await trace("http://localhost:9222/e2e");
console.log("|> profile ===> ", profile);
};

// fn();
getProfile();
19 changes: 19 additions & 0 deletions packages/e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"include": ["./perf.ts"],
"compilerOptions": {
"useDefineForClassFields": true,
"lib": ["esnext"],
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"sourceMap": false,
"noImplicitAny": false,
"typeRoots": ["./node_modules/@types", "../../node_modules/@types"]
}
}