4.2.6 · Performance + Build pipeline
บทนี้วิเคราะห์ performance characteristics ของ vtrc-rc-backoffice + อธิบาย build pipeline (CRA 3.4.3 + multi-stage Docker + nginx)
Build pipeline
CRA 3.4.3 (not ejected)
vtrc-rc-backoffice ใช้ CRA 3.4.3 ไม่ eject — script ทั้งหมดมาจาก react-scripts
vtrc-rc-backoffice/package.json (scripts):
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}ข้อจำกัด CRA 3.4.3:
- Webpack 4 (ล้าสมัย — CRA 5 ใช้ Webpack 5)
- ไม่สามารถกำหนด webpack config เองได้ โดยตรง ต้องใช้
rescripts/cracoหรือ eject - tree-shaking อ่อน — ทำให้ bundle ใหญ่
Dockerfile
vtrc-rc-backoffice/Dockerfile:1-17:
FROM node:16 AS stage-1
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --legacy-peer-deps
COPY . .
RUN CI=false GENERATE_SOURCEMAP=false NODE_OPTIONS=--max-old-space-size=4096 npm run build
FROM nginx:1.24.0 AS stage-2
COPY ./nginx/default.conf /etc/nginx/conf.d/
COPY --from=stage-1 /usr/src/app/build/ /usr/share/nginx/html/build/จุดสำคัญ:
- Node 16 (EOL September 2023) — ควร upgrade เป็น 18 หรือ 20
npm install --legacy-peer-deps— จำเป็นเพราะ peer dep conflict ระหว่างreact-apollo+@apollo/client+ MUI v5NODE_OPTIONS=--max-old-space-size=4096— heap 4GB (Webpack ของ CRA 3.4.3 out-of-memory ถ้าไม่เพิ่ม)CI=false— ปิด warning-as-errorGENERATE_SOURCEMAP=false— ปิด source map/usr/share/nginx/html/build/— static serve ที่ path/build/(ต่างจากvtrc-webที่ serve ที่ root)
nginx config
vtrc-rc-backoffice/nginx/default.conf — SPA fallback ผ่าน try_files $uri $uri/ /index.html
Bundle size analysis
ขนาดประมาณการ
| Library | ขนาดประมาณการ | หมายเหตุ |
|---|---|---|
antd@4.15 (full import) | ~1.2 MB | UI library หลัก |
@mui/*@5.11 | ~300 KB | ใช้น้อย (WorkForce module) |
react@16.14 + react-dom@16.14 | ~150 KB | core |
react-apollo@3.1 + Apollo ecosystem | ~280 KB | GraphQL |
recoil@0.7 | ~50 KB | state (module ใหม่) |
moment@2.29 | ~300 KB | date |
chart.js@3 + react-chartjs-2 | ~250 KB | charts |
stimulsoft-reports-js | ~5 MB | report — ใหญ่มาก |
xlsx@0.18 + exceljs | ~800 KB | Excel export |
@react-pdf/renderer + react-pdf + pdfjs-dist | ~2 MB | PDF preview |
crypto-js | ~120 KB | AES |
Misc (lodash, axios, qrcode, react-router-dom, ...) | ~1 MB | — |
รวม ~11-13 MB (gzip ~3-4 MB)
สาเหตุที่ bundle ใหญ่กว่า vtrc-web
- Stimulsoft Reports (~5MB) — ใช้สำหรับ report generation ฝั่ง client แต่ load ตั้งแต่ app boot
- MUI v5 (~300KB) — ใช้แค่ WorkForce module แต่อยู่ใน bundle ทั้งหมด
- Excel + PDF library 2 ตัว —
xlsx+exceljs+react-pdf+pdfjs-dist
Performance issues
PERF-VTRC-RC-01 · Bundle 11-13MB — TTI ช้ามาก
ที่: package.json + ไม่มี code splitting
Impact:
- TTI: ~5-8s บน 4G
- ผู้ใช้ network ช้า (3G, rural) — 15-25s
- Stimulsoft 5MB load ตลอดเวลาแม้ไม่ได้ใช้
Remediation:
- Code splitting —
React.lazy(() => import('./StimulsoftReport'))แยก Stimulsoft เป็น chunk - AntD tree-shake —
babel-plugin-import - MUI v5 consolidate — ตัดออกถ้าเปลี่ยน WorkForce ไป AntD ได้
- Replace moment.js — ด้วย
date-fns(50KB)
PERF-VTRC-RC-02 · fetchPolicy: 'no-cache' — network load สูง
ที่: vtrc-rc-backoffice/src/config/apollo.js:171-185
Evidence — apollo.js:171-185:
apolloClient.defaultOptions = {
watchQuery: {
fetchPolicy: 'no-cache',
errorPolicy: 'ignore'
},
query: {
fetchPolicy: 'no-cache',
errorPolicy: 'all'
}
}Impact: ทุก query ดึงจาก backend ทุกครั้ง ทำให้ network load สูง + หน้าช้า
Trade-off: เหมาะกับ backoffice ที่ต้องการข้อมูลใหม่เสมอ แต่ทำให้ performance แย่
Remediation:
- ใช้
cache-and-networkสำหรับ list page (cache + background refresh) - ใช้
network-onlyสำหรับ form submit
PERF-VTRC-RC-03 · console.log = () => {} — debug ยาก
ที่: App/index.js:17
Impact: ไม่ใช่ perf issue โดยตรง แต่ทำให้ developer ใช้ debugger หรือ React DevTools แทน console.log ทำให้ debug cycle ช้า
PERF-VTRC-RC-04 · Image ไม่ optimize
เหมือน vtrc-web — รูป copy ตรงไป bundle
PERF-VTRC-RC-05 · Build time ช้า
ที่: Dockerfile npm run build step
Impact: cold Docker build ~6-10 นาที (ช้ากว่า vtrc-web เพราะ heap 4GB + MUI v5)
Remediation:
- Babel swc plugin (faster)
- Webpack 5 migration (build time -40%)
- Docker layer cache สำหรับ
node_modules/
Performance scorecard
| Dimension | สถานะ | เหตุผล |
|---|---|---|
| Bundle size | 🔴 | ~11-13MB — ใหญ่มาก |
| Code splitting | 🔴 | แทบไม่มี |
| TTI | 🔴 | ~5-8s บน 4G |
| Stimulsoft loading | 🔴 | 5MB load ตั้งแต่ boot |
| Cache strategy | 🟡 | no-cache ทุกที่ — works แต่ network load สูง |
| Image optimization | 🔴 | ไม่มี |
| HTTP/2 + gzip | 🟡 | HTTPS มี แต่ HTTP/2 ไม่ชัวร์ |
| Build time | 🔴 | 6-10 min cold |
| Service worker | 🟢 | ไม่มี (not critical) |
Modernization priority (ROI-weighted)
- Lazy-load Stimulsoft — ลด bundle 5MB, investment ปานกลาง
- AntD tree-shake — ลด bundle ~600KB, investment เล็ก
- Code splitting — ลด TTI, investment ปานกลาง
- Replace moment.js — ลด bundle ~250KB, investment ปานกลาง
- CRA → Webpack 5 migration — build time -40%, investment ใหญ่
- Consolidate MUI v5 → AntD v4 — ลด bundle 300KB, investment ใหญ่
เปรียบเทียบกับ vtrc-web
| ด้าน | vtrc-web | vtrc-rc-backoffice |
|---|---|---|
| Build system | Webpack 4 (ejected) | CRA 3.4.3 (not ejected) |
| Webpack config | custom | default |
| Node (build) | 14 | 16 |
| Bundle | ~12 MB | ~11-13 MB |
| TTI | ~5-8s | ~5-8s |
| Build time | ~5-8 min | ~6-10 min |
| Lazy loading | ไม่มี | ไม่มี |
| Cache strategy | cache-first (default) | no-cache (defaultOptions) |
| Stimulsoft | (ไม่มีในประมาณการ) | 5MB |
| MUI v5 | ไม่มี | ใช้น้อย |
| Code splitting | แทบไม่มี | แทบไม่มี |