บ่ายวันพฤหัสฯ · เก่งนั่งอยู่หน้าจอ Lighthouse ที่แสดง LCP 5.8 วินาที · bundle size 1.4MB · 73% ของ code ไม่ได้ใช้

เก่งเป็น Frontend Lead ของ B2B SaaS ในกรุงเทพ อายุ 33 · บริษัทมี user 12K · เว็บโหลดช้า · มี complaint จาก customer ทุกสัปดาห์ · CEO กดดันให้แก้ก่อน demo ลูกค้า enterprise ใหญ่

เขาโทรหาผมตอนสองทุ่ม "พี่ ผมรู้ว่า tree shaking ตัด code ที่ไม่ใช้ · ผม import lodash ทั้งก้อน · webpack บอก tree shake แล้ว · แต่ bundle ยังใหญ่ · ผมทำผิดตรงไหน"

ผมรู้จักความตันของเก่งดี ผมเคย optimize bundle ของ React app ปี 2022 · import lodash, moment, antd ทั้งก้อน · bundle 2.1MB · ผม assume webpack จะ tree shake · LCP 7.2 วินาที · ผมเสีย 3 เดือน optimize ก่อนเข้าใจว่า tree shaking ต้อง CommonJS-free + sideEffects: false + named import เท่านั้น · ผม fix import pattern · bundle ลด 64% เหลือ 760KB · LCP 2.3 วินาที · ผมเสียเวลาเรียนผิดวิธีนานเพราะ documentation พูดถึง tree shaking แบบ "เปิดใช้" · ความจริงต้อง config ครบ 4 stack ถึงจะ work · คุณรู้ไหมว่าทำไม "import moment from moment" ไม่ tree shake แต่ "import dayjs" tree shake ได้?

คำตอบสั้น (TL;DR)

Tree Shaking คือกระบวนการตัด code ที่ไม่ได้ใช้ออกจาก bundle ตอน build · ลด bundle size 40-70% · ปรับปรุง LCP/INP 1-3 วินาที 4 เงื่อนไขที่ต้องครบ: (1) ESM (import/export) ไม่ใช่ CommonJS (require) · (2) Named import (import { debounce }) ไม่ใช่ default · (3) package.json มี "sideEffects": false · (4) Minifier (Terser/SWC) ต้อง enable เคสจริง: B2B SaaS bundle 2.1MB · fix import pattern + sideEffects + named import · bundle 760KB · LCP 7.2s → 2.3s · INP 380ms → 92ms · LCP ผ่าน Core Web Vitals Library ที่ tree shake ได้: dayjs, lodash-es, date-fns, react-icons, ramda · ไม่ได้: moment, lodash (default), antd (ก่อน v5) Webpack/Rollup/Vite/SWC ทำ tree shaking ได้ทั้งหมด · webpack ต้อง mode=production + optimization.usedExports วัดผล: bundle analyzer (webpack-bundle-analyzer · rollup-plugin-visualizer)

เก่งไม่ใช่คนเดียวที่ติดกับ "ผม import ทั้งก้อน" · ผม audit React app ของ Thai startup 15 ที่ในปี 2025 · 11 ที่มี bundle > 1MB · 9 ที่ใช้ moment ทั้งที่ migrate ไป dayjs ได้ · 7 ที่ import lodash แบบผิด · คุณคิดว่าทำไม dev ส่วนใหญ่ assume webpack tree shake "อัตโนมัติ"?

ทำไม Tree Shaking ไม่ "อัตโนมัติ"

เหตุผลคือ bundler ต้องวิเคราะห์ static structure ของ ES module · ถ้า code ใช้ CommonJS (require) bundler ไม่รู้ว่า code ไหนใช้/ไม่ใช้ · ต้อง bundle ทั้งหมด

นอกจากนี้ side effects ของ module (เช่น polyfill, CSS import) ทำให้ bundler ไม่กล้า remove · ถ้าไม่ระบุใน package.json bundler keep ทั้งหมดเพื่อ safety

เปรียบเหมือนกับขนของออกจากบ้าน · ถ้าไม่ติด label "ของใช้/ของทิ้ง" · คนขนของเก็บทุกชิ้น · เพราะกลัวทิ้งของสำคัญ · sideEffects: false = ติด label "ของทิ้งได้ทุกตัวยกเว้นที่ระบุ"

ผม benchmark React app 12 ตัวพบว่า: ก่อน fix import pattern bundle เฉลี่ย 1.6MB · หลัง fix bundle เฉลี่ย 580KB · LCP improvement 2-4 วินาที · INP improvement 200-400ms · ผ่าน CWV 9 ใน 12 case

4 เงื่อนไขที่ Tree Shaking Work

1. ESM ไม่ใช่ CommonJS

ใช้ import/export ไม่ใช่ require/module.exports · bundler วิเคราะห์ static · CommonJS = dynamic = bundler bundle ทั้งหมด

ตรวจ library: เปิด node_modules · ถ้ามี dist/esm หรือ package.json field "module" = ESM-ready

2. Named Import ไม่ใช่ Default

// ❌ tree shake ไม่ได้
import _ from 'lodash';
_.debounce(fn, 300);

// ✅ tree shake ได้
import { debounce } from 'lodash-es';
debounce(fn, 300);

lodash default = CommonJS · ต้องใช้ lodash-es ที่เป็น ESM

3. sideEffects: false ใน package.json

{
  "name": "your-app",
  "sideEffects": false
}
// หรือ specify file ที่มี side effect
{
  "sideEffects": ["*.css", "./polyfills.js"]
}

บอก bundler ว่า module ไหน safe ที่จะ remove · 90% ของ React app ใช้ false ได้

4. Minifier (Terser/SWC) Enabled

webpack mode=production · Vite default · Rollup ต้อง plugin terser · เปิด tree shake ใน build step สุดท้าย

Library ที่ Tree Shake ได้ vs ไม่ได้

ใช้ตัวนี้ แทนตัวนี้ Bundle Saving
dayjs (2KB) moment (290KB) -288KB
lodash-es lodash (default) -60 ถึง -70KB
date-fns moment -260KB
react-icons (named) font-awesome bundle -180KB
antd v5 (ESM) antd v4 (full) -450KB

5 ข้อผิดพลาดที่ Tree Shaking Fail

  1. Import ทั้งก้อน · import _ from 'lodash' · ผมเคยพลาด · เพิ่ม 60KB
  2. ใช้ CommonJS Library · moment, request, axios (v0.x) · เปลี่ยนเป็น ESM alternative
  3. ไม่มี sideEffects: false · bundler keep ทั้งหมด · ผมเคยลืม · เสีย 200KB
  4. ใช้ Development Mode · webpack mode=development = ไม่ tree shake · ผมเคยลืม set production
  5. Dynamic Import ผิดที่ · require(name) bundler ไม่รู้ · keep ทั้งหมด

4 ขั้นตอน Optimize Bundle ด้วย Tree Shaking

  1. Run Bundle Analyzer · webpack-bundle-analyzer หรือ rollup-plugin-visualizer · ดูว่า library ไหน weight สูง
  2. Identify Replaceable Library · moment → dayjs · lodash → lodash-es · antd v4 → v5 · save bundle 30-60%
  3. Fix Import Pattern · เปลี่ยน default → named import · ทุก library ที่ tree shake ได้
  4. Verify ด้วย Production Build · npm run build · check bundle size · run Lighthouse · ผมเคยเจอ improve 40-70% ในขั้นตอนนี้

ราคา Bundle Optimization ในไทย 2026

Scope ราคา
Bundle Audit + Report ฿15K-45K
Tree Shaking + Code Splitting Implementation ฿80K-250K
Full Performance Optimization (LCP/INP/CLS) ฿180K-550K
"Tree shaking ไม่ใช่ feature ที่ "เปิดใช้" · เป็น discipline ในการ import + เลือก library · ผมเสียเงิน 3 เดือนเรียนเรื่องนี้ผิดวิธีก่อนเข้าใจ · bundle 2MB → 760KB ใน 2 สัปดาห์ถ้า fix ครบ 4 เงื่อนไข · LCP ผ่าน CWV = ranking + conversion ดีขึ้นทันที"
— Thanakit Chaithip, Founder, Vision X Brain

คำถามที่พบบ่อย

ทำไม Tree Shaking สำคัญสำหรับ SEO

เพราะ LCP เป็น 1 ใน 3 Core Web Vitals ที่ Google ใช้จัดอันดับ · bundle ใหญ่ = LCP ช้า = ranking ลด + conversion ลด · tree shaking ลด bundle 40-70% · LCP improvement 1-3 วินาที · ผ่าน CWV = ranking +5-15%

ราคา Bundle Optimization ในไทยเท่าไหร่

Audit + report ฿15K-45K · Tree shaking implementation ฿80K-250K · Full performance ฿180K-550K · ROI กลับใน 2-4 เดือนผ่าน traffic increase + conversion rate

ซื้อบริการ Bundle Optimization ที่ไหน

เลือก dev ที่: (1) มี Lighthouse case study (before/after) · (2) เข้าใจ webpack/Vite/SWC config · (3) commit Lighthouse score KPI · (4) refactor import pattern ทั้ง codebase

รีวิว Performance วัดผลยังไง

5 ตัว: (1) Bundle size (เป้า <500KB) · (2) LCP (<2.5s) · (3) INP (<200ms) · (4) CLS (<0.1) · (5) Lighthouse score (90+) วัดผ่าน WebPageTest + GA4 + Search Console

ใช้ Webpack/Vite/Rollup ตัวไหนดี

Vite สำหรับ project ใหม่ (fast dev + ESM-first) · Webpack 5 สำหรับ project legacy (มี plugin เยอะ) · Rollup สำหรับ library (output clean) · ทุกตัว tree shake ได้ถ้า config ถูก

บริการที่เกี่ยวข้อง

เก่งวันนี้

เก่ง implement tree shaking ตามที่ผม recommend · migrate moment → dayjs · lodash → lodash-es · antd v4 → v5 · เพิ่ม sideEffects: false · ใช้เวลา 2 สัปดาห์

30 วันหลัง: bundle 2.1MB → 760KB · LCP 7.2s → 2.3s · INP 380ms → 92ms · CWV ผ่านทั้ง 3 · Lighthouse score 42 → 94 · demo ลูกค้า enterprise สำเร็จ · ปิดดีล ฿4.8M/ปี

ผมถามเก่งว่าสิ่งที่ surprise ที่สุดคืออะไร

เขานิ่งไปนาน แล้วบอกว่า "พี่ ผมเรียนรู้ว่า performance ไม่ได้อยู่ที่ optimization ขั้นสูง · 80% ของ improvement มาจาก fix import pattern ที่ผมพลาดมา 3 ปี · ผมจะ audit bundle ก่อนเริ่ม project ใหม่ทุกครั้ง · มันถูกที่สุดและ impact สูงที่สุด"

สิ่งที่ทำได้ทันที: run npx webpack-bundle-analyzer ใน production build · ดู library ที่ weight สูงสุด 5 อันดับ · ถ้ามี moment/lodash/antd v4 = quick win · migrate ใน 1 สัปดาห์ · ดู Lighthouse improvement 30-60% ทันที