Blog / Tehnologija i razvoj / Deploy

Cache busting za CSS,
JavaScript i slike

Cache je odličan dok korisniku ne prikaže staru verziju CSS-a, JavaScripta ili slike. Cache busting rješava taj problem tako da browser dobije novu verziju asseta kada se stvarno promijeni, a stare assete i dalje može učinkovito cacheirati.

Cache busting za CSS, JavaScript i slike u custom web deployu

Cache busting je mali detalj koji sprječava veliki broj čudnih produkcijskih problema: “meni radi”, “klijent još vidi staru verziju”, “CSS se nije primijenio”, “slika je stara” ili “JavaScript handler ne odgovara novom HTML-u”. Kod custom webova jednostavan assembly broj često je dovoljan da deploy bude predvidljiv.

Suština: asseti trebaju biti dugo cacheirani, ali URL asseta mora se promijeniti kada se promijeni sadržaj asseta. Najjednostavniji način je dodati verziju, primjerice ?v=1.0.70, na CSS, JS i važne slike.

1. Zašto cache busting postoji

Browser cache smanjuje broj requestova i ubrzava web. Ako korisnik već ima style.css, browser ga ne mora ponovno preuzeti na svakoj stranici. Problem nastaje kada deployate novu verziju CSS-a, ali browser i dalje koristi staru datoteku iz cachea.

To je posebno neugodno kada se HTML i CSS/JS mijenjaju zajedno. Novi HTML može očekivati novu CSS klasu ili novi JavaScript behavior, ali browser servira stari asset. Rezultat je vizualni bug koji se ne vidi svima jednako, jer ovisi o cache stanju pojedinog korisnika.

2. Query string verzioniranje

Najjednostavniji cache busting pattern je dodati verziju na kraj asset URL-a. Datoteka može ostati style.css, ali URL postaje style.css?v=1.0.70. Kada se verzija promijeni, browser tretira URL kao novi resurs.

HTML Verzionirani asset URL-ovi
<link rel="stylesheet" href="/assets/css/style.css?v=1.0.70">
<script src="/assets/js/main.js?v=1.0.70"></script>
<img src="/assets/images/hero.webp?v=1.0.70" alt="Hero slika">

Ovo nije jedini način. Možete koristiti i fingerprint u nazivu datoteke, primjerice style.a8f31.css. To je vrlo dobro za build sustave. Ali za manji custom PHP web, assembly verzija u query stringu često je jednostavnija i sasvim dovoljna.

3. ASSEMBLY konstanta kao jednostavan deploy signal

Ako web nema veliki bundler i build pipeline, možete imati jednu produkcijsku konstantu koja označava verziju deploya. Kada se promijeni CSS, JS ili javni asset koji treba osvježiti, assembly se poveća i svi asset URL-ovi dobiju novu verziju.

PHP Osnovni assembly config
<?php

const BASE_URL = 'https://example.com';
const ASSEMBLY = '1.0.70';
PHP Asset helper
<?php

function asset_url(string $path): string
{
    $path = '/' . ltrim($path, '/');

    return rtrim(BASE_URL, '/') . $path . '?v=' . rawurlencode(ASSEMBLY);
}

Nakon toga templatei ne trebaju ručno slagati verziju. Svi asseti prolaze kroz isti helper, što smanjuje šansu da jedna datoteka ostane bez verzije.

4. Primjena u headeru i footeru

CSS i JavaScript su najvažniji kandidati za cache busting jer promjene u njima mogu odmah razbiti layout ili interakciju. Ako web ima light/dark CSS, dodatne theme datoteke ili JS module, svi trebaju istu verzijsku disciplinu.

PHP/HTML CSS i JS kroz helper
<link rel="stylesheet" href="<?= asset_url('/assets/css/style.css') ?>">

<button
    data-light-theme-href="<?= asset_url('/assets/css/style-light.css') ?>"
>
    Promijeni temu
</button>

<script src="<?= asset_url('/assets/js/main.js') ?>"></script>

5. Slike: kada verzionirati, a kada ne

Slike također mogu biti cacheirane. Ako zamijenite hero sliku istim filenameom, korisnik može još neko vrijeme vidjeti staru verziju. Query verzija to rješava. Ali ne treba panično mijenjati verziju za svaku sliku ako se ništa nije promijenilo.

Asset
Verzionirati?
Napomena
CSS
Da, uvijek kroz helper.
Stari CSS može razbiti novi HTML.
JavaScript
Da, uvijek kroz helper.
Stari JS može očekivati drugačiji DOM.
Hero slike
Da, ako se mogu zamijeniti istim filenameom.
Važno za LCP i OG/Twitter prikaz.
Uploadani media
Ovisi.
Ako filename uključuje hash ili ID verziju, query nije nužan.

6. Preload mora koristiti istu verziju kao img tag

Ako preloadate hero sliku, preload URL mora biti isti kao URL koji se kasnije koristi u img tagu. Ako preload ima ?v=1.0.70, a slika u bodyju nema verziju, browser može tretirati ta dva URL-a kao dva različita resursa i preuzeti sliku dvaput.

HTML Usklađen preload i img URL
<link
    rel="preload"
    as="image"
    href="<?= asset_url('/assets/images/hero.webp') ?>"
    type="image/webp"
    fetchpriority="high"
>

<img
    src="<?= asset_url('/assets/images/hero.webp') ?>"
    width="1024"
    height="1024"
    fetchpriority="high"
    alt="Hero slika"
>

Ova sitnica je važna za performance. Preload nije samo “dodaj link u head”; mora biti točno isti resurs koji će browser kasnije trebati.

7. Fingerprint filename vs query string

Kod većih aplikacija često se koristi fingerprint u nazivu datoteke. Build alat generira main.8fd3a2.js i taj filename se promijeni samo kada se promijeni sadržaj. To je vrlo precizno i dobro radi s CDN-ovima.

Query string pristup je jednostavniji. Jedan assembly bump osvježi sve verzionirane assete. To može biti manje precizno jer mijenja URL i za assete koji se nisu promijenili, ali kod manjih custom webova kompromis je često prihvatljiv.

Kada koristiti koji pristup

  • Query string verzija je dobra za manji custom PHP web bez bundlera.
  • Fingerprint filename je bolji za veće aplikacije s build pipelineom.
  • CDN setup može preferirati fingerprint, ovisno o cache pravilima.
  • Najvažnije je da se URL promijeni kada se sadržaj asseta promijeni.

8. HTTP cache headeri

Cache busting ne znači da treba ugasiti cache. Upravo suprotno: kada asset URL ima verziju, možete si dopustiti agresivnije cacheiranje jer nova verzija dobiva novi URL. Za statične assete često ima smisla dugi cache lifetime.

.htaccess Primjer cache headera za statične assete
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>
Oprez: ako koristite dugi cache, morate imati pouzdan cache busting. Dugi cache bez verzioniranja je pozivnica za “zašto još vidim staru verziju” probleme.

9. Deploy workflow

Cache busting mora biti dio deploy discipline. Ako se promijeni CSS, JS ili javna slika, assembly se mora bumpati. Ako se mijenja samo tekst PHP stranice bez promjene asseta, bump možda nije tehnički nužan, ali može biti dio jednostavnog pravila da svaki deploy ima novu assembly verziju.

Deploy checklist

  • Commitati promjene i provjeriti lokalno renderiranje stranica.
  • Bumpati ASSEMBLY u produkcijskom configu.
  • Uploadati samo promijenjene datoteke i potrebne assete.
  • Provjeriti da produkcijski HTML koristi novu ?v=... vrijednost.
  • Provjeriti promijenjene stranice i nove slike na produkciji.
  • Ažurirati sitemap ako je dodana ili sadržajno promijenjena javna stranica.

10. Najčešće greške

Cache busting je jednostavan, ali sitne nedosljednosti mogu napraviti nered. Najčešće greške su ručno dodavanje verzije samo na neke assete, različita verzija u preloadu i img tagu, automatsko mijenjanje verzije na svakom requestu ili prepisivanje produkcijskog configa s lokalnim vrijednostima.

Greška
Posljedica
Bolje rješenje
Verzija se generira s time().
Cache se praktički gasi na svakom requestu.
Koristiti stabilnu verziju deploya.
Neki asseti nemaju verziju.
Dio korisnika vidi staru kombinaciju HTML/CSS/JS-a.
Svi asseti idu kroz isti helper.
Preload i img imaju različit URL.
Browser može preuzeti isti asset dvaput.
Oba URL-a generirati istim helperom.

Zaključak: cache busting je mali pattern koji čuva deploy

Cache busting nije glamurozan, ali je jedan od onih tehničkih detalja koji čine produkciju mirnijom. Kada CSS, JS i slike imaju dosljednu verziju, korisnik dobiva nove assete kad treba, a browser i dalje može pametno cacheirati statične datoteke.

Kod custom webova assembly pristup je jednostavan, transparentan i lak za ručni deploy. Dobro se veže uz optimizaciju slika, Core Web Vitals i tehnički SEO. Za povezane teme pogledajte optimizaciju slika za web, Core Web Vitals i custom CMS za malu poslovnu web stranicu.

Custom web razvoj Tehnički SEO