Pretraga...

Keširanje i kompresovanje – Optimizacija sajta [03]

Nakon članaka o merenju brzine sajta i otkrivanju “usporenja”, i članka o eliminisanju višestrukih redirekcija, tema ovog članka je keširanje sajta i kompresovanje sadržaja. Objasniću ukratko šta je to keširanje i zbog čega je važno. Praćeno istim za kompresiju. Na kraju, objasniću kako sam ovo implementirao na ovom (relativno malom i jednostavnom) WordPress sajtu. Poseban članak bavi se WordPress plaginovima, u smislu brzine i pouzdanosti.

Sadržaj:

  1. Keširanje
    1.1. Šta je to keširanje?
    1.2. Keširanje veb-sajtova
  2. Politika keširanja veb-sajta
    2.1. Validnost i validacija keša
    2.2. Primena keširanja
  3. Implementacija keširanja
    3.1. Implementacija keširanja na serveru
    3.2. Implementacija keširanja prilikom dizajna web-sajta
    3.3. Implementacija keša preko CDN servisa
  4. Kompresija sadržaja – zip i gZip
  5. Minimizacija
    5.1. Spajanje (kombinovanje) CSS i JavaScript fajlova
  6. Šta sam uradio na BikeGremlin sajtu?
  7. Testiranje
  8. Izvori

1. Keširanje

1.1. Šta je to keširanje?

Keširanje – generalno

Pogledajte koliko je sati u momentu kada ovo čitate. Spremni? Koji je glavni grad Sjedinjenih Američkih Država? Najverovatnije ste upravo iskoristili nešto najsličnije keširanju – velika većina ljudi napamet zna ime glavnog grada ove države. Pri tome je korišteno keširanje nalik kešu RAM memorije (pleonazam, prim. aut.). Za razliku od ovoga, pokušajte odgovoriti na pitanje: koji je glavni grad Rodezije? Većina će morati koristiti Google (i verovatno naučiti nešto i iz istorije i iz geografije tražeći odgovor).

Ova dva primera najbolje objašnjavaju koliko je keširanje važno za povećanje brzine. Kada jednom izguglate podatke o Rodeziji, oni ostaju u Vašem “RAM-u” i u buduće ćete brzo odgovarati na pitanje o glavnom gradu Rodezije – dok ga ne zaboravite, što je analogno brisanju keš memorije.

Keširanje dinamičkih resursa

Još jedan primer, važan za razumevanje. Zamislite da se pripremate za kviz o glavnim gradovima. Najverovatnije ćete napraviti spisak svih država sa njihovim glavnim gradovima – složenu po kojem god redu je Vama najlakše da sve zapamtite (učitate u svoj “RAM”). Pravljenje spiska traži puno više vremena od čitanja gotovog spiska. Ovo bi bio primer nečega što ću nazvati “keširanje procesa (servera)” . Jednom napravljen spisak ostaje zapisan i nema više potrebe da se svaki put iznova pravi isti spisak. Pri tome, spisak je poput keša na disku, dok je pamćenje svih glavnih gradova napamet poput keša u RAM-u.

Rok trajanja keša

Koliko je sati? Da li Ste ponovo pogledali na sat, ili se oslonili na podatak utvrđen na početku čitanja ovog poglavlja? Ovo demonstrira još jednu bitnu karakteristiku keširanja: što se nešto brže i češće menja, to je keširanje toga manje zahvalno (i manje praktično/smisleno) za izvesti.

Politika keširanja

U prethodnim primerima objašnjena je važnost keširanja rezultata procesa i nekih podataka, kao i besmisao keširanja podatka o tačnom vremenu. Podešavanje ovoga: šta će se keširati, gde će se taj keš čuvati i koliko često će se taj keš osvežavati, zove se “politika keširanja”. Kada se politika keširanja osmisli i implementira pravilno, sajt će raditi brzo i bez grešaka. Podesite ovo pogrešno i dobićete sajt koji pokazuje tačno vreme samo jednom u svaka 24 časa. 🙂  Politika keširanja je detaljnije opisana u poglavlju 2.

Postoji puno različitih vrsta (i tehnika) keširanja, ali to prevazilazi okvir ovog teksta. Ovde ću se držati keširanja u smislu ubrzanja rada veb-sajtova.

1.2. Keširanje veb-sajtova

Kada korisnik dođe na sajt, ako sajt nije “praistorijskog” tipa sa statičkim html stranicama, server obično prvo izvrši neki kod kako bi generisao stranicu koju korisnik treba da vidi (generisanje sadržaja, padajućih menija i slično). Ovo traži neko vreme. Onda korisnik treba sve to da downloaduje (“prevuče” preko Interneta do svog računara). Ovo isto traži neko vreme. Konačno, često postoje skripte (“programi”) koji se nakon downloada moraju izvršiti na računaru posetioca. Tek nakon svega ovoga stranica može biti prikazana i “raditi” kako treba na ekranu posetioca sajta.

Postoje dve osnovne vrste “keširanja sajtova” – na strani servera i na strani korisnika (veb-pregledača, tj. browsera).

Keširanje u veb-pregledaču

Veb-pregledači (“browseri”) imaju mogućnost da jednom dobijene podatke snime i sačuvaju neko vreme. Slika koja se nalazi u pozadini ovog sajta (lep fixie bicikl 🙂 ) je, na primer, nešto što Vaš pregledač snimi prilikom prve posete sajtu i čuva za svaki sledeći put, učitavajući je iz keša (osim ako u opcijama pregledača ne podesite da briše/ne koristi keš).

Takođe, pregledač će sačuvati u svom kešu i java skripte koje treba da izvrši kako bi stranica izgledala kao što izgleda. Padajući meniji na vrhu stranice koju sada čitate su primer toga. Pored ovoga, moguće je skriptama “reći” da se izvršavaju nešto kasnije, nakon što je stranica sa osnovnim izgledom već prikazana. Ovo omogućava posetiocu da vidi i počne čitati stranicu, pre nego ona dobije svoju punu funkcionalnost (“učitavanje u pozadini”, ili “asinhrone skripte“).

Svi ovi elementi se keširaju lokalno, na hard disku/SSD-u posetioca. Svaki posetilac će ih downloadovati barem jednom, pri prvoj poseti sajtu, a kasnije (duže vreme) više neće morati. Postoji više različitih načina na koje se pregledaču korisnika saopštava šta može keširati i koliko dugo je taj keš “svež”.

Na primer: dobro je da korisnik ne mora svaki put učitavati BikeGremlin logo i pozadinsku sliku, ali ako se prijavi i napiše komentar na ovoj stranici, nema smisla prikazati mu potom staru, keširanu verziju stranice, u kojoj nije “osvežen” novo dodati (njegov/njen) komentar. Ako se na host-serveru ne definišu instrukcije za pregledače, oni će po svojoj podrazumevanoj politici sami keširati određeni sadržaj. Ovo može praviti probleme u funkcionalnosti sajta, pa je zato bolje pružiti ispravne instrukcije pregledačima u vezi keširanja.

Proksi keširanje

Proksi (eng. Proxy) se najlakše može objasniti kao zajednički keš veb-pregledača, koji obično provajderi Interneta, ili veće kompanije, postavljaju (najčešće uz firewall) za svoje korisnike. Prosto rečeno, ako korisnik poseti bikegremlin.com, njegove “komšije” (svi koji koriste isti proksi) će većinu sadržaja moći da skinu direktno sa proksija, bez potrebe da se povezuju na host-server sajta.

Keširanje na host-serveru

Na serveru se podešavaju instrukcije (politika keširanja) koje server daje ostalima. Dakle instrukcije pregledačima u vezi keša koji se kod njih čuva, zatim instrukcije proksijima i tako dalje. Ovaj deo je veoma bitan, što sam pokušao objasniti iznad.

Uz sve ovo, veoma važan deo je podešavanje keširanja na samom serveru. Koje stranice, ili rezultate procesa (obično izvršenja PHP koda) server čuva na svojim hard diskovima (ili SSD-ovima), u svom RAM-u i koliko dugo.

Na primer, dok čitate ovaj tekst, ne postoji nikakva bikegremlin.com/keširanje.html stranica sa ovim člankom, već host-server izvršavanjem PHP koda i čitanjem podataka iz baze prikazuje sve ovo moje lupetanje. 🙂  Pošto se post napiše jednom, uz retke izmene, idealan je kandidat za keširanje i čuvanje rezultata izvršenog koda sa gotovim prikazom stranice.

Gateway keš (CDN)

Geteway keš je vrsta “obrnutog proksi” keša. Dok proksi keš posetiocu štedi odlazak do servera, gateway keš serveru štedi obradu zahteva posetioca koji mu se obraća. Tj. služi da smanji opterećenje servera tako što će, kada klijenit (posetioci) traže materijal koji je keširan u gateway kešu, dati materijal iz gateway keša, bez opterećivanja samog servera.

CDN (eng. Content Delivery Network) servisi pružaju ovu vrstu usluge (često uz dodatne usluge zaštite i optimizacije). Glavna prednost je što sadržaj drže u više kopija na više različitih geografskih lokacija, usmeravajući posetioce na gateway keš lokaciju sa kojom posetioci imaju najbržu/najbolju konekciju. Tako da je moguće postaviti server u Novom Sadu, na primer, a posetiocima koji žive sa pogrešne strane Atlantika pružiti podatke sa gateway keširane kopije koja se nalazi u Los Anđelesu (uz pomoć CDN servisa).


2. Politika keširanja veb-sajta

Za implementaciju keširanja je na prvom mestu važno napraviti dobru politiku keširanja. Dobri kandidati za keširanje su:

  • Sadržaj koji se retko menja, a i prikaz zastarelog sadržaja nije problematičan – pozadinska slika na primer i slično.
  • Sadržaj koji se retko menja, ali je potrebno vršiti kontrolu je li keširana verzija još uvek aktuelna (ne sme biti poslužen bajat) – komentari i postovi na primer.

2.1. Validnost i validacija keša

Rok trajanja

Keš se može definisati sa određenim datumom (Expires), ili rokom trajanja (Max-Age). U tom slučaju, pregledač posetioca će proveriti kod sebe taj podatak i ako je rok još uvek važeći, neće ni proveravati sa host-serverom je li došlo do nekih promena. Ovo je super-brzo rešenje, ali može biti nezgodno ako se dese promene koje su važne za “iskustvo korisnika”. Na primer, ako promenim sliku pozadine sajta tako da pokazuje kupon za popust u biciklističkoj prodavnici. Stari posetioci bi pri ponovnim posetama i dalje videli staru, keširanu, sliku fixie bicikla. Ove situacije rešive su jedino promenom imena fajla. Ako sliku sa izmenjenom pozadinom snimim kao “pozadina2.jpg”, umesto stare “pozadina1.jpg”, pregledač će dobiti informaciju da treba da učita pozadina2.jpg. Pošto ta slika ranije nije postojala na sajtu, svakako je nije ni mogao imati u kešu, pa će svakako učitati i prikazati novu sliku.

To je glavna mana oba načina implementacije keširanja sa rokom trajanja (Expires i Max-Age).

Mana postavljanja datuma trajanja (Expires) je što se mora ažurirati – inače će, ako je taj datum prošao, a podatak nije izmenjen, stranica biti praktično ne-keširana, tj. uvek će se preuzimati “sveža” verzija sa servera. U tom smislu je rok trajanja (Max-Age) zahvalnija opcija. Osim ako postoji dobar razlog za baš određeni datum/vreme roka trajanja.

Izmene

Drugi način, koji je nešto sporiji (traži uvek obraćanje serveru), ali sigurniji po pitanju ažurnosti, je podešavanje keša tako da se proverava je li keširana verzija uvek aktuelna. Ovo znači čuvanje keša sa podatkom o “poslednjoj izmeni” (Last-Modified), ili ceduljicom (ETag) koja je jedinstvena za svaki fajl i menja se kad god se izvorni sadržaj promeni. Pregledač proverava sa serverom da li se Last-Modified/ETag koji ima u kešu razlikuje od onog na serveru – ako ne, nema potrebe za skidanjem nove verzije fajla. Ovi tagovi su po pravilu puno manji od celog fajla za koji su vezani, pa se brže razmene i uporede, ali ipak traže neko vreme za razmenu. To je glavna mana ovog metoda keširanja.

Javno/privatno

Uz gore navedene načine provere ažurnosti keša, moguće je definisati i keš kao:

  • Javni (Cache-control: public) – keš se može čuvati na javnim proksijima i sl.
  • Privatni (Cache-control: private) – keš se čuva samo u veb-pregledaču pojedinačnog posetioca. Dobro rešenje za sadržaj koji se razlikuje u zavisnosti od konkretnog (ulogovanog) posetioca.
  • Bez keširanja (Cache-control: no-cache) – keš se nigde ne čuva – za podatke koji se stalno menjaju, a ime im ostaje isto.

2.2. Primena keširanja

Poglavlje 2.1. objašnjava zašto je važno pri definisanju politike keširanja pravilno odrediti koji metod je bolji za koje fajlove/objekte. Pošto veb-sajtovi često imaju različite vrste sadržaja, optimalan izbor metoda keširanja se može razlikovati u zavisnosti od sadržaja, tj. neće biti isti ca celokupan sajt. Ovo je važna stavka.

Pri definisanju politike keširanja, mogu se odrediti posebna pravila koja važe:

  • za ceo sajt – slike, na primer. Može se definisati isto pravilo za keširanje slika koje važi za ceo sajt, tj. za sve slike na sajtu.
  • za određene stranice – određena vrsta stranica, ili grupa objekata, po ključu direktorijuma, URL adrese i sl. može imati definisana svoja pravila keširanja. Na primer postovi, čiji sadržaj se povremeno ažurira, mogu imati rok trajanja od nedelju-dve dana (Expires, Max-Age), dok komentari moraju imati ažuriranje keša vezano za to da li je bilo izmena ili ne (Last-Modified, ETag).
  • za pojedinačnu stranicu/objekat – recimo, ako se stranice na sajtu definišu sa rokom trajanja keša od dve nedelje, ali stranica sa radnim vremenom, ili cenovnikom mora ipak ostati uvek ažurna.


3. Implementacija keširanja

3.1. Implementacija keširanja na serveru

Kada se politika keširanja definiše kako treba, ostaje da se implementira (i testira, što je veoma važno). Ovo se prvo radi na samom host-serveru sajta. Tehnika se razlikuje u zavisnosti od vrste servera (Apache, Microsoft itd.) i objašnjenje toga prevazilazi obim ovog teksta.

3.2. Implementacija keširanja prilikom dizajna web-sajta

Pri samom dizajnu sajta, takođe treba voditi računa o keširanju. Neka generalna pravila:

  • Konzistentno postavljanje URL-ova – isti sadržaj treba uvek da bude sa istom URL adresom. Osim ako stoji baš dobar, poseban razlog da ne bude tako. Nema smisla praviti dve stranice o_autoru.html i o-autoru.html (ako sadrže isti sadržaj), pa linkovati nekad jednu nekad drugu gde god je potrebno na sajtu. Jedna je dovoljna. Isto važi i za druge objekte i slike. Stavite ih sve u istu biblioteku (direktorijum) i linkujte ka njima ka tom istom mestu kada god su potrebni.
  • Ako se slika ili fajl koji se downloaduje sa servera promene, promeniti njihovo ime – datum ili broj verzije u imenu fajla su dobra ideja.
  • Ne menjati fajlove bez preke potrebe. Ako se, na primer, sajt ažurira preko FTP-a, uploadovati samo izmenjene fajlove/sadržaj. U suprotnom će “na silu” biti promenjen datum poslednje izmene fajlova koji nisu menjani, pa će se isti verovatno ponovo učitavati, iako su bili keširani.
  • Koristite cookije samo kada su neophodni. Teški su za keširati i generalno su potrebni samo na dinamičkim stranama.

Kontrola keša se može definisati u HTML zaglavljima stranica. Ovo je zgodno za kontrolu keširanja pojedinačnih stranica, inače se može podesiti na nivou servera.

Skripte koje za isti ulaz daju iste izlazne podatke su takođe odličan kandidat za keširanje i to treba u njima implementirati. Ovo se može izvesti smeštanjem skripti u tekstualne fajlove, kako bi server mogao “videti” kada se promene i osvežiti keš, ili ubacivanjem Max-Age podatka, pa čak i pravljenjem validatora izmene (If-Modified-Since, koji će poslati odgovor 304 Not Modified kada je to tačno).

Posebna kategorija, vezana za WordPress sajtove je korištenje plag-inova za keširanje. Oni često vrše potrebne izmene u zaglavljima i .htaccess fajlu direktorijuma u kojem je instaliran WordPress. Praktično automatski rešavajući keširanje (neki traže/dozvoljavaju više ručnog podešavanja, neki ne).

U posebnom članku detaljno sam objasnio podešavanje LiteSpeed Cache plagina za keširanje WordPress sajtova, koji je po meni ubedljivo najbolji.

3.3. Implementacija keša preko CDN servisa

CDN servisi će uglavnom poštovati podešavanja keširanja iz zaglavlja za kontrolu keša sa host-servera. Mogu omogućiti izmenu dužine trajanja keša, najčešće produžavanjem, preko pravila definisanih u kontrolnom panelu CDN-a. U idealnom slučaju, CDN treba da sprovodi (dobro) podešenu politiku keširanja host-servera, samo je prenoseći na više različitih geografskih lokacija, lakše i brže dostupnih posetiocima iz različitih delova sveta.

Postavljanje dužeg perioda validnosti starog keša na CDN-u (nego na host-serveru) znači da politika keširanja na serveru nije optimalno podešena (inače ne bi bilo potrebe “produžavati” keš na CDN-u). Slično se može reći za kraći rok važenja keša na CDN-u (u odnosu na host-server).


4. Kompresija sadržaja – zip i gZip

Slike i video snimci su uglavnom već kompresovani, ali tekstualni sadržaj ostavlja dosta prostora za “zipovanje”. Server se može konfigurisati tako da svim pregledačima koji to mogu prihvatiti šalje kompresovan sadržaj. Ovo ima smisla uraditi sa svim tekstualnim sadržajem: text, html, javascript, css, xml fajlovi i slično. Tj. za sve fajlove koji su čisto tekstualni.

Kompresovani fajlovi su puno manji i skidaju se puno brže. Sam proces kompresije (na strani servera) i dekompresije (na strani klijenta) opterećuje procesor, ali moderni procesori su brzi i lako se nose sa tim, dok je brzina Internet konekcije još uvek često usko grlo. Tako da kad se sve sabere i oduzme, kompresija doprinosi ukupnoj brzini sajta, u velikoj većini slučajeva.

Konkretne komande za podešavanje zavise od vrste servera, time se ovde neću baviti. U poglavlju Izvori postoje linkovi na kojima je to detaljnije objašnjeno.


5. Minimizacija

Sav kod koji se piše na sajtu (html, css, JavaScript itd.) je napisan tako da bude razumljiv i ljudima koji ga pišu/čitaju/edituju. To izgleda otprilike ovako:

<style type='text/css'>
			#gallery-2 {
				margin: auto;
			}
			#gallery-2 .gallery-item {
				float: left;
				margin-top: 10px;
				text-align: center;
				width: 50%;
			}
			#gallery-2 img {
				border: 2px solid #cfcfcf;
			}
			#gallery-2 .gallery-caption {
				margin-left: 0;
			}
			/* see gallery_shortcode() in wp-includes/media.php */
		</style>

Ipak, računaru uopšte nisu potrebni ni novi redovi, komentari, niti uvlačenje (ovo poslednje ne vole ni neki programeri, ali to je posebna priča 🙂 ).

Minimizacija je izbacivanje svih (računaru) nepotrebnih viškova, kako bi se dobila što kraća verzija koda koji radi ono za šta je pisan – i posluživanje ovako minimiziranih verzija veb-pregledačima. Minimizovana verzija koda iznad izgleda ovako:

<style type=’text/css’>#gallery-2{margin: auto;}#gallery-2 .gallery-item{float: left;margin-top: 10px;text-align: center;width: 50%;}#gallery-2 img {border: 2px solid #cfcfcf;}#gallery-2 .gallery-caption {margin-left: 0;}</style>

Računaru je sve isto, sve jasno. Minimizovan kod je manji, samim tim se brže šalje i downloaduje. Minimizacija se može izvesti nakon pisanja svih skripti (menjanjem izvornih fajlova na serveru), ili posluživanjem minimiziranih, keširanih kopija veb-pregledačima, uz ostavljanje izvornog koda kakav jeste (za lakše kasnije dorade i ispravke).

Opet, samom implementacijom se neću baviti u ovom postu.

5.1. Spajanje (kombinovanje) CSS i JavaScript fajlova

Preuzimanje svakog fajla sa servera je poseban zahtev serveru. Takođe, svaki fajl ima neku vrstu zaglavlja, čija veličina ne zavisi bitno od veličine samog fajla. Zbog toga, ako posetilac sajta prevlači puno malih fajlova da bi video stranicu, to dodatno usporava rad sajta. Bolje je spojiti ih u jedan veći fajl (i povrh toga još i kompresovati).

Slika ispod pokazuje neke od .css i .js fajlova jednog WordPress sajta. Za bolju optimizaciju, sadržaj više različitih .css fajlova može se ubaciti unutar jednog. Isto važi i za .js fajlove.

.css i .js fajlovi jedne teme WordPress sajta
.css i .js fajlovi jedne teme WordPress sajta

Ovo spajanje može se uraditi prilikom pisanja WordPress teme, ili naknadnim optimizovanjem, pomoću nekog plagina za keširanje/optimizaciju. Naravno, nije moguće sve objediniti. Zavisi od samog sajta (ili korištene WordPress teme i ostalih plaginova). Ja koristim LiteSpeed plagin za keširanje i optimizaciju, čiji developeri su napravili dosta lepu stranicu koja objašnjava rešavanje problema sa kombinovanjem .css i .js fajlova.


6. Šta sam uradio na BikeGremlin sajtu?

S obzirom da je BikeGremlin trenutno na relativno sporom, shared hosting serveru i da planiram uskoro preseljenje, nisam se puno upuštao u podešavanje samog servera.

Iskoristio sam servis Cloudflare, njegov besplatni paket, koji nudi neke osnovne funkcije CDN-a i zaštite sajta od napada. Cloudflare takođe vrši minimizaciju koda, tako da je taj deo, za sada, rešen preko njega. Uz to, zaštita od nedozvoljenog prikaza slika sa sajta na drugim sajtovima (korištenjem mog servera) je aktivirana (“Hotlink protection” ).

Keširanje zajedno sa kompresijom, sam rešio pomoću Hyper Cache Extended plug-ina. O različitim plug-inovima za keširanje WordPress sajtova ću napisati poseban članak. Za sada ću samo reći da HCE plug-in radi najbolje sa relativno jednostavnim sajtom na relativno sporom serveru, kao što je sada kod mene slučaj. Ovaj plug-in podešava politiku keširanja tako da sve stranice dobijaju željeni Max-Age period, kako bi pregledač posetioca čuvao kopiju u željenom periodu, ali uz dodatak Last-Modified polja, tako da se, u slučaju izmene posta, pregledač dobija tu informaciju i samo tada skida osveženu verziju stranice.

EDIT 2019:
Poseban članak koji objašnjava plaginove za keširanje i aktuelnu verziju plagina koji koristim: Keširanje WordPress sajta.


7. Testiranje

Testiranje je najbolje uraditi u lokalu, sa svim proverama pre uploadovanja na “živi” sajt. Menjati jedno po jedno podešavanje, kako bi se eventualni problemi mogli uočiti i znati tačno “gde je zapelo”.

Alat GTmetrix daje podatke i o kvalitetu keširanja, barem osnovne (postoji li, za koje objekte ne postoji, ili keš ima kratak rok trajanja i slično). Ovako izgleda rezultat GTmetrix testa tipične stranice na bikegremlin.com:

Test using GTmetrix tool
Test pomoću GTmetrix alata

Rezultati Google analitike iz prve dve nedelje u maju i prve dve nedelje u septembru (nakon sređivanja redirekcija, implementacije keširanja i pretresanja plug-inova – o ovom poslednjem pisaću u posebnom postu):

May (first) and September (second) page load time stats from Google Analytics
Statistika vremena učitavanja stranice za maj (prvo) i septembar (drugo) iz Google Analytics alata

– Relja Gonzales Novović


8. Izvori

2 misli o “Keširanje i kompresovanje – Optimizacija sajta [03]”

Komentari su zatvoreni.


Molim Vas da koristite BikeGremlin.net forum za sva pitanja i komentare.

Ako ste primetili neku grešku u članku, ili informacije koje nedostaju - molim Vas da mi na to skrenete pažnju komentarom na BikeGremlin forumu.
Na forumu možete pisati anonimno (stavite bilo koje ime/nadimak pri registraciji), ali mislim da je dobro da sve dopune i ispravke članaka budu javno dokumentovane (čak i ako njihov autor izabere da ostane anoniman).

TOC
Skip to content