Image resizer - performance rubrika: Programování: PHP

5 kacerr
položil/-a 5.10.2013

V ramci aplikace na jejimz vyvoji se podilim jsem implementoval image resizer, ktery vyuziva phpThumbOf knihovnu. Kdyz jsem se poustel do prvotni implementaci, tak to "vlastne nikdo nechtel", mne ale dost obtezovalo, ze jsme meli profilovy fotky v aplikaci (cca 200x200) o objemu 1MB (originaly proste byly tak velke a nikomu nejak nevadilo, ze na strance, co listovala profily - ne vsechny, ale treba 30 na strance se prenaslo 30MB dat). Pak se to zaclo pouzivat jeste tady, tamhle a ..... vzhledem k tomu, ze cela aplikace je typicka webova aplikace - trochu lepsi blog + cms, tak nakonec 90% obrazku jde skrz ten resizer.

Pote co jsem udelal tuhle hrubou implementaci, tak kdyz se to zaclo seriozne pouzivat, tak se samozrejme objevily problemy, protoze to napriklad vracelo obrazek vzdy (cachovani bylo od zacatku, nicmene pouze se preskocil krok transformace obrazku - soubor byl klientovi dale posilan pokazde)

  • implementovali jsme neco jako
      if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($thumbnailPath)){
        header('HTTP/1.0 304 Not Modified');

Pak se samozrejme ukazalo, ze je vhodne, aby krome toho, ze server vrati not modified client po nejakou dobu cachoval obrazky lokalne (pravdepodobnost nekterych, ze se zmeni je 0%, u ostatnich spis nizka nez vysoka)

  • takze jsem implementoval pro zacatek caching na 2 hodiny na klientu (nejspis zbytecne malo, ale ...)
    header('Expires: '. gmdate('D, d M Y H:i:s \G\M\T', time() + 7200));    

Kam jsem se chtel dopracovat? Predevsim ted resim jak presne se postavit k tomu cachovani na strane klienta (header expires), jak dlouho cachovat na klientu je rozumny? Hrozi mi neco co jsem "nedomyslel" ?

Pokud by se tu rozjela nejaka obsirnejsi diskuse na tohle tema, ktera by poukazala na nejaky dalsi aspekty tohodle problemu, to by bylo hezku ;-)

Komentáře

  • Twista : My vzdy pred nazev obrazku davame timestamp (tedy neco jako [timestamp]_[nazev_souboru]), pote si nemusis lamat hlavu s tim na jak dlouho nastavovat dobu expirace. 5.10.2013
odkaz
7 onelook
odpověděl/-a 5.10.2013

a) Při cachování po stanovenou dobu máš problém s tím, že uživatel nemusí vidět změnu ihned. Třeba si změní profilovou fotku a pořád vidí tu starou, což jej může zmást. Takový konkrétní případ lze sice řešit nějak explicitně (necachovat tak agresivně např. své obrázky). Ale obecně možnosti jsou:

1) dotazovat se na server při každém použití (s tím, že server může ověřit např. ETAG nebo datum poslední změny někde např. v DB, memcache apod., aniž by sahal fyzicky na soubor s obrázkem) a vrátit info, že se nic nezměnilo.

2) můžeš verzovat obrázky - tedy, když se změní obrázek, změní se i verze v URL obrázku, např. img123456.jpg?verze=123. Cache může být s neomezenou platností a po změně bude mít obrázek jinou URL a tak prohlížeč provede dotaz na server.

3) můžeš mít obrázky jako neměnné objekty. A když je třeba jej změnit, tak vytvoříš nový. V tomto případě bude třeba změnit všude, kde byla použita předchozí verze obrázku, odkaz ze starého na nový.

4) spokojit se s tím, že nebude každý koukat na nejnovější verzi obrázku (záleží na aplikaci, zda to vadí nebo nevadí). Tak to víceméně máš.

Komentáře

  • kacerr : #1 zni dobre a konkretne v mojem pripade je taky problem v tom, ze volani toho imageResizeru neni zdaleka tak lightweight jak by mohlo byt (nebal bych se rict, ze je pomerne dost heavyweight - takze tam je obrovskej prostor pro performance improvement - mozna je to taky jeden z duvodu proc bylo momentalne potreba omezit pocet volani i v pripade, ze to vracale jen 304 - not modified). Stale tam ovsem je http request pro kazde zobrazeni obrazku, ktery vnimam jako nezadouci #2 obrazky verzovat nechci, idealne chci aby klient ten obrazek pote co ho poprve stahnul vubec nepoptaval - akorat je potreba tam vyresit rovnovahu mezi cachovat prilis a cachovat malo (jak jsem psal nektere obrazky se prakticky nikdy nezmeni), nektere ovsem mohou Ted mne napada, kdyby se dalo nejakym zpusobem vynutit aby klient provedl refresh toho obrazku i kdyz drive dostal Expires header ktery jeste nevyprsel. Nejsem si uplne jisty je-li to mozny, ale teoreticky by mohlo. Nejaky javascript? I kdyz i kdyby tohle slo, tak si nejsem jistej, jestli by to slo nejak rozumne implementovat. Takze jsem se ted dopracoval k tomu, ze mozna ty profilovy obrazky verzovat chci ;-) to budu muset promyslet, protoze sice to znamena, ze budu mit nekde v cachi par desitek/stovek obrazku navic, ktery budou potreba casem uklidit ..... jo, to vypada, ze tudy cesta povede #4 to byl puvodni plan, cachovat ruzny typy obrazku ruzne dlouho, ale ted se klonim k tomu, ze to pujde poresit lip v nekterych pripadech 5.10.2013
  • kacerr : BTW: da se v komentari nejak formatovat vystup? (aspon odradkovani?) 5.10.2013
  • Anonym : ne 6.10.2013

Pro zobrazení všech 5 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.