§

Options

Minify options
§

วาง JavaScript

§

JS ที่บีบอัดแล้ว

js
§

ประหยัด %

  • ขนาดเดิม
  • ขนาดที่บีบอัด
  • ประหยัดได้
  • ประหยัด %

ทีมพัฒนาในไทยที่ deploy ผ่าน AWS CloudFront, Cloudflare และ Fastly บีบอัด JavaScript เป็นขั้นตอนสุดท้ายก่อน production release ค่า CDN egress คิดตามไบต์ที่ถ่ายโอน และ Core Web Vitals ของ Google ลงโทษ JavaScript payload ขนาดใหญ่ในคะแนน Lighthouse ทุกครั้งที่ PageSpeed รัน Webpack, Vite, Rollup และ esbuild ต่างใช้ Terser เป็น minifier เริ่มต้นด้วยเหตุผลเดียวกัน: รองรับ JavaScript สมัยใหม่โดยไม่มีข้อแปลกใจและให้ผลลัพธ์ที่กระชับที่สุด

วิธีการทำงานของ JavaScript minification

Terser ทำงานใน 4 ขั้นตอนบน Abstract Syntax Tree ของโค้ด แต่ละขั้นตอนเป็นอิสระ จึงสามารถเปิดหรือปิดใดก็ได้โดยไม่กระทบขั้นตอนอื่น

  1. Parse. Terser แยกวิเคราะห์ JavaScript เป็น AST ข้อผิดพลาด syntax จะปรากฏที่นี่พร้อม token และบรรทัดที่ทำให้เกิดปัญหา เพื่อให้หาปัญหาจริงก่อนที่ transformation จะรัน ตัวแยกวิเคราะห์รองรับทุก ECMAScript construct มาตรฐานจนถึง stage-4 proposal ล่าสุด
  2. Compress. Compressor เดินผ่าน AST และใช้ transform ที่รักษา semantic หลายสิบรายการ: constant folding, dead-branch elimination, inlining ฟังก์ชัน pure สั้น การยุบการประกาศ var ต่อเนื่อง และการเขียน statement ที่เทียบเท่าใหม่ (if/else เป็น ternary การย่น comparison chain การยุบ conditional return) ทุก transform สามารถย้อนกลับได้ในหลักการ compressor ไม่เปลี่ยนพฤติกรรมที่สังเกตได้เลย
  3. Mangle. Mangler เปลี่ยนชื่อ local binding เป็น identifier ที่สั้นที่สุดที่ไม่ซ้ำ (a, b, c, …) ภายใต้แต่ละ scope มีเพียงชื่อที่ไม่สามารถออกนอกขอบเขต module เท่านั้นที่ถูกเปลี่ยนชื่อ ดังนั้น exported binding, property key และ global reference จึงยังคงไม่ถูกแตะต้อง ผลลัพธ์คือการประหยัดไบต์สูงสุดในบรรดาทุกขั้นตอน
  4. Render. Terser พิมพ์ AST ที่ถูก transform กลับเป็น JavaScript string โดยยุบช่องว่างและลด statement separator ให้เหลือน้อยที่สุดตาม grammar ที่ยอมรับ คอมเมนต์ถูกลบออกเว้นแต่จะเก็บไว้โดยสวิตช์ preserve-license ซึ่งเก็บบล็อก /*! … */ ที่สัญญาอนุญาต CDN ส่วนใหญ่กำหนดให้เก็บไว้

ทำไมต้องบีบอัด JavaScript

  • โหลดหน้าเร็วขึ้น. Script ที่เล็กลง parse และ execute เร็วขึ้น บนการเชื่อมต่อ 4G มือถือ การลดไบต์ 40 เปอร์เซ็นต์จะตัดวินาทีจริง ๆ ออกจาก Time to Interactive ซึ่งเป็น metric ที่ Google PageSpeed Insights วัดอย่างเข้มข้นที่สุด
  • ค่า egress CDN ต่ำลง. CloudFront, Cloudflare และ Fastly เรียกเก็บเงินต่อกิกะไบต์ของการส่งออก การลด script 40 เปอร์เซ็นต์ใน page view รายเดือนหลายล้านครั้งสะสมเป็นการประหยัดจริงก่อนที่จะมีการปรับปรุงรูปภาพหรือ CSS ใด ๆ การคำนวณยังใช้ได้แม้หลัง gzip และ brotli — minification ลบ token ที่ compressor จะต้อง encode อยู่แล้ว
  • Minifier นี้ไม่ทำให้หน้าช้าลง. Terser มีขนาดประมาณ 1 MB ที่ไม่ถูกบีบอัด minifier ออนไลน์ส่วนใหญ่โหลดไลบรารีทั้งหมดตอนโหลดหน้า ซึ่งทำลายคะแนน Lighthouse ของตัวเองและทำให้หน้ารู้สึกช้าก่อนที่ผู้ใช้จะพิมพ์อะไรด้วยซ้ำ หน้านี้ lazy-load Terser เฉพาะเมื่อคุณคลิกบีบอัดหรือเปิดโหมดสด — เพื่อให้การ render เริ่มต้นยังคงอยู่ใต้ขีดจำกัด Core Web Vitals ที่เครื่องมือนี้สัญญาว่าจะช่วยให้คุณบรรลุ
  • ผ่าน Core Web Vitals. Lighthouse และ PageSpeed Insights ตั้งค่าสถานะ JavaScript ขนาดใหญ่ว่าเป็นสาเหตุโดยตรงของ Total Blocking Time ที่แย่ การบีบอัด vendor library และ application bundle คือผลตอบแทนที่เร็วที่สุดในการตรวจสอบ "ลด JavaScript ที่ไม่ใช้" และ "ลบ module ที่ซ้ำกัน" ของ Lighthouse — มักเป็นการลดครั้งเดียวที่คุ้มค่าสิบถึงยี่สิบคะแนน

การใช้งานทั่วไป

JavaScript minification ปรากฏในเกือบทุกขั้นตอนของ web project สมัยใหม่

  • Pre-commit hook: บีบอัด utility script แต่ละรายการก่อน commit ลงใน repo เพื่อให้ artifact ที่ commit พร้อมสำหรับ production และ diff แสดงการเปลี่ยนแปลงเชิงตรรกะแทนช่องว่างที่เปลี่ยน
  • ตรวจสอบ third-party widget: วาง embed snippet ของ vendor และตรวจสอบว่าถูกบีบอัดแล้วหรือสามารถลดได้อีกก่อนที่จะ serve ให้ผู้ใช้หลายล้านคน
  • ทำความสะอาด legacy script: บีบอัด jQuery plugin เก่าและ script ที่เขียนด้วยมือซึ่งมีก่อน build pipeline ปัจจุบัน โดยไม่ต้องแตะต้อง source tree

ตัวอย่างที่ใช้งานได้จริง

ลองฟังก์ชันเล็ก ๆ: function add(firstNumber, secondNumber) { /* sums two numbers */ return firstNumber + secondNumber; } console.log(add(1, 2)); — ประมาณ 130 ไบต์รวมคอมเมนต์ วางด้านบนโดยเปิด Mangle และ Compress ทั้งคู่ ผลลัพธ์จะสั้นลงเหลือประมาณ function add(n,o){return n+o}console.log(add(1,2)); — ประมาณ 55 ไบต์ ลด 58 เปอร์เซ็นต์ ชื่อฟังก์ชัน add ยังอยู่เพราะถูกอ้างอิงใน console.log ชื่อ parameter firstNumber และ secondNumber สั้นลงเป็นตัวอักษรเดียวเพราะ local ต่อ function body ปิด Mangle เพื่อเก็บชื่อ parameter ที่อ่านได้พร้อมยุบช่องว่างและลบคอมเมนต์

FAQ

รันในเบราว์เซอร์ของฉันหรือไม่?

ใช่ Terser โหลดแบบ lazy ครั้งแรกที่คุณคลิกบีบอัดหรือเปิดโหมดสด — ประมาณ 200 KB ที่บีบอัดแล้วจะไปอยู่ใน browser cache จากนั้นไม่มีการดาวน์โหลดเพิ่มเติม โค้ดของคุณจะไม่ออกจากหน้าเลย

การย่อชื่อคืออะไรและปลอดภัยหรือไม่?

การ mangle เปลี่ยนชื่อตัวแปร local เป็นตัวอักษรเดียวเพื่อประหยัดไบต์ ปลอดภัยสำหรับ self-contained script และ IIFE bundle เพราะการเปลี่ยนชื่อไม่ออกนอก scope ไม่ปลอดภัยสำหรับ script ที่ expose global ตามชื่อ (เช่น window.myLib = …) โดยไม่มี wrapper ปิด Mangle เมื่อไม่แน่ใจ

ทำไมโค้ดของฉันเสียหายหลัง minification?

สาเหตุที่พบบ่อย 3 ประการ: eval หรือ with ที่อ้างอิงตัวแปรตาม string; การอ่าน Function.name หรือ arguments.callee ที่พึ่งพา identifier ต้นฉบับ; หรือ global ที่ expose ตามชื่อที่ถูกเปลี่ยนชื่อ ปิด Mangle ก่อนเพื่อแยกว่าการเปลี่ยนชื่อหรือ Compress transform เป็นสาเหตุ

รองรับ syntax สมัยใหม่ (ES2020+) หรือไม่?

ใช่ ตั้งเป้าหมาย ECMAScript เป็น ES2020 หรือ Next แล้ว Terser จะเก็บ optional chaining, nullish coalescing, top-level await และ logical-assignment operator ไว้ ตั้งเป็น ES5 แล้ว Terser จะ down-compile ได้บางส่วน แต่ไม่ใช่ transpiler เต็มรูปแบบ — ใช้ Babel สำหรับ syntax ที่ ES5 ไม่สามารถ represent ได้เลย

JavaScript minification ฝั่งเบราว์เซอร์ด้วย Terser ให้ผลลัพธ์คุณภาพ production โดยไม่ต้องเพิ่ม build tool วาง script เลือกเป้าหมาย ECMAScript คัดลอกหรือดาวน์โหลดผลลัพธ์ ไม่มีการอัปโหลด ไม่มีบัญชี ไม่มี build pipeline Minifier เองโหลดเฉพาะเมื่อคุณขอเท่านั้น ดังนั้นการเปิดหน้านี้จะสิ้นเปลืองเพียงไม่กี่กิโลไบต์ ไม่ใช่เมกะไบต์