L
JavaScript • Literally Web ID

Optimasi Edge Caching dan WAF Cloudflare untuk Aplikasi Single Page

⏱️ 18 menit baca • 📅 12 Oct 2026 • 👁️ 1 views
Optimasi Edge Caching dan WAF Cloudflare untuk Aplikasi Single Page

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap pengembangan aplikasi web modern, arsitektur Single Page Application (SPA) yang dibangun menggunakan kerangka kerja seperti React, Vue, Angular, atau Svelte telah menjadi standar industri. Keunggulan utama SPA adalah pengalaman pengguna (UX) yang sangat mulus, menyerupai aplikasi native desktop atau mobile, karena proses rendering UI dilakukan sepenuhnya di sisi klien (Client-Side Rendering) melalui eksekusi JavaScript.

Namun, arsitektur ini mendatangkan tantangan operasional yang masif bagi tim Infrastructure Engineer dan SecOps. Bottleneck performa terbesar pada SPA bukanlah pada komputasi klien, melainkan pada Time to First Byte (TTFB) dari entrypoint utama (index.html) dan latensi unduhan asset statis (JavaScript chunks dan CSS bundles). Karena seluruh rute aplikasi bergantung pada satu berkas index.html, kegagalan mengonfigurasi cache dengan benar akan menyebabkan setiap navigasi ulang atau refresh halaman mengharuskan klien mengunduh ulang seluruh aset dari origin server. Hal ini membebani infrastruktur backend, meningkatkan biaya egress bandwidth cloud, dan memperlambat muat halaman global.

Dari sudut pandang keamanan, SPA mengekspos endpoint API backend secara langsung melalui browser. Tanpa lapisan proteksi yang memadai di edge network, aplikasi rentan terhadap serangan Distributed Denial of Service (DDoS), serangan brute-force pada endpoint otentikasi, serta eksploitasi kerentanan logika bisnis oleh bot jahat yang menyamar sebagai pengguna sah.

Sebelum vs Sesudah Penerapan Optimasi Edge & WAF Cloudflare

Metrik / Aspek Sebelum Optimasi (Origin Direct / Cache Default) Sesudah Optimasi (Cloudflare Edge Caching & WAF) Dampak Bisnis / Teknis
TTFB Global 450ms - 1200ms (tergantung lokasi origin) 15ms - 45ms (dilayani dari Cloudflare Edge PoP terdekat) Peningkatan drastis pada skor Core Web Vitals (LCP & FID).
Beban CPU Origin Server Tinggi (melayani seluruh request asset dan HTML) Berkurang hingga 95% (hanya melayani API dinamis dan webhook) Efisiensi biaya infrastruktur, pencegahan autoscaling berlebih.
Mitigasi Bot & DDoS Mengandalkan rate-limiting aplikasi backend (rentan exhaustion) Ditangkap di Edge via Cloudflare WAF, Managed Ruleset, dan Bot Management Zero downtime saat serangan Layer 7 skala masif.
Manajemen Cache Update Manual, sering terjadi isu stale cache pada file JS baru setelah deploy Otomatis via Cloudflare API / CI/CD Pipeline dengan Purging terarah Zero-deployment downtime, pengguna selalu mendapat versi terbaru.

[!IMPORTANT] Mengabaikan pemisahan aturan cache antara berkas index.html dan hashed asset chunks adalah kesalahan fatal yang menyebabkan pengguna menjalankan versi aplikasi kadaluarsa meskipun deployment baru telah sukses dilakukan.


2. Konsep Inti & Deep Dive Arsitektur

Untuk memahami bagaimana mengoptimalkan SPA di ekosistem Cloudflare, kita harus membedah siklus hidup request (request lifecycle) dari browser pengguna hingga mencapai server origin.

[ Browser Pengguna ] 
        │
        ▼ (HTTPS Request)
[ Cloudflare Edge PoP (Anycast DNS) ]
        ├──> Cek WAF & Managed Rules (Blokir Bot/DDoS)
        ├──> Cek Cache Rules:
        │      ├──> Jika `index.html`: Bypass / Stale-While-Revalidate (SWR)
        │      └──> Jika Asset (`*.js`, `*.css`): Cache TTL Panjang (Immutable)
        │
        ├── (Cache HIT)  ──> Kembalikan Response Langsung ke Browser
        │
        └── (Cache MISS) ──> Teruskan ke Origin Server (Nginx / S3 / Node.js)

Anatomi Aset SPA

  1. Entrypoint (index.html): Berkas HTML yang sangat kecil namun memuat referensi ke seluruh aset JavaScript dan CSS utama. Berkas ini tidak boleh di-cache secara permanen karena berisi referensi hash dari build terbaru.
  2. Asset Chunks (/static/js/*.hash.js, /static/css/*.hash.css): Berkas yang dihasilkan oleh bundler (Webpack, Vite, Rollup) dengan menyertakan hash kriptografi pada nama filenya (contoh: main.a1b2c3d4.js). Karena nama file akan berubah total setiap kali ada perubahan kode, aset ini sangat aman untuk di-cache selamanya (immutable).

Alur Eksekusi Cloudflare Workers & Cache Rules

Cloudflare Cache Rules mengevaluasi ekspresi kondisi (seperti http.request.uri.path) untuk menentukan tindakan cache. Ketika Cloudflare Workers dilibatkan di edge, kita dapat melakukan manipulasi request/response secara programmatic sebelum cache dievaluasi, memungkinkan Edge Routing, A/B Testing, atau Dynamic Injection tanpa membebani origin.


3. Perbandingan Komparatif / Analisis Pendekatan

Dalam mengonfigurasi caching dan sekuritas SPA di Cloudflare, terdapat beberapa pendekatan arsitektural yang dapat dipilih berdasarkan kompleksitas aplikasi:

Pendekatan Arsitektur Kompleksitas Setup Fleksibilitas Routing Latency Overhead Biaya Operasional
1. Standar Page Rules (Legacy) Rendah Terbatas (3 aksi per rule) Sangat Rendah Gratis / Free Tier
2. Cache Rules + WAF Managed Rules Menengah Tinggi (Ekspresi Filter Kompleks) Rendah Pro / Business Tier
3. Cloudflare Workers (Edge Routing + Cache API) Tinggi Maksimal (Full Programmability) Sedang (Tergantung kompleksitas script) Enterprise / Workers Paid

Analisis Trade-off

  • Pendekatan Page Rules sudah mulai usang dan dibatasi jumlahnya oleh Cloudflare. Pendekatan ini tidak direkomendasikan untuk aplikasi enterprise skala besar karena keterbatasan logika percabangan.
  • Pendekatan Cache Rules modern menawarkan performa optimal dengan menggunakan sintaks ekspresi mirip Wireshark, memproses aturan secara paralel di edge tanpa latensi tambahan dari eksekusi JavaScript v8 engine.
  • Cloudflare Workers memberikan kontrol mutlak. Kita dapat memprogram ulang header cache secara dinamis, melakukan HTML rewriting di edge untuk OpenGraph tags, atau menerapkan autentikasi berbasis JWT langsung sebelum request menyentuh origin. Trade-off-nya adalah kurva pembelajaran yang lebih curam dan manajemen kode worker di dalam repositori proyek.

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum menyelam ke konfigurasi teknis, pastikan environment berikut telah terpenuhi:

  1. Domain Terdaftar di Cloudflare: Pastikan nameserver domain Anda telah diarahkan ke Cloudflare dan status proxy DNS aktif (ikon awan oranye / Proxied).
  2. Akses API & Global Token: Memiliki Cloudflare API Token dengan hak akses minimal: Zone.Zone Settings (Read), Zone.Zone (Read), Zone.Cache Rules (Edit), Zone.WAF (Edit), dan Workers Scripts (Edit).
  3. Build Tool SPA: Proyek frontend menggunakan Vite, Webpack, atau Next.js (Static Export) yang menghasilkan direktori dist/ atau build/ dengan hash asset.
  4. Origin Server: Web server (Nginx/Caddy) atau Object Storage (AWS S3 / MinIO) tempat berkas SPA di-host.

5. Panduan Implementasi Langkah demi Langkah

Langkah 1: Konfigurasi Web Server Origin (Nginx)

Meskipun aset akan di-cache di Cloudflare, origin server harus menyiapkan header yang benar untuk mengantisipasi cache miss.

server {
    listen 80;
    server_name app.domain.com;
    root /var/www/spa/dist;
    index index.html;

    # Gzip / Brotli Compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Cache Policy untuk Asset Chunks dengan Hash (Immutable)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, max-age=31536000, immutable";
        access_log off;
    }

    # Jangan pernah cache index.html di origin secara permanen
    location = /index.html {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
        expires 0;
    }
}

Langkah 2: Konfigurasi Cloudflare Cache Rules via Terraform / API

Kita menggunakan Terraform untuk mendefinisikan aturan cache Cloudflare secara deklaratif agar tercatat dalam Infrastructure as Code (IaC).

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

resource "cloudflare_cache_rules" "spa_assets" {
  zone_id = var.cloudflare_zone_id
  rules {
    name        = "Cache Static Chunks Immutable"
    enabled     = true
    expression  = "http.request.uri.path wildcard \"/static/*\""
    action      = "set_cache_settings"
    action_parameters {
      cache = true
      edge_ttl {
        mode    = "override_origin"
        default = 31536000 # 1 Tahun
      }
      browser_ttl {
        mode    = "override_origin"
        default = 31536000
      }
    }
  }
}

resource "cloudflare_cache_rules" "spa_index" {
  zone_id = var.cloudflare_zone_id
  rules {
    name        = "Bypass Cache Index HTML"
    enabled     = true
    expression  = "http.request.uri.path eq \"/index.html\" or http.request.uri.path eq \"/\""
    action      = "set_cache_settings"
    action_parameters {
      cache = false
    }
  }
}

Langkah 3: Strategi Purging Cache Otomatis via CI/CD (GitHub Actions)

Setiap kali deployment baru dilakukan, cache Cloudflare untuk index.html dan file manifest harus dibersihkan agar pengguna langsung mengambil versi terbaru.

name: Deploy SPA and Purge Cloudflare Cache

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install Dependencies & Build
        run: |
          npm ci
          npm run build

      - name: Deploy to Origin Server (rsync over SSH)
        uses: easingthemes/ssh-deploy@v5
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          ARGS: "-rltgoDzvO --delete"
          SOURCE: "dist/"
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_USER: ${{ secrets.REMOTE_USER }}
          TARGET: "/var/www/spa/dist/"

      - name: Purge Cloudflare Cache
        uses: jakejarvis/cloudflare-purge-action@v0.3.0
        env:
          CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
          CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
          PURGE_TOTAL: "true"

Langkah 4: Implementasi Cloudflare WAF Custom Rules untuk Frontend Entrypoint

Lindungi SPA dari serangan brute-force pada halaman login dan serangan bot scraping dengan WAF Custom Rules.

{
  "filter": {
    "expression": "(http.request.uri.path eq \"/api/v1/auth/login\" and http.request.method eq \"POST\")",
    "paused": false,
    "description": "Rate Limit Login Endpoint to prevent Brute Force"
  },
  "action": "block",
  "ratelimit": {
    "characteristics": ["ip.src"],
    "period": 60,
    "requests_per_period": 5,
    "mitigation_timeout": 600
  }
}

Langkah 5: Implementasi Edge Routing Menggunakan Cloudflare Workers

Script Worker berikut menangani Single Page Application fallback routing di edge, memastikan semua rute non-file mengembalikan index.html tanpa membebani origin server.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;

  // Daftar ekstensi file statis yang valid
  const staticExtensions = ['.js', '.css', '.png', '.jpg', '.jpeg', '.svg', '.ico', '.json', '.woff', '.woff2'];
  const isStaticFile = staticExtensions.some(ext => path.endsWith(ext));

  // Jika ini adalah aset statis atau request API, teruskan langsung ke origin
  if (isStaticFile || path.startsWith('/api/')) {
    return fetch(request);
  }

  // Untuk semua rute SPA lainnya (misal: /dashboard, /settings), rewrite ke /index.html
  const indexUrl = new URL('/index.html', url.origin);
  const proxyRequest = new Request(indexUrl, {
    headers: request.headers,
    method: request.method,
  });

  let response = await fetch(proxyRequest);
  
  // Pastikan header cache untuk index.html di edge diatur agar tidak di-cache permanen
  response = new Response(response.body, response);
  response.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate');
  
  return response.exec ? response : response;
}

6. Bedah Kode & Penjelasan Detail Baris Kunci

  1. try_files $uri $uri/ /index.html; (Nginx): Baris ini adalah inti dari routing SPA di web server. Jika berkas fisik sesuai URL tidak ditemukan ($uri), Nginx tidak mengembalikan error 404, melainkan mengarahkan ulang request ke /index.html, menyerahkan manajemen rute selanjutnya kepada Router JavaScript di sisi klien (React Router / Vue Router).
  2. add_header Cache-Control "public, max-age=31536000, immutable"; (Nginx & Cloudflare): Parameter immutable memberi tahu browser modern bahwa aset ini tidak akan pernah berubah selama masa berlakunya. Browser tidak akan mengirimkan conditional request (If-Modified-Since / ETag) ke server saat pengguna memuat ulang halaman, memangkas latensi jaringan secara signifikan.
  3. PURGE_TOTAL: "true" (GitHub Actions): Dalam skrip deployment, pembersihan cache total dilakukan setelah rilis baru. Untuk aplikasi skala enterprise besar, disarankan menggunakan Tagged Cache Purging agar hanya berkas HTML dan manifest yang dibersihkan, sementara aset chunk lama tetap aman di cache edge untuk pengguna yang sedang aktif di sesi sebelumnya.
  4. characteristics: ["ip.src"] & requests_per_period: 5 (WAF): Aturan pembatasan tingkat (rate limiting) ini memantau alamat IP sumber secara ketat. Jika sebuah IP mengirimkan lebih dari 5 request POST ke endpoint /api/v1/auth/login dalam kurun waktu 60 detik, Cloudflare akan memblokir IP tersebut selama 10 menit (mitigation_timeout: 600).

7. Skenario Produksi & Studi Kasus Dunia Nyata

Studi Kasus: E-Commerce Flash Sale Skala Global

Sebuah platform e-commerce berbasis SPA mengalami lonjakan trafik hingga 500.000 Request Per Second (RPS) saat event flash sale. Sebelum optimasi, server origin mengalami database connection exhaustion karena ribuan bot mencoba melakukan scraping pada halaman katalog dan melakukan credential stuffing pada form login.

Solusi Arsitektur yang Diterapkan:

  1. Cloudflare Cache Rules: Seluruh halaman katalog produk statis dan aset JS di-cache di 300+ Edge PoP Cloudflare di seluruh dunia.
  2. Cloudflare Waiting Room: Diaktifkan di depan entrypoint SPA (/). Ketika trafik melebihi kapasitas backend, pengguna baru akan ditempatkan di ruang tunggu virtual interaktif berbasis antrean FIFO (First In, First Out), menjaga load origin tetap stabil pada tingkat 20%.
  3. WAF Bot Management: Mengaktifkan JavaScript Detection dan Machine Learning Bot Score dari Cloudflare untuk membedakan pembeli manusia asli dari bot skrip automasi (Puppeteer/Selenium).

Hasil Akhir: Origin server bertahan tanpa satupun downtime, TTFB rata-rata turun dari 850ms menjadi 22ms secara global, dan upaya serangan bot berhasil diblokir 100% di edge sebelum mencapai lapisan aplikasi backend.


8. Common Pitfalls, Anti-Patterns & Solusi

[!WARNING] Anti-Pattern 1: Mengaktifkan Caching Menyeluruh (/*) Tanpa Pengecualian Mengatur Cloudflare cache untuk mencakup seluruh path termasuk index.html dan file service-worker.js akan mengakibatkan pengguna terjebak selamanya dalam versi aplikasi lama. Solusi: Selalu buat aturan pengecualian (bypass cache) untuk index.html, service-worker.js, dan semua endpoint API dinamis.

[!WARNING] Anti-Pattern 2: Mengabaikan Header Vary Kegagalan mengonfigurasi header Vary: Accept-Encoding atau Vary: Authorization dapat menyebabkan Cloudflare menyajikan cache respons pengguna terautentikasi kepada pengguna anonim (Cache Poisoning / Data Leak). Solusi: Pastikan origin mengirimkan header Vary yang akurat atau gunakan Cloudflare Cache Key customization.


9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memastikan konfigurasi edge caching dan WAF memberikan dampak nyata, lakukan pengujian performa menggunakan tool seperti k6 atau wrk serta audit menggunakan Google Lighthouse.

Perintah Pengujian Beban dengan wrk

# Menguji performa endpoint SPA melalui Cloudflare Edge (100 thread, 1000 koneksi selama 30 detik)
wrk -t100 -c1000 -d30s https://app.domain.com/index.html

Interpretasi Metrik Kinerja Target

  • Requests/sec: Harus mencatatkan angka di atas 10.000 RPS untuk Cache HIT di edge Cloudflare.
  • Latency Distribution: 99% request (p99) harus berada di bawah 50ms untuk pengguna di regional yang sama dengan PoP edge.
  • Lighthouse Performance Score: Memastikan skor First Contentful Paint (FCP) di bawah 0.8 detik dan Largest Contentful Paint (LCP) di bawah 1.5 detik.

10. Checklist Penerapan Produksi & Kesimpulan

Gunakan checklist berikut sebelum merilis arsitektur optimasi SPA ke lingkungan produksi:

  • Cloudflare Cache Rules telah dikonfigurasi membedakan index.html (Bypass) dan Asset Chunks (Immutable).
  • Skrip CI/CD otomatis melakukan cache purge (index.html) setiap kali deployment berhasil.
  • Nginx/Origin Server mengembalikan header Cache-Control dan ETag yang tepat.
  • Cloudflare WAF Custom Rules aktif untuk mitigasi rate-limiting pada endpoint autentikasi.
  • Cloudflare Workers (jika digunakan) telah diuji terhadap kasus edge routing rute SPA tanpa infinite loop.
  • Pengujian Lighthouse dan load testing (k6/wrk) menunjukkan peningkatan skor performa minimal 70%.

Dengan menerapkan strategi komprehensif ini, aplikasi Single Page Anda tidak hanya akan berjalan dengan kecepatan kilat berkat distribusi edge global Cloudflare, tetapi juga terlindung secara kokoh dari berbagai ancaman eksploitasi keamanan modern.

🏷️ Tags: #Cloudflare #Edge Caching #Web Performance #Spa #Waf