web: add benchmarks

This commit is contained in:
Abdullah Atta
2024-11-13 13:47:31 +05:00
committed by Abdullah Atta
parent a011857286
commit 2f4590fbb6
6 changed files with 267 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2023 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { chromium } from "playwright";
import { Bench } from "tinybench";
import { withCodSpeed } from "@codspeed/tinybench-plugin";
import { spawn } from "child_process";
const TESTS = [
{
name: "root import",
start: "import:root",
end: "start:app"
},
{
name: "app startup",
start: "start:app",
end: "render:app"
},
{
name: "database load",
start: "load:database",
end: "render:app"
},
{
name: "signup page load",
start: "start:app",
end: "load:auth",
route: "/signup"
}
];
async function startServer() {
return new Promise((resolve, reject) => {
const server = spawn("npx", ["serve", "-s", "build"]);
server.stdout.on("data", (data) => {
if (data.toString().includes("Accepting connections")) {
console.log(data.toString());
resolve(server);
}
});
server.stderr.on("data", (data) => {
reject(data.toString());
});
server.on("error", (error) => {
reject(error);
});
});
}
await startServer();
const browser = await chromium.launch();
for (const testCase of TESTS) {
/**
* @type {import("playwright").BrowserContext}
*/
let context;
/**
* @type {import("playwright").Page}
*/
let page;
const bench = withCodSpeed(
new Bench({
async setup() {
context = await browser.newContext({
baseURL: "http://localhost:3000"
});
await context.addInitScript({
content: `window.localStorage.setItem("skipInitiation", "true");
const observer = new PerformanceObserver((list, observer) => {
list.getEntries().forEach((entry) => {
if (entry.entryType === "mark" && entry.name === "${testCase.end}") {
observer.disconnect();
console.log(
"ended: ${testCase.name}",
performance.measure(
"${testCase.end}",
"${testCase.start}",
"${testCase.end}"
).duration
);
window.close();
}
});
});
observer.observe({ entryTypes: ["mark"] });`
});
page = await context.newPage();
},
async teardown() {
await context.close();
}
})
);
bench.add(testCase.name, async () => {
await page.goto(testCase.route || "/");
await page.waitForEvent("console", {
predicate(consoleMessage) {
return consoleMessage.text().startsWith(`ended: ${testCase.name}`);
}
});
});
await bench.warmup();
await bench.run();
console.table(bench.table());
}
await browser.close();

View File

@@ -88,6 +88,7 @@
},
"devDependencies": {
"@babel/core": "^7.22.5",
"@codspeed/tinybench-plugin": "^3.1.1",
"@playwright/test": "^1.43.1",
"@swc/core": "^1.5.24",
"@swc/plugin-react-remove-properties": "^2.0.4",
@@ -31023,7 +31024,9 @@
"@lingui/swc-plugin": "^4.0.10",
"@types/react": "^18.2.39",
"babel-plugin-macros": "^3.1.0",
"nodemon": "^3.1.7",
"react": "18.2.0",
"rollup": "^4.24.4",
"typescript": "5.5.3",
"vite": "^5.4.8",
"vite-plugin-dts": "^4.2.3",
@@ -40525,6 +40528,33 @@
"pnpm": ">=5"
}
},
"node_modules/@codspeed/core": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@codspeed/core/-/core-3.1.1.tgz",
"integrity": "sha512-ONhERVDAtkm0nc+FYPivDozoMOlNUP2BWRBFDJYATGA18Iap5Kd2mZ1/Lwz54RB5+g+3YDOpsvotHa4hd3Q+7Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"axios": "^1.4.0",
"find-up": "^6.3.0",
"form-data": "^4.0.0",
"node-gyp-build": "^4.6.0"
}
},
"node_modules/@codspeed/tinybench-plugin": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@codspeed/tinybench-plugin/-/tinybench-plugin-3.1.1.tgz",
"integrity": "sha512-LVF4End0kDU9V7CzuwAcmngSPJNnpduPnr+csOKvcG++FsYwfUuBJ1rvLPtv6yTkvxpUmUEsj6VA7/AEIBGZVw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@codspeed/core": "^3.1.1",
"stack-trace": "1.0.0-pre2"
},
"peerDependencies": {
"tinybench": "^2.3.0"
}
},
"node_modules/@dnd-kit/accessibility": {
"version": "3.1.0",
"license": "MIT",
@@ -44735,6 +44765,23 @@
"version": "1.1.0",
"license": "MIT"
},
"node_modules/find-up": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
"integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
"dev": true,
"license": "MIT",
"dependencies": {
"locate-path": "^7.1.0",
"path-exists": "^5.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/follow-redirects": {
"version": "1.15.3",
"funding": [
@@ -46210,6 +46257,22 @@
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/locate-path": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
"integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-locate": "^6.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"license": "MIT"
@@ -47438,6 +47501,18 @@
}
}
},
"node_modules/node-gyp-build": {
"version": "4.8.3",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.3.tgz",
"integrity": "sha512-EMS95CMJzdoSKoIiXo8pxKoL8DYxwIZXYlLmgPb8KUv794abpnLK6ynsCAWNliOjREKruYKdzbh76HHYUHX7nw==",
"dev": true,
"license": "MIT",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
@@ -47637,6 +47712,38 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
"integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"p-limit": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate/node_modules/p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
"integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"yocto-queue": "^1.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parent-module": {
"version": "1.0.1",
"license": "MIT",
@@ -47667,6 +47774,16 @@
"version": "6.0.1",
"license": "MIT"
},
"node_modules/path-exists": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
"integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/path-is-absolute": {
"version": "1.0.1",
"devOptional": true,
@@ -48964,6 +49081,16 @@
"version": "1.0.3",
"license": "BSD-3-Clause"
},
"node_modules/stack-trace": {
"version": "1.0.0-pre2",
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-1.0.0-pre2.tgz",
"integrity": "sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/stackback": {
"version": "0.0.2",
"dev": true,

View File

@@ -86,6 +86,7 @@
},
"devDependencies": {
"@babel/core": "^7.22.5",
"@codspeed/tinybench-plugin": "^3.1.1",
"@playwright/test": "^1.43.1",
"@swc/core": "^1.5.24",
"@swc/plugin-react-remove-properties": "^2.0.4",

View File

@@ -53,7 +53,9 @@ locale.then(({ default: locale }) => {
});
i18n.activate("en");
performance.mark("import:root");
import("./root").then(({ startApp }) => {
performance.mark("start:app");
startApp();
});
});

View File

@@ -54,6 +54,7 @@ export async function startApp() {
await useKeyStore.getState().init();
performance.mark("load:database");
loadDatabase(
path !== "/sessionexpired" || Config.get("sessionExpired", false)
? "db"
@@ -145,6 +146,7 @@ function RouteWrapper(props: {
</Text>
</div>
);
performance.mark("render:app");
return <Component route={routeProps?.route || "login:email"} />;
}

View File

@@ -198,6 +198,7 @@ export function HeadlessAuth(props: AuthProps) {
db.user.getUser().then((user) => {
if (user && authorizedRoutes.includes(route) && !isSessionExpired())
return openURL("/", { authenticated: true });
performance.mark("load:auth");
setIsReady(true);
});
}, [route, openURL]);