การย่อขนาด JavaScript มักถูกเข้าใจสับสนกับการทำให้อ่านยาก (obfuscation) ทั้งที่จริงแล้วเป็นงานคนละอย่างกันที่มีเป้าหมายต่างกัน อย่างหนึ่งช่วยประหยัดขนาดไฟล์ อีกอย่างมีไว้เพื่อทำให้เข้าใจตรรกะของโค้ดได้ยากขึ้น
การย่อขนาดทำอะไรบ้าง
เครื่องมือย่อขนาดจะลบช่องว่าง คอมเมนต์ และการขึ้นบรรทัดใหม่ รวมถึงย่อชื่อตัวแปรภายในให้เหลือหนึ่งหรือสองตัวอักษรในจุดที่ทำได้อย่างปลอดภัย ตรรกะของโปรแกรมยังคงเหมือนเดิมทุกประการ นี่คือการบีบอัดไฟล์ในเชิงเทคนิคล้วน ๆ
จาก JSMin สู่ Terser ประวัติศาสตร์สั้น ๆ
ดักลาส ครอกฟอร์ด (Douglas Crockford) เปิดตัว JSMin ในช่วงต้นยุค 2000s ซึ่งเป็นหนึ่งในเครื่องมือย่อขนาด JS ยุคแรก ๆ ที่มีคนใช้กันอย่างแพร่หลาย โดยมันทำแค่ลบช่องว่างกับคอมเมนต์ ไม่แตะชื่อตัวแปรเลย ส่วนเครื่องมือยุคใหม่อย่าง Terser (ซึ่งแตกมาจาก UglifyJS) และ esbuild ไปไกลกว่านั้น คือแปลงโค้ดเป็น AST (abstract syntax tree) แล้วเปลี่ยนชื่อตัวแปรภายในและพารามิเตอร์ของฟังก์ชันให้เหลือตัวอักษรเดียวในทุกจุดที่ปลอดภัย และขั้นตอนนี้เองที่ช่วยลดขนาดไฟล์ได้มากกว่าการลบช่องว่างเพียงอย่างเดียวในโปรเจกต์จริง
Source map วิธีดีบักโค้ดที่ถูกเปลี่ยนชื่อตัวแปรแล้ว
เมื่อชื่อตัวแปรถูกย่อเหลือเพียง a, b, c และการขึ้นบรรทัดใหม่หายไปหมด stack trace ของข้อผิดพลาดใน production จะชี้ไปยังตำแหน่งที่อ่านไม่ออกในบรรทัดเดียวที่ยาวมาก ๆ source map แก้ปัญหานี้ได้ โดยเป็นไฟล์แยกต่างหากที่จับคู่แต่ละตำแหน่งในโค้ดที่ย่อขนาดแล้วกลับไปยังบรรทัด คอลัมน์ และชื่อตัวแปรดั้งเดิม ทำให้ DevTools ของเบราว์เซอร์แสดง stack trace ที่อ่านได้ ทั้งที่จริง ๆ แล้วเบราว์เซอร์กำลังรันโค้ดที่ย่อขนาดอยู่
ใช้ทำอะไรได้บ้าง
- ลดขนาดของ JS bundle ก่อนดีพลอยขึ้น production
- เร่งความเร็วในการดาวน์โหลดและแปลงสคริปต์ในเบราว์เซอร์
- เข้าใจว่าทำไมโค้ดที่ย่อขนาดแล้วยังอ่านออกได้ถ้าต้องการ ในขณะที่โค้ดที่ถูกทำให้อ่านยากนั้นตีความได้ยากกว่ามาก
Tree shaking กับการย่อขนาด แตกต่างกันอย่างไร
Tree shaking เป็นเทคนิคคนละอย่างที่ไม่ควรสับสนกับการย่อขนาด มันวิเคราะห์กราฟการพึ่งพากันระหว่างโมดูล แล้วลบฟังก์ชันและ export ที่ไม่ถูกใช้งานที่ไหนเลยออกจาก bundle สุดท้ายอย่างสมบูรณ์ตั้งแต่ขั้นตอน build ในขณะที่การย่อขนาดทำงานกับโค้ดที่เสร็จสมบูรณ์แล้ว และแค่ย่อการเขียนแทนในรูปแบบข้อความเท่านั้น โดยไม่ลบตรรกะที่ถูกใช้งานจริงเลยแม้แต่น้อย เครื่องมือ build สมัยใหม่อย่าง Vite หรือ webpack มักใช้ทั้งสองเทคนิคเรียงต่อกัน คือให้ tree shaking ลบโค้ดที่ตายแล้วออกก่อน จากนั้นการย่อขนาดจึงบีบอัดส่วนที่เหลือ