Skip to content

Commit 2b7ac09

Browse files
committed
perf: avoid Object.create(null)
1 parent c8cd26a commit 2b7ac09

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

src/context.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import type { RouterContext } from "./types";
22

3+
const RouterStaticMap = /* @__PURE__ */ (() => {
4+
const C = function () {};
5+
C.prototype = Object.create(null);
6+
return C;
7+
})() as unknown as { new (): Record<string, any> };
8+
39
/**
410
* Create a new router context.
511
*/
612
export function createRouter<T = unknown>(): RouterContext<T> {
713
const ctx: RouterContext<T> = {
814
root: { key: "" },
9-
static: Object.create(null),
15+
static: new RouterStaticMap(),
1016
};
1117
return ctx;
1218
}

src/operations/_utils.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@ export function splitPath(path: string) {
44
return path.split("/").filter(Boolean);
55
}
66

7+
const RouteParams = /* @__PURE__ */ (() => {
8+
const C = function RouteParams() {};
9+
C.prototype = Object.create(null);
10+
return C;
11+
})() as unknown as { new (): Record<string, any> };
12+
713
export function getMatchParams(
814
segments: string[],
915
paramsMap: ParamsIndexMap,
1016
): MatchedRoute["params"] {
11-
const params = Object.create(null);
17+
const params = new RouteParams();
1218
for (const [index, name] of paramsMap) {
1319
const segment =
1420
index < 0 ? segments.slice(-1 * index).join("/") : segments[index];

src/operations/add.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import type { RouterContext, ParamsIndexMap } from "../types";
22
import { splitPath } from "./_utils";
33

4+
const NodeStaticMap = /* @__PURE__ */ (() => {
5+
const C = function () {};
6+
C.prototype = Object.create(null);
7+
return C;
8+
})() as unknown as { new (): Record<string, any> };
9+
10+
const NodeMethodsMap = /* @__PURE__ */ (() => {
11+
const C = function () {};
12+
C.prototype = Object.create(null);
13+
return C;
14+
})() as unknown as { new (): Record<string, any> };
15+
416
/**
517
* Add a route to the router context.
618
*/
@@ -53,7 +65,7 @@ export function addRoute<T>(
5365
} else {
5466
const staticNode = { key: segment };
5567
if (!node.static) {
56-
node.static = Object.create(null);
68+
node.static = new NodeStaticMap();
5769
}
5870
node.static![segment] = staticNode;
5971
node = staticNode;
@@ -63,7 +75,7 @@ export function addRoute<T>(
6375
// Assign index, params and data to the node
6476
const hasParams = paramsMap.length > 0;
6577
if (!node.methods) {
66-
node.methods = Object.create(null);
78+
node.methods = new NodeMethodsMap();
6779
}
6880
if (!node.methods![method]) {
6981
node.methods![method] = [];

test/bench/bundle.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ describe("benchmark", () => {
1313
findAllRoutes();
1414
`;
1515
const { bytes, gzipSize } = await getBundleSize(code);
16-
// console.log("bundle size", { bytes, gzipSize });
17-
expect(bytes).toBeLessThanOrEqual(2500); // <2.5kb
18-
expect(gzipSize).toBeLessThanOrEqual(1000); // <1kb
16+
console.log("bundle size", { bytes, gzipSize });
17+
expect(bytes).toBeLessThanOrEqual(3000); // <3kb
18+
expect(gzipSize).toBeLessThanOrEqual(1500); // <1.5kb
1919
});
2020
});
2121

0 commit comments

Comments
 (0)