Penggunaan fungsi RES.HEADER pada PHP

Setelah sebelumnya kita membahas HTTP Request dan HTTP Response, kali ini kita akan membahas mengenai HTTP Cache yang bermanfaat untuk mempercepat waktu load website atau blog.

Daftar isi:

1. HTTP Header

Untuk dapat menerapkan HTTP Cache, kita perlu mengetahui HTTP Header. Apa itu HTTP Header?

Ketika membuka website, browser akan mengirim HTTP Request ke Web Server dan Web Server menjawabnya dengan  mengirim HTTP Response, Request/Response ini  SELALU disertai dengan yang namanya HTTP Header yang berisi segala informasi terkait request/response.

Dari HTTP Header inilah browser menentukan langkah yang akan diambil, apakah mendownload file atau mengambilnya dari cache, penggunaan cache akan secara signifikan meningkatkan kecepatan akses website, karena browser tidak perlu mendownload file dari web server.

HTTP Header ini dapat dilihat menggunakan Developer Tools pada Chrome (Tekan F12) atau Web Developer Tools pada Firefox (Tekan F12) kemudian pilih bagian Network

Penggunaan fungsi RES.HEADER pada PHP
Penggunaan fungsi RES.HEADER pada PHP

2. HTTP Header Untuk Pengaturan Cache

Secara default pengaturan pada HTTP Header dilakukan oleh administrator web server (hosting) kita, namun kita juga dapat mengubah pengaturan tersebut sesuai dengan keperluan kita.

Berikut ini beberapa field Header yang penting untuk kita ketahui agar dapat melakukan pengaturan cache dengan benar.

1 Expires Header

Expires Header yang diperkenalkan pada HTTP 1.0, berfungsi untuk melakukan batasan umur cache secara spesifik berdasarkan tanggal dan waktu sesuai dengan format yang telah ditentukan (GMT), contoh: Expires: Wed, 11 Jan 2017 05:00:00 GMT, setelah melewati waktu tersebut, cache dianggap expired.

Untuk selalu mendapatkan “fresh content”, biasanya diatur agar browser selalu menganggap cache expired, untuk itu dapat dilakukan dengan memberi nilai -1 pada Expires Header.

Kelemahan dari header ini disamping besarnya kemungkinan perbedaan waktu antara browser dengan server, juga batas waktu yang ditentukan tidak fleksibel, karena strict pada tanggal dan waktu tertentu.

2 Cache-control Header

Untuk mengatasi berbagai kekurangan pengaturan cache pada HTTP 1.0, maka pada HTTP 1.1 (1997), diperkenalkan Cache-control Header. Salah satu contoh yang sering kita lihat adalah:

Cache-control: no-cache, no-store,  max-age=0, must-revalidate, public

Agar lebih jelas, mari kita bahas satu persatu:

a Cache-control: max-age=0, must-revalidate, public

max-age directive ditujukan untuk menggantikan Expires, jika Expires menggunakan tanggal dan waktu, maka max-age menggunakan satuan detik, sehingga jauh lebih fleksibel.

max-age sendiri artinya cache akan “expire” setelah sekian detik dari waktu terakhir file diakses dari server, menurut spesifikasi RFC 2616, nilai maksimal dari max-age adalah satu tahun kedepan atau 31536000 detik.

Contoh jika kita menggunakan Cache-control: max-age=3600, artinya cache akan bertahan selama 1 jam, maka jika dalam waktu satu jam terjadi request file yang sama, maka browser akan mengambilnya dari cache, jika melebihi 1 jam, maka browser akan mengirim informasi file cache ke server untuk dilakukan validasi, jika hasil validasi:

  1. File cache tersebut masih yang terbaru, maka browser akan menggunakan cache.
  2. File cache tersebut telah expired, maka browser akan mendownload file dari server kemudian menyimpannya sebagai file cache yang baru.

max-age=0 berarti bahwa cache selalu DIANGGAP expired sehingga browser HARUS melakukan validasi.

Agar compatibel baik pada HTTP 1.0 dan 1.1, maka sebaiknya Cache-control: max-age digunakan bersama dengan Expires, ketika digunakan bersamaan, maka browser harus mendahulukan max-age.

must-revalidate 

Artinya sama seperti penjelasan diatas, jika setelah satu jam, maka permintaan file yang sama harus divalidasi ke server, bukannya sama saja ya?  iya sama saja: Cache-control: max-age=3600 akan sama dengan Cache-control: max-age=3600, must-revalidate.

Directive ini berguna ketika tidak ada pendefinisian umur dari cache sehingga diserahkan pada masing-masing browser, yang terkadang ketika terjadi request, browser langsung mengambilnya dari cache, dengan adanya 

#Reformat ETAG
FileETag MTime Size

#Cache-control Header - HTTP 1.1
<IfModule mod_headers.c>
	#Cache 1 Minggu
	<FilesMatch "\.(html|htm)$">
		Header set Cache-control "max-age:604800"
	</FilesMatch>

	#Cache 3 Bulan
	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
		Header set Cache-Control "max-age=5184000"
	</FilesMatch>

	#Cache 1 Bulan
	<FilesMatch "\.(js|css)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
</IfModule>

#Expires Header - HTTP 1.0
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access"
	ExpiresByType image/gif "access plus 3 month"
	ExpiresByType image/png "access plus 3 month"
	ExpiresByType image/jpg "access plus 3 month"
	ExpiresByType image/jpeg "access plus 3 month"
	ExpiresByType video/mp4 "access plus 3 month"
	ExpiresByType video/webm "access plus 3 month"

	ExpiresByType text/html "modification plus 1 weeks"

	ExpiresByType text/css "access plus 1 month"
	ExpiresByType text/javascript "access plus 1 month"
	ExpiresByType application/javascript "access plus 1 month"
</IfModule>
0, maka browser harus melakukan validasi ke server.

public atau private

Public berarti bahwa respon dari server dapat di simpan sebagai file cache meskipun sebenarnya tidak diperbolehkan untuk disimpan sebagai file cache. public ini cocok digunakan pada file statis seperti pada gambar, css, dan javascript.

Directive public sebenarnya tidak diperlukan ketika header telah memuat informasi bahwa respon dapat di cache seperti penggunaan directive max-age.

private berarti respon (file dari server) dapat disimpan sebagai private (non-shared) cache, respon tersebut ditujukan untuk user tertentu, sehingga tidak dapat disimpan oleh intermediate cache seperti proxy server dan CDN.

private juga berarti respon ditujukan untuk END user bukan yang lain seperti proxy server tadi, disamping itu, private juga TIDAK terkait dengan security, hanya untuk menampilkan content yang pas untuk user tertentu.

Bagi browser, user tertentu ini bisa bermacam macam, bisa user OS, user browser (seperti di chrome), dll, tergantung browser mendefinisikannya seperti apa.

b Cache-control: no-cache

Perlu diperhatikan bahwa no-cache TIDAK sama dengan do-not-cache (tidak boleh disimpan sebagai cache) . no-cache artinya browser tidak boleh menggunakan informasi dari cache, melainkan harus selalu melakukan validasi ke server, sehingga no-cache ini dapat dipersamakan dengan max-age=0.

no-cache tidak terpengaruh dengan max-age, sehingga jika kita menuliskan

#Reformat ETAG
FileETag MTime Size

#Cache-control Header - HTTP 1.1
<IfModule mod_headers.c>
	#Cache 1 Minggu
	<FilesMatch "\.(html|htm)$">
		Header set Cache-control "max-age:604800"
	</FilesMatch>

	#Cache 3 Bulan
	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
		Header set Cache-Control "max-age=5184000"
	</FilesMatch>

	#Cache 1 Bulan
	<FilesMatch "\.(js|css)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
</IfModule>

#Expires Header - HTTP 1.0
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access"
	ExpiresByType image/gif "access plus 3 month"
	ExpiresByType image/png "access plus 3 month"
	ExpiresByType image/jpg "access plus 3 month"
	ExpiresByType image/jpeg "access plus 3 month"
	ExpiresByType video/mp4 "access plus 3 month"
	ExpiresByType video/webm "access plus 3 month"

	ExpiresByType text/html "modification plus 1 weeks"

	ExpiresByType text/css "access plus 1 month"
	ExpiresByType text/javascript "access plus 1 month"
	ExpiresByType application/javascript "access plus 1 month"
</IfModule>
1, maka setiap kali terjadi request maka browser akan tetap melakukan validasi ke server, tidak menunggu 3600 detik, sehingga penggunaan no-cache SEBAIKNYA tidak digabungkan dengan max-age.

  • penggunaan directive no-cache sebaiknya disertai
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    2 agar kompatibel dengan HTTP 1.0
  • no-cache tidak berlaku pada Internet Explorer, karena IE menterjemahkan no-cache dengan no-store (tidak boleh menggunakan cache) sehingga tidak ada validasi yang dilakukan, melainkan langsung mendownload content dari server. lebih lengkapnya silakan mengunjungi: Blog Internet Explorer

c Cache-control: no-store

Seperti namanya, berarti bahwa respon dari server sama sekali tidak boleh disimpan sebagai cache, meskipun hanya sekedar digunakan untuk mempermudah back button, forward button atau view source.

Dengan

#Reformat ETAG
FileETag MTime Size

#Cache-control Header - HTTP 1.1
<IfModule mod_headers.c>
	#Cache 1 Minggu
	<FilesMatch "\.(html|htm)$">
		Header set Cache-control "max-age:604800"
	</FilesMatch>

	#Cache 3 Bulan
	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
		Header set Cache-Control "max-age=5184000"
	</FilesMatch>

	#Cache 1 Bulan
	<FilesMatch "\.(js|css)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
</IfModule>

#Expires Header - HTTP 1.0
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access"
	ExpiresByType image/gif "access plus 3 month"
	ExpiresByType image/png "access plus 3 month"
	ExpiresByType image/jpg "access plus 3 month"
	ExpiresByType image/jpeg "access plus 3 month"
	ExpiresByType video/mp4 "access plus 3 month"
	ExpiresByType video/webm "access plus 3 month"

	ExpiresByType text/html "modification plus 1 weeks"

	ExpiresByType text/css "access plus 1 month"
	ExpiresByType text/javascript "access plus 1 month"
	ExpiresByType application/javascript "access plus 1 month"
</IfModule>
3, maka setiap permintaan file langsung didownload dari server, tidak ada validasi dan tidak peduli dengan umur cache, sehingga jika menuliskan
#Reformat ETAG
FileETag MTime Size

#Cache-control Header - HTTP 1.1
<IfModule mod_headers.c>
	#Cache 1 Minggu
	<FilesMatch "\.(html|htm)$">
		Header set Cache-control "max-age:604800"
	</FilesMatch>

	#Cache 3 Bulan
	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
		Header set Cache-Control "max-age=5184000"
	</FilesMatch>

	#Cache 1 Bulan
	<FilesMatch "\.(js|css)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
</IfModule>

#Expires Header - HTTP 1.0
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access"
	ExpiresByType image/gif "access plus 3 month"
	ExpiresByType image/png "access plus 3 month"
	ExpiresByType image/jpg "access plus 3 month"
	ExpiresByType image/jpeg "access plus 3 month"
	ExpiresByType video/mp4 "access plus 3 month"
	ExpiresByType video/webm "access plus 3 month"

	ExpiresByType text/html "modification plus 1 weeks"

	ExpiresByType text/css "access plus 1 month"
	ExpiresByType text/javascript "access plus 1 month"
	ExpiresByType application/javascript "access plus 1 month"
</IfModule>
4, maka no-cache akan mengalahkan lainnya.

Penggunaan fungsi RES.HEADER pada PHP
Penggunaan fungsi RES.HEADER pada PHP

d Reset Cache

PENTING diperhatikan bahwa kita harus hati-hati dalam menentukan umur dari cache, karena sekali di set, maka akan sulit merubahnya, terlebih jika telah diload oleh ribuan user, misal: setelah kita set 3 bulan (max-age: 7776000), maka untuk merubahnya kita harus merubah nama file atau mendefinisikan

#Reformat ETAG
FileETag MTime Size

#Cache-control Header - HTTP 1.1
<IfModule mod_headers.c>
	#Cache 1 Minggu
	<FilesMatch "\.(html|htm)$">
		Header set Cache-control "max-age:604800"
	</FilesMatch>

	#Cache 3 Bulan
	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
		Header set Cache-Control "max-age=5184000"
	</FilesMatch>

	#Cache 1 Bulan
	<FilesMatch "\.(js|css)$">
		Header set Cache-Control "max-age=2592000"
	</FilesMatch>
</IfModule>

#Expires Header - HTTP 1.0
<IfModule mod_expires.c>
	ExpiresActive on
	ExpiresDefault "access"
	ExpiresByType image/gif "access plus 3 month"
	ExpiresByType image/png "access plus 3 month"
	ExpiresByType image/jpg "access plus 3 month"
	ExpiresByType image/jpeg "access plus 3 month"
	ExpiresByType video/mp4 "access plus 3 month"
	ExpiresByType video/webm "access plus 3 month"

	ExpiresByType text/html "modification plus 1 weeks"

	ExpiresByType text/css "access plus 1 month"
	ExpiresByType text/javascript "access plus 1 month"
	ExpiresByType application/javascript "access plus 1 month"
</IfModule>
5 untuk beberapa saat lamanya.

3. Validasi: Last Modified dan Etags

Validasi disini berarti bahwa ketika browser mengirim informasi file cache yang akan digunakan, informasi tersebut divalidasi oleh server dengan tujuan memastikan browser mendapatkan versi terbaru dari file yang diminta.

Jika hasil validasi menunjukkan bahwa file cache sama dengan yang ada di server, maka browser dapat menggunakan file cache tersebut, jika tidak, maka browser akan mendownload file tersebut dari server.

Pada HTTP, ada dua jenis validasi yang digunakan server, yaitu Last Modified, dan Etag.

a Last Modified

Header Last Modified didefinisikan pada HTTP versi 1.0

Header ini berfungsi untuk membandingkan waktu modifikasi terakhir antara file cache dan file server, jika Last Modified date pada file server > Last modified pada file cache berarti file cache sudah expired, maka browser akan mendownload file tersebut.

Tanggal Last Modified sendiri harus menggunakan zona GMT dan format baku yang telah ditentukan contoh:

Last-Modified: Fri, 29 Apr 2016 14:20:10 GMT

Dalam prakteknya ternyata metode ini memiliki kelemahan yaitu jika waktu pada client tidak sama dengan server, maka bisa jadi sistem cache tidak berfungsi sebagaimana mestinya. Namun hingga saat ini, header ini masih menjadi andalan utama untuk melakukan validasi cache, dan seharusnya disertakan oleh server.

Secara singkat, cara kerja Header Last Modified adalah sebagai berikut:

  1. Browser melakukan permintaan halaman “A” ke web server.
  2. Web server menjawab dengan menyertakan attribute
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    6 pada HTTP Response Header
  3. Browser menyimpan halaman tersebut sebagai cache beserta informasi
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    6 nya.
  4. Ketika Browser kembali melakukan permintaan halaman “A” ke server, browser akan menyertakan attribute
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    8 pada HTTP Request header.
  5. Server kemudian melakukan validasi apakah nilai
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    8 yang dikirim browser lebih lama dari nilai 
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    
    6 pada file server, jika ya, maka Server akan mengirim HTTP Response Header dengan status 304 Not Modified, yang artinya tidak ada modifikasi pada file sehingga server tidak mengirim data file yang diminta (hanya mengirim header tidak ada body), jika tidak sama, maka proses kembali ke nomor 3.

b Etag

Selanjutnya untuk mengatasi kelemahan tersebut, pada HTTP versi 1.1 (1997) dibuat standar baru untuk memvalidasi file cache, yaitu menggunakan Header Etag yang merupakan kependekan dari Entity-Tag, contoh seperti pada gambar berikut:

Penggunaan fungsi RES.HEADER pada PHP
Penggunaan fungsi RES.HEADER pada PHP

Etag ini memiliki format

<IfModule mod_headers.c>
	Header set Cache-control "no-cache, max-age:0"
	Header set Pragma "no-cache"
	Header set Expires "-1"
</IfModule>
1, dimana:

  1. INode - Kode unik server yang biasanya digenerate oleh sistem operasi.
  2. MTime – Modified Time – waktu modifikasi terakhir dari file.
  3. Size - Ukuran file dalam byte.

untuk penjelasan lebih lengkap dapat dilihat pada halaman

Adapun cara kerja Etag ini mirip dengan Last Modified yaitu:

  1. Browser melakukan permintaan file ke web server.
  2. Web server menjawab dengan menyertakan atribut
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    2.
  3. Browser menyimpan file tersebut sebagai cache beserta informasi
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    2 nya.
  4. Browser kembali melakukan permintaan file yang sama ke server, namun kali ini dengan menyertakan attribute
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    4 (yang berisi nilai Etag) pada HTTP Request Header.
  5. Server kemudian melakukan validasi apakah nilai 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    4 sama dengan nilai
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    2 pada file server, jika sama, maka Server akan mengirim HTTP Response Header dengan status 304-Not Modified, yang artinya file masih sama dan tidak ada data yang dikirim oleh server (hanya header saja tidak diikuti body), jika Etag tidak sama, maka proses kembali ke nomor 3.

Mengaktifkan Etag

Jika HTTP Response Header belum menyertakan Etag, kita dapat mengaktifkannya dengan cara:

  1. Jika Anda Administrator, pastikan module 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    7 aktif, buka file
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    8 yang berada pada  
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    9 kemudian cari (Ctrl+F) mod_headers, kemudian hilangkan tanda pagar (#) di awal baris. Jika berada pada server hosting, dapat langsung mencoba step 2, jika tidak berhasil, coba hubungi admin web server.
  2. Tambahkan
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    0 beserta parameter yang diinginkan, misal 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    1 pada file
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    2, jika ingin menggunakan semua parameter maka dapat menuliskan 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    3 atau cukup ditulis dengan 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    4

c Last Modified atau Etag?

Berdasarkan RFC Standard, Etag dan Last Modified digunakan secara bersama sama, sehingga jika salah satu terpenuhi, misal: Etag tidak sama tapi Last Modified sama maka validasi bernilai

<IfModule mod_headers.c>
	Header set Cache-control "no-store"
	Header set Pragma "no-cache"
	Header set Expires "-1"
</IfModule>
5

Etag ini memiliki kelemahan yaitu jika file ditempatkan di server berbeda, maka nilai Etag akan berbeda (INode), namun kelemahan ini dapat diatasi dengan membuat Etag dengan format: MTime-Size.

4. HTTP Cache – Working Code

Pengaturan untuk HTTP Cache dapat dilakukan dengan berbagai cara, namun paling pas dilakukan melalui konfigurasi server, pada apache, pengaturan dapat dilakukan melalui file .htaccess, adapun kode yang dapat digunakan adalah:

  1. Meningkatkan SPEED website. Untuk meningkatkan kecepatan akses website/blog selalu gunakan cache, dengan demikian akan meminimalisir jumlah dan ukuran request, berikut ini contoh yang saya gunakan:
    #Reformat ETAG
    FileETag MTime Size
    
    #Cache-control Header - HTTP 1.1
    <IfModule mod_headers.c>
    	#Cache 1 Minggu
    	<FilesMatch "\.(html|htm)$">
    		Header set Cache-control "max-age:604800"
    	</FilesMatch>
    
    	#Cache 3 Bulan
    	<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    		Header set Cache-Control "max-age=5184000"
    	</FilesMatch>
    
    	#Cache 1 Bulan
    	<FilesMatch "\.(js|css)$">
    		Header set Cache-Control "max-age=2592000"
    	</FilesMatch>
    </IfModule>
    
    #Expires Header - HTTP 1.0
    <IfModule mod_expires.c>
    	ExpiresActive on
    	ExpiresDefault "access"
    	ExpiresByType image/gif "access plus 3 month"
    	ExpiresByType image/png "access plus 3 month"
    	ExpiresByType image/jpg "access plus 3 month"
    	ExpiresByType image/jpeg "access plus 3 month"
    	ExpiresByType video/mp4 "access plus 3 month"
    	ExpiresByType video/webm "access plus 3 month"
    
    	ExpiresByType text/html "modification plus 1 weeks"
    
    	ExpiresByType text/css "access plus 1 month"
    	ExpiresByType text/javascript "access plus 1 month"
    	ExpiresByType application/javascript "access plus 1 month"
    </IfModule>
    

    Pada Expires Header, batas waktu yang dapat digunakan adalah seconds, minutes, hours, days, weeks, months, dan years, selain itu kita juga dapat menggunakan acuan waktu

    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    6 atau
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    7 untuk lebih jelasnya dapat mengunjungi halaman mod_expires – Apache HTTP Server

    Seperti sebelumnya telah disampaikan, selalu gunakan max-age bersama dengan Expires header agar kompatibel di semua versi HTTP yang ada di server kita.

    Aktifkan Module

    Untuk dapat menggunakan module expires, pastikan module 

    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    8 telah aktif, sedangkan untuk dapat menggunakan module header, pastikan module
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    9  telah aktif.

    Jika anda administrator, untuk mengaktifkannya buka file

    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
    8 yang berada di dalam direktori Expires: Wed, 11 Jan 2017 05:00:00 GMT1, cari baris yang mengandung kata
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    8 dan 
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    9, kemudian hilangkan tanda pagar di depannya, restart apache.

    Penggunaan fungsi RES.HEADER pada PHP
    Penggunaan fungsi RES.HEADER pada PHP

    Jika berada pada server hosting, bisa langsung mencoba script diatas, jika tidak berhasil, silakan hubungi administrator hosting anda.

  2. Lainnya 1: Jika ingin menggunakan cache dan ingin memastikan content yang ada selalu yang terbaru (selalu ada request ke web server namun hanya HTTP header saja – sekitar 49 byte), terutama untuk file php, htm, dan html, maka dapat menggunakan kode berikut:
    <IfModule mod_headers.c>
    	Header set Cache-control "no-cache, max-age:0"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>
    
  3. Lainnya 2: Jika ingin setiap request selalu mengambil file dari server, maka kita cegah browser untuk menyimpan dan menggunakan cache, gunakan kode berikut:
    <IfModule mod_headers.c>
    	Header set Cache-control "no-store"
    	Header set Pragma "no-cache"
    	Header set Expires "-1"
    </IfModule>

Selanjutnya pastikan bahwa cache telah berjalan, buka developer tools (tekan F12) kemudian pilih bagian network. Berikut ini contoh dengan menggunakan browser chrome:

Penggunaan fungsi RES.HEADER pada PHP
Penggunaan fungsi RES.HEADER pada PHP

Demikian pembahasan mengenai HTTP Cache semoga bermanfaat.

Subscibe Now

Suka dengan artikel di Jagowebdev.com? jangan sampai ketinggalan, segera join ke milis kami untuk update informasi terbaru dari Jagowebdev.com

Komitmen Kami: Kami senantiasa menghargai privasi Anda dan tidak akan membagikan identitas Anda ke pihak manapun.

agusph says:

Varvy sepertinya ngambil dari google page speed insight juga mas, dan saya tidak terlalu menghiraukan score disana.

Yang menjadi perhatian adalah SPEED web nya mas, karena google sendiri tidak menggunakan score grade tapi SPEED. Untuk tes kecepatan website bisa menggunakan tool seperti pada pingdom.com.

Perbaiki error yang bisa kita handle, jangan terlalu pusing dengan yang diluar jangkauan kita seperti script dari cdn, facebook, google-analytics, dll yang tidak mungkin kita mampu mengatur cache nya