Canary deploy untuk asset font relevan saat perubahan file font bisa mengubah rendering teks, memicu fallback browser, merusak layout, atau dalam kasus khusus seperti font berbasis QR, menurunkan keberhasilan pemindaian. Masalahnya bukan hanya apakah file berhasil diunduh, tetapi apakah font benar-benar dipakai, dirender konsisten, dan aman untuk pengguna nyata.

Pendekatan yang paling aman adalah memperlakukan font sebagai artefak produksi yang punya versi, checksum, observabilitas, dan jalur rollback cepat. Untuk tim kecil, ini bisa diterapkan tanpa platform rumit: gunakan object storage atau CDN, rilis bertahap lewat manifest atau feature flag, ukur kegagalan load dan dampaknya ke layout, lalu siapkan prosedur rollback yang tidak bergantung pada purge cache panik.

Mengapa asset font perlu canary deploy

Banyak tim menganggap font hanyalah file statis. Dalam praktiknya, font memengaruhi beberapa lapisan sistem:

  • Rendering visual: perubahan glyph, kerning, hinting, atau metrik font dapat menggeser layout dan memicu layout shift.
  • Fallback browser: jika font gagal dimuat atau dianggap invalid, browser akan jatuh ke fallback font yang lebarnya bisa berbeda jauh.
  • Performa: ukuran file, format, dan cache policy memengaruhi waktu render teks.
  • Fungsi bisnis: pada font khusus seperti font untuk pola QR atau simbol machine-readable, sedikit perubahan bentuk glyph dapat menurunkan scanability.

Canary deploy mengurangi risiko dengan membatasi dampak awal. Alih-alih langsung mengganti seluruh traffic ke file font baru, Anda mengarahkan sebagian kecil pengguna ke versi baru dan memantau sinyal teknis sebelum rollout penuh.

Arsitektur rilis aman untuk font di CDN atau object storage

Prinsip dasar

Jangan menimpa file font lama di path yang sama. Gunakan nama file berversi atau berbasis hash agar setiap rilis bersifat immutable. Ini penting karena cache browser dan cache CDN sering bertahan lebih lama daripada yang diperkirakan.

Contoh struktur yang lebih aman:

/fonts/qrfont/2026-07-08/qrfont-4f9c2a.woff2
/fonts/qrfont/2026-07-08/manifest.json

Dengan pendekatan ini:

  • aset lama tetap tersedia untuk rollback,
  • cache bisa diatur agresif untuk file font yang immutable,
  • peralihan versi dilakukan lewat referensi, bukan overwrite.

Checksum dan versioning

Simpan metadata rilis minimal berupa:

  • version: misalnya timestamp atau nomor build,
  • checksum: SHA-256 atau hash lain untuk memastikan artefak yang diunggah identik dengan hasil build,
  • format: misalnya WOFF2 dan bila perlu WOFF,
  • source commit: commit aplikasi atau repository desain/font yang menghasilkan file tersebut.

Manifest sederhana dapat dipakai untuk mengikat aplikasi ke versi font tertentu:

{
  "fontFamily": "QRCustom",
  "version": "2026-07-08T10:30Z",
  "files": {
    "woff2": "/fonts/qrfont/2026-07-08/qrfont-4f9c2a.woff2"
  },
  "checksum": {
    "woff2": "sha256-BASE64_OR_HEX_VALUE"
  }
}

Aplikasi frontend bisa mengambil manifest ini, atau lebih sederhana lagi, build aplikasi menghasilkan CSS yang merujuk ke versi tertentu. Kunci utamanya: versi font harus dapat dibalik dengan cepat.

Header cache yang disarankan

Untuk file font yang immutable, gunakan masa cache panjang. Untuk manifest atau pointer aktif, gunakan cache pendek.

  • File font berversi: Cache-Control: public, max-age=31536000, immutable
  • Manifest aktif: Cache-Control: public, max-age=30 atau lebih pendek sesuai kebutuhan rollout

Trade-off-nya jelas: file immutable aman untuk performa dan konsistensi, tetapi Anda harus mengubah referensi untuk beralih versi. Ini justru yang diinginkan pada canary deploy.

Pola canary deploy untuk asset font

Opsi 1: Canary lewat manifest atau config endpoint

Ini pola yang paling fleksibel. Sebagian kecil pengguna menerima manifest yang merujuk ke font baru, sedangkan mayoritas tetap menerima font lama. Routing canary dapat ditentukan oleh:

  • cookie,
  • header request dari edge/CDN,
  • persentase hash dari user ID anonim,
  • feature flag dari aplikasi.

Keunggulan pola ini adalah rollback cukup dengan mengubah pointer manifest kembali ke versi stabil tanpa menghapus file font dari storage.

Opsi 2: Canary lewat CSS terpisah

Jika aplikasi Anda sudah punya pipeline CSS yang rapi, buat dua varian stylesheet:

  • stylesheet stabil merujuk ke font versi lama,
  • stylesheet canary merujuk ke font versi baru.

Lalu kontrol pemilihannya lewat feature flag atau edge logic. Ini lebih mudah dipahami, tetapi sedikit kurang granular dibanding manifest jika Anda ingin mengubah font tanpa menerbitkan ulang CSS utama.

Opsi 3: Canary di level CDN/path

Beberapa tim memilih membagi traffic edge ke dua origin path berbeda, misalnya /fonts/stable/... dan /fonts/canary/.... Pendekatan ini bisa bekerja, tetapi perhatikan bahwa observabilitas dan kontrol rollback sering lebih jelas jika aplikasi mengetahui versi font mana yang sedang dipakai.

Catatan: untuk font yang memengaruhi scanability, jangan hanya mengukur keberhasilan download file. Anda perlu memvalidasi hasil render akhir.

Implementasi frontend yang praktis

Contoh @font-face dengan fallback yang eksplisit

@font-face {
  font-family: 'QRCustom';
  src: url('/fonts/qrfont/2026-07-08/qrfont-4f9c2a.woff2') format('woff2');
  font-display: swap;
}

.qr-text {
  font-family: 'QRCustom', 'Segoe UI Symbol', sans-serif;
}

font-display: swap membantu menghindari teks kosong terlalu lama, tetapi ada trade-off: fallback bisa sempat muncul sebelum font utama termuat. Jika metrik fallback sangat berbeda, ini dapat menambah CLS. Untuk elemen kritis seperti teks yang harus dipindai atau dicetak, Anda mungkin memilih strategi render yang lebih ketat pada area tertentu, bukan global.

Feature flag sederhana di aplikasi

Contoh berikut menunjukkan ide dasarnya: server memilih URL CSS/font berdasarkan flag. Implementasinya bisa di backend, edge worker, atau frontend config bootstrap.

const fontConfig = window.__FONT_CONFIG__;
const style = document.createElement('style');
style.textContent = `
  @font-face {
    font-family: 'QRCustom';
    src: url('${fontConfig.woff2}') format('woff2');
    font-display: swap;
  }
`;
document.head.appendChild(style);

Jika Anda memakai flag, pastikan ada default yang aman. Saat config gagal dimuat, aplikasi harus jatuh ke font stabil atau fallback font yang sudah diuji.

Observabilitas yang benar-benar berguna

Pada canary deploy untuk font, observabilitas harus menjawab empat pertanyaan:

  1. Apakah file font berhasil diambil?
  2. Apakah browser benar-benar memakainya?
  3. Apakah layout atau performa memburuk?
  4. Untuk font khusus, apakah output tetap bisa dipindai atau dibaca mesin?

Metrik inti

  • Error rate asset: status 4xx/5xx saat mengambil file font dari CDN/object storage.
  • Font load failure: kegagalan load menurut browser, misalnya promise FontFaceSet gagal atau timeout internal aplikasi.
  • Fallback usage rate: persentase sesi yang berakhir memakai fallback font untuk elemen target.
  • CLS: amati apakah versi canary menaikkan layout shift pada halaman yang menggunakan font tersebut.
  • Render timing: waktu hingga font siap dipakai pada komponen penting.
  • Sample scan success rate: untuk font QR/simbol machine-readable, ukur keberhasilan pemindaian pada sampel render.

Instrumentation dasar di browser

Berikut contoh ringan untuk mendeteksi apakah font siap digunakan. Ini bukan pengganti RUM penuh, tetapi cukup untuk memberi sinyal awal.

async function monitorFontLoad() {
  const startedAt = performance.now();
  try {
    await document.fonts.load("16px QRCustom");
    const loaded = document.fonts.check("16px QRCustom");
    window.dispatchEvent(new CustomEvent('font-metric', {
      detail: {
        family: 'QRCustom',
        loaded,
        durationMs: Math.round(performance.now() - startedAt)
      }
    }));
  } catch {
    window.dispatchEvent(new CustomEvent('font-metric', {
      detail: {
        family: 'QRCustom',
        loaded: false,
        durationMs: Math.round(performance.now() - startedAt)
      }
    }));
  }
}

monitorFontLoad();

Dari event ini, kirim telemetry ke endpoint analytics internal atau observability pipeline yang sudah ada. Selalu sertakan atribut berikut:

  • versi font,
  • halaman/fitur yang terpengaruh,
  • browser dan OS,
  • apakah sesi canary atau stabil.

Health check sintetis

Tambahkan pemeriksaan otomatis dari luar browser pengguna. Untuk font biasa, health check sintetis minimal memverifikasi:

  • file bisa diakses,
  • header cache sesuai harapan,
  • ukuran file tidak nol dan checksum cocok,
  • halaman uji merender teks target tanpa error konsol besar.

Untuk font yang memengaruhi scanability, buat halaman sintetis yang merender sampel representatif, ambil screenshot, lalu jalankan decoder pada hasil render tersebut. Jika decoder gagal pada varian canary tetapi lulus pada varian stabil, rollout harus berhenti.

Ini penting karena file font bisa valid secara teknis tetapi tetap gagal secara fungsional. Misalnya, bentuk glyph terlalu tipis, bounding box berubah, atau anti-aliasing membuat pola sulit dipindai di browser tertentu.

Strategi cache invalidation tanpa membuat rollback sulit

Kesalahan umum adalah mengandalkan purge cache total untuk setiap perubahan font. Ini memperbesar risiko karena hasil antar edge bisa tidak seragam selama propagasi purge.

Strategi yang lebih aman:

  • anggap file font sebagai immutable dan jangan overwrite,
  • ubah pointer aktif lewat manifest atau CSS canary,
  • gunakan TTL pendek hanya pada pointer, bukan pada file font besar,
  • purge dilakukan hanya bila ada kebocoran referensi lama yang benar-benar harus dihapus.

Dengan model ini, rollback tidak bergantung pada seberapa cepat CDN menghapus cache; cukup arahkan traffic kembali ke referensi stabil.

Rollback cepat yang realistis

Rollback cepat untuk asset font seharusnya bisa dilakukan dalam hitungan menit tanpa build ulang aplikasi utama. Siapkan prosedur yang sesederhana mungkin.

Langkah rollback operasional

  1. Hentikan ekspansi canary: bekukan rollout di persentase saat ini.
  2. Alihkan pointer aktif: ubah manifest/flag/CSS selector kembali ke versi stabil.
  3. Verifikasi sintetis: jalankan health check pada jalur stabil.
  4. Pantau metrik 10-30 menit: pastikan error rate, fallback usage, dan CLS kembali normal.
  5. Tandai artefak bermasalah: jangan hapus dulu; ubah status menjadi blocked agar tidak terpilih ulang secara otomatis.

Contoh alur rollback berbasis manifest

# sebelum rollback
active-font-version=2026-07-08T10:30Z

# sesudah rollback
active-font-version=2026-07-01T09:00Z

Jika memakai object storage, pointer aktif bisa berupa file JSON kecil atau key konfigurasi di sistem flag. Jangan simpan satu-satunya referensi versi aktif di banyak tempat sekaligus; itu memperlambat rollback dan meningkatkan peluang konfigurasi tidak sinkron.

Kapan rollback harus otomatis?

Untuk tim kecil, rollback otomatis layak dipertimbangkan jika ada ambang yang jelas, misalnya:

  • lonjakan font load failure di canary dibanding stabil,
  • kenaikan error 404/5xx pada asset font,
  • sample scan success turun di bawah ambang aman internal,
  • CLS atau fallback usage meningkat signifikan pada halaman target.

Ambang tepatnya berbeda tiap sistem. Yang penting, definisikan sebelum rilis, bukan saat insiden sedang berlangsung.

Pencegahan sebelum rilis

Preflight test lintas browser

Sebelum canary, uji minimal pada kombinasi browser yang benar-benar dipakai pengguna Anda. Fokus pada:

  • Chrome/Chromium, Firefox, Safari, dan browser mobile utama,
  • perbedaan rendering pada OS berbeda,
  • fallback saat koneksi lambat atau file gagal dimuat,
  • layout pada ukuran teks yang penting untuk produk.

Untuk font khusus seperti font QR, sertakan uji screenshot atau render sampling di lebih dari satu browser engine. Hasil yang terlihat mirip secara visual belum tentu sama untuk decoder.

Fallback font yang disengaja

Jangan biarkan fallback dipilih secara kebetulan. Tetapkan fallback yang paling dekat metriknya dengan font utama, atau untuk area yang sensitif, tampilkan mode degradasi yang tidak bergantung pada font kustom.

Contohnya, bila komponen QR text gagal memakai font khusus, aplikasi bisa:

  • mengganti ke gambar atau SVG yang sudah dihasilkan server,
  • menonaktifkan tampilan interaktif tertentu,
  • menampilkan pesan bahwa render machine-readable tidak tersedia.

Ini lebih baik daripada menampilkan fallback acak yang terlihat “cukup mirip” tetapi tidak bisa dipindai.

Checklist sebelum menekan tombol rollout

  • File font punya versi unik dan checksum tercatat.
  • Manifest atau pointer aktif bisa diubah tanpa deploy aplikasi penuh.
  • File stabil masih tersedia di origin/CDN.
  • Header cache untuk file font dan manifest sudah dibedakan.
  • Health check sintetis lulus pada jalur canary.
  • RUM atau telemetry minimal untuk font load sudah aktif.
  • Fallback path telah diuji secara sengaja.
  • Runbook insiden tersedia dan mudah diakses.

Runbook insiden ringkas untuk tim kecil

Trigger

  • Error rate asset font naik.
  • Pengguna melaporkan teks rusak, layout bergeser, atau scan gagal.
  • Metrik canary menyimpang dari stabil.

Diagnosis cepat

  1. Cek versi font aktif dan persentase canary.
  2. Bandingkan status CDN/origin untuk file font stabil vs canary.
  3. Periksa apakah browser benar-benar memakai font canary atau jatuh ke fallback.
  4. Lihat dashboard CLS, error asset, dan font load failure.
  5. Untuk kasus QR, uji satu sampel render nyata dengan decoder.

Aksi

  1. Jika dampak nyata terlihat, rollback pointer ke versi stabil.
  2. Bekukan perubahan lain sampai sinyal stabil.
  3. Kumpulkan artefak: URL file, checksum, screenshot, browser affected, log request CDN.

Komunikasi internal

  • Versi yang bermasalah
  • Mulai kejadian
  • Dampak fitur/halaman
  • Status rollback
  • Tindak lanjut investigasi

Template postmortem ringan

Postmortem tidak harus panjang. Untuk insiden asset font, format ringkas berikut biasanya cukup:

Judul:
Insiden canary font QRCustom versi 2026-07-08

Ringkasan:
Versi canary menyebabkan fallback pada browser tertentu dan menurunkan keberhasilan pemindaian pada sampel render.

Timeline:
- Rilis canary dimulai
- Alert pertama muncul
- Validasi manual dilakukan
- Rollback selesai
- Metrik kembali normal

Dampak:
- Halaman/fitur terdampak
- Persentase traffic terdampak
- Gejala utama: fallback, CLS, scan gagal, atau error asset

Akar masalah:
- Contoh: glyph/metrik berubah, file korup, header salah, path salah, CORS, cache pointer tidak sinkron

Deteksi:
- Metrik/alert apa yang pertama kali menangkap masalah
- Apa yang terlambat terdeteksi

Resolusi:
- Langkah rollback
- Validasi pasca-rollback

Pencegahan:
- Tambah preflight browser tertentu
- Tambah synthetic scan test
- Perbaiki fallback path
- Tambah guardrail rollout otomatis

Kesalahan umum yang sering terjadi

  • Overwrite file font lama: rollback jadi sulit karena cache pengguna tidak seragam.
  • Tidak mencatat versi aktif: tim bingung file mana yang sedang dipakai produksi.
  • Hanya memantau 200 OK: file berhasil diambil belum berarti font benar-benar dipakai.
  • Mengabaikan fallback: masalah nyata sering tersembunyi sebagai fallback diam-diam.
  • Tidak menguji browser engine berbeda: render font dapat berbeda cukup jauh antar engine.
  • Tidak punya jalur degradasi: komponen kritis tetap dipaksa tampil meski font gagal.

Alur operasional yang bisa langsung diterapkan

  1. Build font baru, hitung checksum, unggah ke path berversi di object storage.
  2. Publikasikan manifest canary yang merujuk ke versi baru.
  3. Arahkan 1% traffic lewat feature flag atau edge rule.
  4. Pantau 15-30 menit: error asset, font load failure, fallback rate, CLS, dan sample scan success.
  5. Jika aman, naikkan bertahap ke 5%, 25%, 50%, lalu 100%.
  6. Jika ada penyimpangan, rollback pointer ke versi stabil tanpa menghapus file baru.
  7. Dokumentasikan hasil dan perbarui checklist bila ada celah proses.

Canary deploy untuk asset font paling efektif bila diperlakukan seperti deployment kode: ada artefak immutable, distribusi bertahap, sinyal observabilitas yang tepat, dan rollback yang sudah dilatih. Untuk font biasa ini mencegah layout rusak dan fallback tak terduga; untuk font khusus seperti font QR, pendekatan ini juga menjaga agar output tetap dapat dipindai di kondisi nyata.