ขนาดไฟล์ CSS/JS มีผลโดยตรงต่อความเร็วโหลด (LCP/INP) และอัตราแปลง (Conversion) เป้าหมายคือ “ส่งมอบโค้ดเท่าที่จำเป็น ในเวลาที่เหมาะสม ด้วยรูปแบบที่เบาที่สุด” บทความนี้สรุปแนวทางตั้งแต่ระดับโค้ด การบันเดิล ไปจนถึงการส่งมอบผ่านเครือข่าย

หลักคิด 3 ชั้น (Code → Bundle → Delivery)
- Code: เขียนโค้ดให้น้อยลง ใช้เฉพาะที่จำเป็น ตัดสิ่งซ้ำซ้อน
- Bundle: รวม/แยกอย่างมีเหตุผล เปิดใช้การลบโค้ดที่ไม่ถูกเรียกใช้งาน
- Delivery: บีบอัด แคช และโหลดแบบ “ต้องใช้เมื่อไร ค่อยโหลด”
เทคนิคฝั่ง CSS
- ลบ CSS ที่ไม่ได้ใช้ (Unused CSS): ใช้เครื่องมืออย่าง PurgeCSS/Lightning CSS/UnoCSS กับเส้นทางไฟล์จริง (HTML/JSX/Liquid ฯลฯ)
- Critical CSS: ดึงสไตล์ที่จำเป็นต่อ Above-the-fold มา inline แล้วโหลดไฟล์หลักแบบ
media="print"→ onload เปลี่ยนเป็นallหรือใช้rel="preload" - แยก CSS ตามหน้า/ฟีเจอร์: ไม่ต้องส่งสไตล์ทั้งไซต์ในทุกหน้า (code-splitting ระดับ CSS)
- ลด/จัดระเบียบยูทิลิตี: หากใช้เฟรมเวิร์กอย่าง Tailwind ให้เปิด JIT/Purge เพื่อตัดคลาสที่ไม่ใช้
- ลดแอนิเมชัน/ฟิลเตอร์หนัก ๆ: โดยเฉพาะบนมือถือ เพราะเพิ่มงานเรนเดอร์
- Minify: ใช้ csso/lightningcss/postcss-csso เพื่อลดช่องว่าง ความซ้ำซ้อน
เทคนิคฝั่ง JavaScript
Tree Shaking & Dead Code Elimination: ใช้ ES Modules (import/export) ให้ bundler (Rollup/Webpack/ESBuild/Vite) ตัดฟังก์ชันที่ไม่ใช้
- Side Effects: ตั้ง
sideEffects: falseในpackage.json(ถ้าปลอดภัย) ช่วยลบโค้ดที่ไม่ถูกเรียก - Code Splitting/Dynamic Import:
import()โหลดตามเส้นทางการใช้งาน (route-level / component-level) - เลือกไลบรารีแบบเบา: แทน lodash ทั้งก้อน →
lodash-esนำเข้าฟังก์ชันย่อย, แทน moment → date-fns/dayjs, React หนักมากอาจพิจารณา Preact ในบางเคส - กำหนด Target สมัยใหม่: ลด transpile/polifyll เกินจำเป็น (เช่น ตั้ง browserslist ให้เหมาะกับกลุ่มเป้าหมาย)
- ลบ debug/code dev: ตัด
console.*,debugger, source map เฉพาะโปรดักชัน - Minify & Mangle: ใช้ Terser/ESBuild minify เพื่อลดตัวแปร/ช่องว่าง/ฟังก์ชันซ้ำ
กลยุทธ์การโหลด (Loading Strategy)
deferสำหรับสคริปต์ที่ต้องใช้ทุกหน้า: ให้โหลดคู่กับ HTML แล้วรันเมื่อ DOM พร้อมasyncสำหรับสคริปต์บุคคลที่สาม: ไม่บล็อกเรนเดอร์ (Analytics/Ads—พิจารณาโหลดช้าได้)- Preload/Prefetch อย่างพอดี:
rel="preload"สำหรับไฟล์ที่จะใช้แน่ ๆ ในหน้า,rel="prefetch"สำหรับหน้า/โค้ดที่ผู้ใช้ “น่าจะ” เข้าในลำดับถัดไป - Islands/Partial Hydration (ถ้าใช้เฟรมเวิร์กสมัยใหม่): ไฮเดรตเฉพาะส่วนที่มีปฏิสัมพันธ์จริง
การส่งมอบผ่านเครือข่าย (Delivery)
- บีบอัด: เปิด Brotli (br) และ Gzip สำรอง
- HTTP Caching: ตั้ง
Cache-Control: public, max-age=31536000, immutableสำหรับไฟล์เวอร์ชัน (มี hash) - CDN & HTTP/2+: เปิด multiplexing และ TLS ใหม่ ๆ เพื่อลด round-trip
- ลดจำนวนคำขอ: รวมไฟล์เท่าที่เหมาะ (แต่อย่ารวมจนเสียประโยชน์ของ code-splitting)
เครื่องมือที่แนะนำ (ตัวอย่าง)
- บันเดิล: Vite, Rollup, Webpack, ESBuild
- CSS: PostCSS, Lightning CSS, Tailwind JIT, PurgeCSS
- วิเคราะห์บันเดิล:
rollup-plugin-visualizer,webpack-bundle-analyzer,source-map-explorer - ตรวจ Coverage: Chrome DevTools → Coverage เพื่อหาโค้ดที่โหลดมาแล้วไม่ได้ใช้
การวัดผล & KPI
- ขนาดถ่ายโอน (Transfer Size): CSS/JS รวมต่อหน้า
- Core Web Vitals: LCP, INP, CLS (ให้ความสำคัญกับ LCP/INP)
- JS Execution Time: ลดเวลาประมวลผลบนมือถือเครื่องช้า
- การใช้หน่วยความจำ: โดยเฉพาะหน้า Single Page/รายการยาว
ข้อผิดพลาดที่พบบ่อย
- ใช้ไลบรารีครอบจักรวาลทั้งก้อนเพื่อเรียกฟังก์ชันเดียว
- รวมไฟล์ทุกอย่างเป็นก้อนเดียวจน initial load หนักเกินไป
- เปิดใช้ polyfill ทั้งชุดโดยไม่ดูจริงว่าต้องรองรับเบราว์เซอร์ใด
- Purge CSS พลาด—เผลอตัดคลาสที่สร้างแบบไดนามิก (ควร Whitelist)
- ลืมตั้งแคชชิ่ง/บีบอัดระดับเซิร์ฟเวอร์/CDN
เช็กลิสต์ย่อก่อนขึ้นโปรดักชัน
- เปิด Minify + Tree Shaking + Code Splitting
- ตั้ง Brotli + Cache-Control + CDN
- Purge/Prune CSS ที่ไม่ใช้ + Critical CSS
- ลด third-party/โหลดแบบ async/defer
- Bundle วิเคราะห์แล้ว ยิ่งหน้าแรกยิ่งต้องบาง
- Lighthouse/PageSpeed/DevTools Coverage ผ่านเกณฑ์เป้าหมาย
สรุปท้ายเรื่อง
ลดขนาดไฟล์ให้ได้ผล = ตัดสิ่งที่ไม่ใช้ + แยกโหลดตามบริบท + ส่งมอบด้วยการบีบอัดและแคชที่เหมาะสม เริ่มจากการทำให้หน้าแรกเบาที่สุด แล้วค่อยไล่ปรับหน้าอื่น ๆ ด้วยเครื่องมือวัดผลที่เชื่อถือได้
หากสนใจติดต่อได้ที่ Black Cat Design คลิ๊ก!!!



