Sonamu๋ @fastify/compress๋ฅผ ์ฌ์ฉํ์ฌ HTTP ์๋ต์ ์๋์ผ๋ก ์์ถํ ์ ์์ต๋๋ค. gzip, deflate, brotli ๋ฑ ๋ค์ํ ์์ถ ์๊ณ ๋ฆฌ์ฆ์ ์ง์ํ๋ฉฐ, API๋ณ๋ก ์์ถ ์ฌ๋ถ๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ ๊ตฌ์กฐ
import { defineConfig } from "sonamu";
export default defineConfig({
server: {
plugins: {
compress: {
global: false, // API๋ณ๋ก ์ ์ด
threshold: 1024, // 1KB ์ด์๋ง ์์ถ
encodings: ["gzip", "br"], // ์ง์ ์๊ณ ๋ฆฌ์ฆ
},
},
},
// ...
});
compress ์ค์
ํ์ฑํ/๋นํ์ฑํ
ํ์
: boolean | FastifyCompressOptions
export default defineConfig({
server: {
plugins: {
compress: true, // ๊ธฐ๋ณธ ์ค์ ์ผ๋ก ํ์ฑํ
},
},
});
๋นํ์ฑํ:
export default defineConfig({
server: {
plugins: {
compress: false, // ์์ถ ๋นํ์ฑํ
},
},
});
์ฃผ์ ์ต์
๋ชจ๋ ์๋ต์ ์๋์ผ๋ก ์์ถ์ ์ ์ฉํ ์ง ๊ฒฐ์ ํฉ๋๋ค.
ํ์
: boolean
๊ธฐ๋ณธ๊ฐ: true
export default defineConfig({
server: {
plugins: {
compress: {
global: false, // API๋ณ๋ก ์๋ ์ ์ด
},
},
},
});
true: ๋ชจ๋ ์๋ต์ ์๋ ์์ถ (๊ธฐ๋ณธ๊ฐ)
false: @compress() ๋ฐ์ฝ๋ ์ดํฐ๋ก API๋ณ ์ ์ด
global: false๋ฅผ ๊ถ์ฅํฉ๋๋ค. ์์ ์๋ต์ด๋ ์ด๋ฏธ ์์ถ๋ ํ์ผ(์ด๋ฏธ์ง, ๋์์)์ ์์ถํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
threshold
์์ถ์ ์์ํ ์ต์ ์๋ต ํฌ๊ธฐ์
๋๋ค.
ํ์
: number (bytes)
๊ธฐ๋ณธ๊ฐ: 1024 (1KB)
export default defineConfig({
server: {
plugins: {
compress: {
threshold: 1024, // 1KB ์ด์๋ง ์์ถ
},
},
},
});
๊ถ์ฅ๊ฐ:
1024 (1KB) - ์ผ๋ฐ์ ์ธ ์น ์ฑ
512 (512B) - ์์ JSON ์๋ต๋ ์์ถ
5120 (5KB) - ํฐ ์๋ต๋ง ์์ถ
๋๋ฌด ์์ ์๋ต์ ์์ถํ๋ฉด ์ค๋ฒํค๋๊ฐ ๋ ํด ์ ์์ต๋๋ค.
encodings
์ง์ํ ์์ถ ์๊ณ ๋ฆฌ์ฆ ๋ชฉ๋ก์
๋๋ค.
ํ์
: string[]
๊ธฐ๋ณธ๊ฐ: ["gzip", "deflate"]
export default defineConfig({
server: {
plugins: {
compress: {
encodings: ["gzip", "br"], // gzip๊ณผ brotli๋ง
},
},
},
});
์ง์ ์๊ณ ๋ฆฌ์ฆ:
"gzip" - ๊ฐ์ฅ ๋๋ฆฌ ์ง์๋จ, ๋น ๋ฅธ ์์ถ
"deflate" - gzip๊ณผ ์ ์ฌ
"br" (brotli) - ๋์ ์์ถ๋ฅ , ๋๋ฆฐ ์์ถ
์ฐ์ ์์: ๋ฐฐ์ด ์์๋๋ก ํด๋ผ์ด์ธํธ๊ฐ ์ง์ํ๋ ์ฒซ ๋ฒ์งธ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ
Brotli๋ ์์ถ๋ฅ ์ด ๋์ง๋ง CPU๋ฅผ ๋ ์ฌ์ฉํฉ๋๋ค. ์ ์ ํ์ผ์ ๋ฏธ๋ฆฌ ์์ถํ๊ณ , ๋์ ์๋ต์ gzip ์ฌ์ฉ์ ๊ถ์ฅํฉ๋๋ค.
๊ธฐ๋ณธ ์์
๊ถ์ฅ ์ค์
import { defineConfig } from "sonamu";
export default defineConfig({
server: {
plugins: {
compress: {
global: false, // API๋ณ๋ก ์ ์ด
threshold: 1024, // 1KB ์ด์๋ง
encodings: ["gzip"], // gzip๋ง (๋น ๋ฆ)
},
},
},
});
Brotli ํฌํจ
export default defineConfig({
server: {
plugins: {
compress: {
global: false,
threshold: 1024,
encodings: ["br", "gzip"], // Brotli ์ฐ์ , gzip ๋์ฒด
},
},
},
});
์๋ ์์ถ (๋ชจ๋ ์๋ต)
export default defineConfig({
server: {
plugins: {
compress: {
global: true, // ๋ชจ๋ ์๋ต ์๋ ์์ถ
threshold: 512, // 512B ์ด์
encodings: ["gzip"],
},
},
},
});
API๋ณ ์์ถ ์ ์ด
global: false๋ก ์ค์ ํ๋ค๋ฉด @compress() ๋ฐ์ฝ๋ ์ดํฐ๋ก API๋ณ๋ก ์์ถ์ ์ ์ดํ ์ ์์ต๋๋ค.
import { api, compress } from "sonamu";
export class DataModel {
// ์์ถ ์ ์ฉ
@compress()
@api()
static async getLargeData() {
return {
// ํฐ ๋ฐ์ดํฐ...
};
}
// ์์ถ ์ ํจ (์์ ์๋ต)
@api()
static async getSmallData() {
return { status: "ok" };
}
}
โ Compress ๋ฐ์ฝ๋ ์ดํฐ ์ฌ์ฉ๋ฒ
์ค์ ์์
ํ์ค ์น API
import { defineConfig } from "sonamu";
export default defineConfig({
server: {
plugins: {
compress: {
global: false, // @compress() ๋ฐ์ฝ๋ ์ดํฐ๋ก ์ ์ด
threshold: 1024, // 1KB ์ด์๋ง
encodings: ["gzip"],
},
},
},
});
์ฌ์ฉ:
export class ArticleModel {
@compress() // ํฐ ๋ชฉ๋ก ์๋ต
@api()
static async list() {
return this.getPuri().select("*");
}
@compress() // ํฐ ์์ธ ๋ฐ์ดํฐ
@api()
static async detail(id: number) {
return this.findById(id, ["**"]);
}
@api() // ์์ ์๋ต์ ์์ถ ์ ํจ
static async save(data) {
return { id: 123 };
}
}
CDN ์ต์ ํ
export default defineConfig({
server: {
plugins: {
compress: {
global: false,
threshold: 2048, // 2KB ์ด์๋ง (CDN ๊ณ ๋ ค)
encodings: ["br", "gzip"], // Brotli ์ฐ์
},
},
},
});
๊ฐ๋ฐ vs ํ๋ก๋์
const isDev = process.env.NODE_ENV === "development";
export default defineConfig({
server: {
plugins: {
compress: isDev
? false // ๊ฐ๋ฐ: ์์ถ ๋นํ์ฑํ (๋๋ฒ๊น
ํธ์)
: {
global: false,
threshold: 1024,
encodings: ["gzip"],
},
},
},
});
๊ณ ์์ถ๋ฅ ์ค์
export default defineConfig({
server: {
plugins: {
compress: {
global: false,
threshold: 512, // ์์ ์๋ต๋ ์์ถ
encodings: ["br"], // Brotli๋ง (์ต๊ณ ์์ถ๋ฅ )
brotliOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11, // ์ต๋ ํ์ง
},
},
},
},
},
});
Brotli ํ์ง์ ๋์ด๋ฉด ์์ถ๋ฅ ์ ์ข์์ง์ง๋ง CPU ์ฌ์ฉ๋์ด ํฌ๊ฒ ์ฆ๊ฐํฉ๋๋ค. ํ๋ก๋์
์์๋ ํ
์คํธ ํ ์ฌ์ฉํ์ธ์.
์ถ๊ฐ ์ต์
gzip ๋ ๋ฒจ
import zlib from "zlib";
export default defineConfig({
server: {
plugins: {
compress: {
global: false,
threshold: 1024,
encodings: ["gzip"],
zlibOptions: {
level: zlib.constants.Z_BEST_COMPRESSION, // ์ต๋ ์์ถ
},
},
},
},
});
gzip ๋ ๋ฒจ:
Z_BEST_SPEED (1) - ๋น ๋ฅธ ์์ถ
Z_DEFAULT_COMPRESSION (6) - ๊ธฐ๋ณธ๊ฐ (๊ถ์ฅ)
Z_BEST_COMPRESSION (9) - ์ต๋ ์์ถ
ํน์ Content-Type๋ง ์์ถ
export default defineConfig({
server: {
plugins: {
compress: {
global: true,
threshold: 1024,
encodings: ["gzip"],
customTypes: /^text\/|json$/, // text/* ์ json๋ง
},
},
},
});
์์ถ ์ ์ธ
export default defineConfig({
server: {
plugins: {
compress: {
global: true,
threshold: 1024,
encodings: ["gzip"],
removeContentLengthHeader: false,
inflateIfDeflated: false,
onUnsupportedEncoding: (encoding, request, reply) => {
reply.code(406); // Not Acceptable
return "Unsupported encoding";
},
},
},
},
});
์์ถ ํ์ธ
์๋ต์ด ์์ถ๋์๋์ง ํ์ธํ๋ ๋ฐฉ๋ฒ:
๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ
- Network ํญ ์ด๊ธฐ
- ์๋ต ํค๋์์ ํ์ธ:
- Size ํ์ธ:
Size: 2.5 KB (transferred)
Size: 10 KB (uncompressed)
curl ํ
์คํธ
# gzip ์์ถ ์์ฒญ
curl -H "Accept-Encoding: gzip" http://localhost:1028/api/data -i
# ์๋ต ํค๋ ํ์ธ
# Content-Encoding: gzip
# Content-Length: 1234
# Brotli ์์ถ ์์ฒญ
curl -H "Accept-Encoding: br" http://localhost:1028/api/data -i
์ฑ๋ฅ ์ํฅ
์์ถ์ ํธ๋ ์ด๋์คํ
์ฅ์ :
- ๋์ญํญ ์ ๊ฐ (50-80% ๊ฐ์)
- ๋น ๋ฅธ ์ ์ก ์๊ฐ (ํนํ ๋๋ฆฐ ๋คํธ์ํฌ)
- CDN ๋น์ฉ ์ ๊ฐ
๋จ์ :
- CPU ์ฌ์ฉ๋ ์ฆ๊ฐ
- ์ฒซ ๋ฐ์ดํธ๊น์ง ์๊ฐ ์ฆ๊ฐ (TTFB)
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ
๊ถ์ฅ ์ฌํญ
์์ถํด์ผ ํ๋ ๊ฒ:
- JSON ์๋ต (API)
- HTML, CSS, JavaScript
- SVG, XML
- ํ
์คํธ ํ์ผ
์์ถํ์ง ๋ง์์ผ ํ๋ ๊ฒ:
- ์ด๋ฏธ์ง (JPEG, PNG, WebP) - ์ด๋ฏธ ์์ถ๋จ
- ๋์์ (MP4, WebM) - ์ด๋ฏธ ์์ถ๋จ
- ์์ถ ํ์ผ (ZIP, GZ) - ์ด๋ฏธ ์์ถ๋จ
- ๋งค์ฐ ์์ ์๋ต (< 1KB)
์ฃผ์์ฌํญ
1. ์ด๋ฏธ ์์ถ๋ ํ์ผ
// โ ๋์ ์: ์ด๋ฏธ์ง๋ ์์ถ
compress: {
global: true, // ๋ชจ๋ ๊ฒ์ ์์ถ
}
// โ
์ข์ ์: API๋ณ๋ก ์ ์ด
compress: {
global: false, // ํ์ํ ๊ฒ๋ง @compress()
}
2. CPU ์ฌ์ฉ๋
// โ ๋์ ์: Brotli ์ต๋ ํ์ง
compress: {
encodings: ["br"],
brotliOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11, // ๋๋ฌด ๋๋ฆผ!
},
},
}
// โ
์ข์ ์: ์ ์ ํ ๊ท ํ
compress: {
encodings: ["gzip"], // ๋น ๋ฅด๊ณ ์ถฉ๋ถํ ์์ถ๋ฅ
}
3. threshold ์ค์
// โ ๋์ ์: ๋๋ฌด ๋ฎ์ threshold
threshold: 100 // 100B - ์ค๋ฒํค๋๊ฐ ๋ ํด ์ ์์
// โ
์ข์ ์: ์ ์ ํ ํฌ๊ธฐ
threshold: 1024 // 1KB
๋ค์ ๋จ๊ณ
์๋ต ์์ถ ์ค์ ์ ์๋ฃํ๋ค๋ฉด: