Pengantar
Aplikasi berbasis web menjadi semakin penting untuk diakses secara offline. Ya, semua browser dapat meng-cache halaman dan resource dalam jangka waktu yang lama jika diminta untuk melakukannya, tetapi browser dapat mengeluarkan item tertentu dari cache kapan saja untuk memberi ruang bagi hal lain. HTML5 mengatasi beberapa gangguan saat offline dengan antarmuka ApplicationCache. Menggunakan antarmuka cache memberi aplikasi Anda tiga keuntungan:
- Penjelajahan offline - pengguna dapat menjelajahi seluruh situs Anda saat offline
- Kecepatan - resource langsung berasal dari disk, tidak perlu ke jaringan.
- Ketahanan - jika situs Anda mengalami "pemeliharaan" (misalnya, seseorang tidak sengaja merusak semuanya), pengguna akan mendapatkan pengalaman offline
Cache Aplikasi (atau AppCache) memungkinkan developer menentukan file mana yang harus disimpan dalam cache dan disediakan oleh browser untuk pengguna offline. Aplikasi Anda akan dimuat dan berfungsi dengan benar, meskipun pengguna menekan tombol refresh saat offline.
File manifes cache
File manifes cache adalah file teks sederhana yang mencantumkan resource yang harus di-cache browser untuk akses offline.
Mereferensikan file manifes
Untuk mengaktifkan cache aplikasi untuk aplikasi, sertakan atribut manifes pada
tag html
dokumen:
<html manifest="example.appcache">
...
</html>
Atribut manifest
harus disertakan di setiap halaman aplikasi web yang ingin Anda simpan dalam cache. Browser tidak meng-cache halaman jika tidak berisi
atribut manifest
(kecuali jika dicantumkan secara eksplisit
dalam file manifes itu sendiri. Artinya, setiap halaman yang dibuka pengguna yang
menyertakan manifest
akan ditambahkan secara implisit ke cache aplikasi.
Dengan demikian, Anda tidak perlu mencantumkan setiap halaman dalam manifes. Jika halaman mengarah ke manifes, tidak ada cara untuk mencegah halaman ini di-cache.
Anda dapat melihat URL yang dikontrol oleh cache aplikasi dengan membuka about://://appcache-internals/ di Chrome. Dari sini, Anda dapat menghapus cache dan melihat entri. Ada alat developer yang serupa di Firefox.
Atribut manifest
dapat mengarah ke URL absolut atau jalur relatif,
tetapi URL absolut harus berada di origin yang sama dengan aplikasi web.
File manifes dapat memiliki ekstensi file apa pun, tetapi harus ditayangkan
dengan jenis mime yang benar (lihat di bawah).
<html manifest="http://www.example.com/example.mf">
...
</html>
File manifes harus ditayangkan dengan jenis mime text/cache-manifest
.
Anda mungkin perlu menambahkan jenis file kustom ke server web atau konfigurasi .htaccess
.
Misalnya, untuk menayangkan jenis mime ini di Apache, tambahkan baris ini ke file konfigurasi Anda:
AddType text/cache-manifest .appcache
Atau, di file app.yaml di Google App Engine:
- url: /mystaticdir/(.*\.appcache)
static_files: mystaticdir/\1
mime_type: text/cache-manifest
upload: mystaticdir/(.*\.appcache)
Persyaratan ini dihapus dari spesifikasi beberapa waktu yang lalu, dan tidak lagi diperlukan oleh versi terbaru Chrome, Safari, dan Firefox, tetapi Anda memerlukan jenis mime untuk berfungsi di browser lama dan IE11.
Struktur file manifes
Manifes adalah file terpisah yang Anda tautkan melalui atribut manifes pada elemen html. Manifes sederhana terlihat seperti ini:
CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js
Contoh ini akan meng-cache empat file pada halaman yang menentukan file manifes ini.
Ada beberapa hal yang perlu diperhatikan:
- String
CACHE MANIFEST
adalah baris pertama dan wajib diisi. - File dapat berasal dari domain lain
- Beberapa browser menerapkan pembatasan pada jumlah kuota penyimpanan yang tersedia untuk aplikasi Anda. Misalnya, di Chrome, AppCache menggunakan kumpulan bersama penyimpanan sementara yang dapat dibagikan oleh API offline lainnya. Jika Anda menulis aplikasi untuk Chrome Web Store, penggunaan
unlimitedStorage
akan menghapus batasan tersebut. - Jika manifes itu sendiri menampilkan 404 atau 410, cache akan dihapus.
- Jika manifes atau resource yang ditentukan di dalamnya gagal didownload, seluruh proses update cache akan gagal. Browser akan terus menggunakan cache aplikasi lama jika terjadi kegagalan.
Mari kita lihat contoh yang lebih kompleks:
CACHE MANIFEST
# 2010-06-18:v2
# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
# Resources that require the user to be online.
NETWORK:
*
# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg
Baris yang diawali dengan '#' adalah baris komentar, tetapi juga dapat berfungsi untuk tujuan lain. Cache aplikasi hanya diperbarui saat file manifesnya berubah. Jadi, misalnya, jika Anda mengedit resource gambar atau mengubah fungsi JavaScript, perubahan tersebut tidak akan di-cache ulang. Anda harus mengubah file manifes itu sendiri untuk memberi tahu browser agar memuat ulang file yang di-cache.
Hindari penggunaan stempel waktu yang terus diperbarui atau string acak untuk memaksa pembaruan setiap saat. Manifes diperiksa dua kali selama update, sekali di awal dan sekali setelah semua file yang di-cache diupdate. Jika manifes telah berubah selama update, browser mungkin mengambil beberapa file dari satu versi, dan file lain dari versi lain, sehingga tidak menerapkan cache dan mencoba lagi nanti.
Meskipun cache diperbarui, browser tidak akan menggunakan file tersebut hingga halaman dimuat ulang, karena pembaruan terjadi setelah halaman dimuat dari versi cache saat ini.
Manifes dapat memiliki tiga bagian yang berbeda: CACHE
, NETWORK
, dan FALLBACK
.
CACHE:
- Ini adalah bagian default untuk entri. File yang tercantum di bawah header ini (atau segera setelah
CACHE MANIFEST
) akan di-cache secara eksplisit setelah didownload untuk pertama kalinya.NETWORK:
- File yang tercantum di bagian ini mungkin berasal dari jaringan jika tidak ada di cache. Jika tidak, jaringan tidak akan digunakan meskipun pengguna sedang online. Anda dapat memasukkan URL tertentu ke dalam daftar yang diizinkan di sini, atau cukup "", yang mengizinkan semua URL. Sebagian besar situs memerlukan "".
FALLBACK:
- Bagian opsional yang menentukan halaman penggantian jika resource tidak dapat diakses. URI pertama adalah resource, URI kedua adalah penggantian yang digunakan jika permintaan jaringan gagal atau error. Kedua URI harus berasal dari asal yang sama dengan file manifes. Anda dapat menangkap URL tertentu, tetapi juga awalan URL. "images/large/" akan menangkap kegagalan dari URL seperti "images/large/whatever/img.jpg".
Manifes berikut menentukan halaman "catch-all" (offline.html) yang akan ditampilkan saat pengguna mencoba mengakses root situs saat offline. Kebijakan ini juga mendeklarasikan bahwa semua resource lain (misalnya resource yang berada di situs jarak jauh) memerlukan koneksi internet.
CACHE MANIFEST
# 2010-06-18:v3
# Explicitly cached entries
index.html
css/style.css
# offline.html will be displayed if the user is offline
FALLBACK:
/ /offline.html
# All other resources (e.g. sites) require the user to be online.
NETWORK:
*
# Additional resources to cache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png
Memperbarui cache
Setelah offline, aplikasi tetap di-cache hingga salah satu hal berikut terjadi:
- Pengguna menghapus penyimpanan data browser untuk situs Anda.
- File manifes diubah. Catatan: mengupdate file yang tercantum dalam manifes tidak berarti browser akan meng-cache ulang resource tersebut. File manifes itu sendiri harus diubah.
Status cache
Objek window.applicationCache
adalah akses terprogram Anda ke cache aplikasi browser.
Properti status
-nya berguna untuk memeriksa status cache saat ini:
var appCache = window.applicationCache;
switch (appCache.status) {
case appCache.UNCACHED: // UNCACHED == 0
return 'UNCACHED';
break;
case appCache.IDLE: // IDLE == 1
return 'IDLE';
break;
case appCache.CHECKING: // CHECKING == 2
return 'CHECKING';
break;
case appCache.DOWNLOADING: // DOWNLOADING == 3
return 'DOWNLOADING';
break;
case appCache.UPDATEREADY: // UPDATEREADY == 4
return 'UPDATEREADY';
break;
case appCache.OBSOLETE: // OBSOLETE == 5
return 'OBSOLETE';
break;
default:
return 'UKNOWN CACHE STATUS';
break;
};
Untuk memeriksa update pada manifes secara terprogram, panggil applicationCache.update()
terlebih dahulu.
Ini akan berupaya mengupdate cache pengguna (yang mengharuskan file manifes telah diubah).
Terakhir, saat applicationCache.status
berada dalam status UPDATEREADY
,
memanggil applicationCache.swapCache()
akan menukar cache lama dengan cache baru.
var appCache = window.applicationCache;
appCache.update(); // Attempt to update the user's cache.
...
if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache(); // The fetch was successful, swap in the new cache.
}
Kabar baiknya: Anda dapat mengotomatiskan proses ini. Untuk mengupdate pengguna ke versi terbaru situs Anda, tetapkan pemroses untuk memantau peristiwa updateready
saat pemuatan halaman:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
Peristiwa AppCache
Seperti yang Anda harapkan, peristiwa tambahan ditampilkan untuk memantau status cache. Browser memicu peristiwa untuk hal-hal seperti progres download, mengupdate cache aplikasi, dan kondisi error. Cuplikan berikut menyiapkan pemroses peristiwa untuk setiap jenis peristiwa cache:
function handleCacheEvent(e) {
//...
}
function handleCacheError(e) {
alert('Error: Cache failed to update!');
};
// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);
// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);
// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);
// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);
// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);
// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);
// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);
// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);
Jika file manifes atau resource yang ditentukan di dalamnya gagal didownload, seluruh update akan gagal. Browser akan terus menggunakan cache aplikasi lama jika terjadi kegagalan tersebut.
Referensi
- Spesifikasi API ApplicationCache
- Application Cache is a douchebag - membahas masalah dan kendala terkait AppCache.