Skip to content

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):

json
"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:

dockerfile
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 v5
  • NODE_OPTIONS=--max-old-space-size=4096 — heap 4GB (Webpack ของ CRA 3.4.3 out-of-memory ถ้าไม่เพิ่ม)
  • CI=false — ปิด warning-as-error
  • GENERATE_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 MBUI library หลัก
@mui/*@5.11~300 KBใช้น้อย (WorkForce module)
react@16.14 + react-dom@16.14~150 KBcore
react-apollo@3.1 + Apollo ecosystem~280 KBGraphQL
recoil@0.7~50 KBstate (module ใหม่)
moment@2.29~300 KBdate
chart.js@3 + react-chartjs-2~250 KBcharts
stimulsoft-reports-js~5 MBreport — ใหญ่มาก
xlsx@0.18 + exceljs~800 KBExcel export
@react-pdf/renderer + react-pdf + pdfjs-dist~2 MBPDF preview
crypto-js~120 KBAES
Misc (lodash, axios, qrcode, react-router-dom, ...)~1 MB

รวม ~11-13 MB (gzip ~3-4 MB)

สาเหตุที่ bundle ใหญ่กว่า vtrc-web

  1. Stimulsoft Reports (~5MB) — ใช้สำหรับ report generation ฝั่ง client แต่ load ตั้งแต่ app boot
  2. MUI v5 (~300KB) — ใช้แค่ WorkForce module แต่อยู่ใน bundle ทั้งหมด
  3. 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:

  1. Code splittingReact.lazy(() => import('./StimulsoftReport')) แยก Stimulsoft เป็น chunk
  2. AntD tree-shakebabel-plugin-import
  3. MUI v5 consolidate — ตัดออกถ้าเปลี่ยน WorkForce ไป AntD ได้
  4. Replace moment.js — ด้วย date-fns (50KB)

PERF-VTRC-RC-02 · fetchPolicy: 'no-cache' — network load สูง

ที่: vtrc-rc-backoffice/src/config/apollo.js:171-185

Evidenceapollo.js:171-185:

javascript
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:

  1. Babel swc plugin (faster)
  2. Webpack 5 migration (build time -40%)
  3. 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)

  1. Lazy-load Stimulsoft — ลด bundle 5MB, investment ปานกลาง
  2. AntD tree-shake — ลด bundle ~600KB, investment เล็ก
  3. Code splitting — ลด TTI, investment ปานกลาง
  4. Replace moment.js — ลด bundle ~250KB, investment ปานกลาง
  5. CRA → Webpack 5 migration — build time -40%, investment ใหญ่
  6. Consolidate MUI v5 → AntD v4 — ลด bundle 300KB, investment ใหญ่

เปรียบเทียบกับ vtrc-web

ด้านvtrc-webvtrc-rc-backoffice
Build systemWebpack 4 (ejected)CRA 3.4.3 (not ejected)
Webpack configcustomdefault
Node (build)1416
Bundle~12 MB~11-13 MB
TTI~5-8s~5-8s
Build time~5-8 min~6-10 min
Lazy loadingไม่มีไม่มี
Cache strategycache-first (default)no-cache (defaultOptions)
Stimulsoft(ไม่มีในประมาณการ)5MB
MUI v5ไม่มีใช้น้อย
Code splittingแทบไม่มีแทบไม่มี

ขั้นตอนถัดไป

ไป บท 4.2.7 Scorecard + known bugs