ขนมปังต้นฉบับหมุนเครื่องรีดผ้าผืนใหญ่ให้เป็นม้วนเล็กพร้อมปรับแรงกดด้วยคันโยก

Bun 1.4.3 CompressionStream: ตั้งระดับบีบอัดให้ตรง latency budget

พี่โชว์Engineering

การบีบอัดไม่ใช่ปุ่มยิ่งสูงยิ่งดี response ที่สร้างสดอาจเสีย CPU และเพิ่ม latency มากกว่าขนาดที่ประหยัดได้ Bun 1.4.3 เพิ่มตัวเลือก level ให้ CompressionStream เพื่อกำหนดงบความเร็วกับอัตราบีบอัดตามงานครับ

WHY: แรงอัดต้องเหมาะกับของที่จะส่ง

เหมือนรีดผ้าห่มก่อนส่งพัสดุ แรงอัดสูงสุดทำให้กล่องเล็ก แต่ใช้เวลานาน สำหรับ response แบบ interactive เราอาจเลือก gzip ระดับกลาง ส่วน artifact ที่สร้างครั้งเดียวและดาวน์โหลดหลายครั้งค่อยยอมจ่าย CPU มากขึ้น การตั้งค่าเป็น decision ของ workload ไม่ใช่ค่าศักดิ์สิทธิ์ค่าเดียว

const source = new TextEncoder().encode("forest-data:".repeat(2_000));

async function compress(level: number): Promise<Uint8Array> {
  const stream = new Blob([source])
    .stream()
    .pipeThrough(new CompressionStream("gzip", { level }));
  return new Uint8Array(await new Response(stream).arrayBuffer());
}

const packed = await compress(4);
const restored = new Uint8Array(
  await new Response(
    new Blob([packed]).stream().pipeThrough(new DecompressionStream("gzip")),
  ).arrayBuffer(),
);

if (packed.length >= source.length) throw new Error("expected repetitive data to shrink");
if (!Bun.deepEquals(restored, source)) throw new Error("round-trip changed bytes");
console.log({ source: source.length, packed: packed.length });

HOW: benchmark ด้วย payload จริง

ระดับที่รองรับขึ้นกับ format: gzip/deflate ใช้ช่วง 0–9, Brotli 0–11 และ zstd 1–22 ตาม release note ค่าเกินช่วงจะ throw RangeError ส่วนการไม่ส่ง level รักษา default เดิม การเทียบควรวัดทั้ง p50/p95 latency, CPU time และขนาด output ด้วยข้อมูลจริง เพราะ JSON ซ้ำมากกับภาพที่บีบอัดมาแล้วให้ผลต่างกันมาก

อย่าบีบอัด secret กับ input ที่ผู้โจมตีควบคุมใน stream เดียวกันโดยไม่วิเคราะห์ compression side channel และอย่าบีบอัดซ้ำไฟล์ที่ format ทำ compression อยู่แล้ว ค่า level ไม่แก้ปัญหา memory backpressure; pipeline ยังต้องจัดการ cancellation และขีดจำกัดขนาด input

Recap

  • เลือก level จาก latency และ CPU budget ไม่ใช่ขนาดอย่างเดียว
  • วัดด้วย payload จริงและดู p95
  • ทดสอบ decompress round-trip
  • ไม่บีบอัด format ที่บีบอัดอยู่แล้วซ้ำโดยไม่วัด
  • แยก secret ออกจาก input ที่ผู้โจมตีควบคุม