Skip to content

Commit

Permalink
perf: add ENCODING_UTF8 constant and refactor Response class
Browse files Browse the repository at this point in the history
This commit adds a new constant `ENCODING_UTF8` to the `common.ts` file.
It also refactors the `Response` class in the `Response.ts` file
by replacing all instances of `"utf-8"` with this new constant.
Additionally, it replaces all private method calls to `#send()` with `$end()`.
Finally, it updates some comments for clarity.
  • Loading branch information
ardalanamini committed Jun 20, 2023
1 parent a02556a commit d668000
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/popular-laws-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@foxify/http": patch
---

improve http response performance
44 changes: 22 additions & 22 deletions benchmarks/foxify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,48 @@
┌─────────────────────────────┬──────────────┬────────┬───────────┬──────────────┬─────────────────┐
* │ Version │ Router │ Req/Sec │ Latency (ms) │ Throughput (MB) │
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ foxify-old │ 0.10.20 │ ✓ │ 103,507.2 │ 9.15 │ 16.98
│ foxify-old │ 0.10.20 │ ✓ │ 103,123.2 │ 9.18 │ 16.91
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ fastify │ 4.18.0 │ ✓ │ 99,308.8 │ 9.56 │ 17.80
│ fastify │ 4.18.0 │ ✓ │ 99,680.0 │ 9.52 │ 17.88
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
bare │ 18.16.097,555.2 9.76 │ 16.00
foxify │ 1.0.0-beta.091,321.610.43 │ 16.28
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ foxify │ 1.0.0-beta.0 │ ✓ │ 91,680.010.4016.35
│ foxify-old-with-middlewares │ 0.10.20 │ ✓ │ 86,009.611.1130.75
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
foxify-old-with-middlewares 0.10.20 │ ✓ │ 85,804.8 │ 11.1430.68
polka 0.5.2 │ ✓ │ 85,536.0 │ 11.1811.42
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
polka 0.5.2 │ │ 85,702.4 │ 11.1611.44
koa 2.14.2 │ │ 85,280.0 │ 11.2115.21
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ rayo │ 1.4.0 │ ✓ │ 84,742.4 │ 11.29 │ 11.32
│ rayo │ 1.4.0 │ ✓ │ 84,921.6 │ 11.27 │ 11.34
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
koa 2.14.2 │ ✗ │ 84,371.2 │ 11.3215.04
micro10.0.1 │ ✗ │ 81,427.2 │ 11.7614.53
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
micro │ 10.0.1 │ 80,774.4 │ 11.8714.40
foxify-with-middlewares │ 1.0.0-beta.0 │ 80,864.0 │ 11.8630.08
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
foxify-with-middlewares │ 1.0.0-beta.080,697.611.8830.01
bare │ 18.16.078,624.012.2212.90
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
koa-router12.0.0 │ 76,204.8 │ 12.6013.59
connect 3.7.0 │ 75,180.8 │ 12.7912.33
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
connect 3.7.0 │ 75,782.4 │ 12.6812.43
koa-router12.0.0 │ 74,528.0 │ 12.9113.29
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ hapi │ 21.3.2 │ ✓ │ 73,337.6 │ 13.10 │ 13.08
│ hapi │ 21.3.2 │ ✓ │ 73,760.0 │ 13.03 │ 13.15
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
connect-router │ 1.3.8 │ ✓ │ 71,328.0 │ 13.50 │ 11.70
trek-engine-router │ 1.2.0 │ ✓ │ 70,752.0 │ 13.63 │ 11.61
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
trek-engine-router │ 1.2.0 │ ✓ │ 71,046.4 │ 13.57 │ 11.65
connect-router │ 1.3.8 │ ✓ │ 70,483.2 │ 13.68 │ 11.56
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ trek-engine │ 1.0.5 │ ✗ │ 70,422.4 │ 13.68 │ 11.55
│ trek-engine │ 1.0.5 │ ✗ │ 69,446.4 │ 13.89 │ 11.39
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ micro-router │ 3.1.3 │ ✓ │ 58,729.6 │ 16.51 │ 10.47
│ micro-router │ 3.1.3 │ ✓ │ 58,819.2 │ 16.47 │ 10.49
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ take-five │ 2.0.0 │ ✓ │ 36,534.426.8013.59
│ take-five │ 2.0.0 │ ✓ │ 37,692.825.9714.02
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ express │ 4.18.2 │ ✓ │ 25,860.8 │ 38.02 │ 4.61
│ express │ 4.18.2 │ ✓ │ 25,755.2 │ 38.20 │ 4.59
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ express-with-middlewares │ 4.18.2 │ ✓ │ 23,844.841.27 │ 8.87
│ express-with-middlewares │ 4.18.2 │ ✓ │ 23,115.242.58 │ 8.60
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ fastify-with-middlewares │ 4.18.0 │ ✓ │ 22,497.6 │ 43.73 │ 8.39
│ fastify-with-middlewares │ 4.18.0 │ ✓ │ 22,516.8 │ 43.69 │ 8.40
├─────────────────────────────┼──────────────┼────────┼───────────┼──────────────┼─────────────────┤
│ restify │ 11.1.0 │ ✓ │ 4,783.8204.87 │ 0.86
│ restify │ 11.1.0 │ ✓ │ 4,730.6207.20 │ 0.85
└─────────────────────────────┴──────────────┴────────┴───────────┴──────────────┴─────────────────┘
```
48 changes: 23 additions & 25 deletions packages/http/src/Response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import escapeHtml from "escape-html";
import onFinished from "on-finished";
import send, { mime as sendMime } from "send";
import Request from "./Request.js";
import { JsonT, METHOD, STATUS, StatusT, StringifyT } from "./constants/index.js";
import { ENCODING_UTF8, JsonT, METHOD, STATUS, StatusT, StringifyT } from "./constants/index.js";
import { createETagGenerator, encodeUrl, vary } from "./utils/index.js";
import { CallbackT as EngineCallbackT, Engine } from "./view/index.js";

Expand Down Expand Up @@ -416,7 +416,7 @@ class Response extends ServerResponse<Request> {
public bin(body: Buffer): this {
if (!this.hasHeader("content-type")) this.type("bin");

return this.#send(body);
return this.$end(body);
}

/**
Expand Down Expand Up @@ -734,11 +734,10 @@ class Response extends ServerResponse<Request> {
* res.json({ user: "tj" });
*/
public json(body: JsonT): this {
const encoding = "utf-8";
const type = this.get("content-type");
const type = this.get("Content-Type");

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (typeof type === "string") this.setHeader("Content-Type", setCharset(type, encoding)!);
if (typeof type === "string") this.setHeader("Content-Type", setCharset(type, ENCODING_UTF8)!);
else this.setHeader("Content-Type", "application/json; charset=utf-8");

const {
Expand All @@ -747,15 +746,15 @@ class Response extends ServerResponse<Request> {
"json.escape": escape,
} = SETTINGS;

return this.#send(
return this.$end(
stringify(
this.stringify[this.statusCode],
body,
replacer,
spaces,
escape,
),
encoding,
ENCODING_UTF8,
);
}

Expand Down Expand Up @@ -943,10 +942,10 @@ class Response extends ServerResponse<Request> {

if (Buffer.isBuffer(body)) return this.bin(body);

if (body === null) return this.#send("");
if (body === null) return this.$end("");

// eslint-disable-next-line no-undefined
if (body === undefined) return this.#send();
if (body === undefined) return this.$end();

return this.json(body);
}
Expand Down Expand Up @@ -1069,14 +1068,13 @@ class Response extends ServerResponse<Request> {
* res.send("<p>some html</p>");
*/
public text(body: string): this {
const encoding = "utf-8";
const type = this.get("content-type");

// Reflect this in content-type
if (typeof type === "string") this.set("Content-Type", setCharset(type, encoding));
else this.set("Content-Type", setCharset("text/html", encoding));
if (typeof type === "string") this.set("Content-Type", setCharset(type, ENCODING_UTF8));
else this.set("Content-Type", setCharset("text/html", ENCODING_UTF8));

return this.#send(body);
return this.$end(body);
}

/**
Expand All @@ -1095,7 +1093,7 @@ class Response extends ServerResponse<Request> {
* @param encoding
* @private
*/
#send(body?: Buffer | string, encoding?: BufferEncoding): this {
private $end(body?: Buffer | string, encoding?: BufferEncoding): this {
// eslint-disable-next-line no-undefined
if (body !== undefined) {
const { etag } = SETTINGS;
Expand All @@ -1110,18 +1108,18 @@ class Response extends ServerResponse<Request> {
// Freshness
if (this.fresh) this.statusCode = STATUS.NOT_MODIFIED;

const { statusCode } = this;

// Strip irrelevant headers
if (
STATUS.NO_CONTENT === statusCode
|| STATUS.NOT_MODIFIED === statusCode
) {
this.removeHeader("content-type");
this.removeHeader("content-length");
this.removeHeader("transfer-encoding");

body = "";
switch (this.statusCode) {
case STATUS.NO_CONTENT:
case STATUS.NOT_MODIFIED:
this.removeHeader("content-type");
this.removeHeader("content-length");
this.removeHeader("transfer-encoding");

body = "";
break;
default:
break;
}

// Skip body for HEAD
Expand Down
2 changes: 2 additions & 0 deletions packages/http/src/constants/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const ENCODING_UTF8 = "utf-8" as const;

export type JsonT =
JsonT[] | boolean | number | string | { [ket: string]: JsonT } | null | undefined;

Expand Down

0 comments on commit d668000

Please sign in to comment.