Penyimpanan berperforma tinggi untuk aplikasi Anda: Storage Foundation API

Platform web semakin menawarkan alat yang dibutuhkan developer untuk mem-build aplikasi berperforma tinggi yang telah disesuaikan untuk web. Yang paling penting, WebAssembly (Wasm) telah membuka jalan bagi aplikasi web yang cepat dan andal, sementara teknologi seperti Emscripten kini memungkinkan developer menggunakan kembali kode yang telah dicoba dan diuji di web. Untuk benar-benar memanfaatkan potensi ini, developer harus memiliki kekuatan dan fleksibilitas yang sama dalam hal penyimpanan.

Di sinilah Storage Foundation API berperan. Storage Foundation API adalah API penyimpanan baru yang cepat dan tidak memiliki opini yang membuka kasus penggunaan baru dan banyak diminta untuk web, seperti menerapkan database berperforma tinggi dan mengelola file sementara berukuran besar dengan baik. Dengan antarmuka baru ini, developer dapat "membawa penyimpanan mereka sendiri" ke web, sehingga mengurangi kesenjangan fitur antara kode khusus web dan platform.

Storage Foundation API dirancang agar menyerupai sistem file yang sangat mendasar sehingga memberikan fleksibilitas kepada developer dengan menyediakan primitif generik, sederhana, dan berperforma tinggi yang dapat mereka gunakan untuk mem-build komponen tingkat tinggi. Aplikasi dapat memanfaatkan alat terbaik untuk kebutuhannya, menemukan keseimbangan yang tepat antara kegunaan, performa, dan keandalan.

Mengapa web memerlukan API penyimpanan lain?

Platform web menawarkan sejumlah opsi penyimpanan untuk developer, yang masing-masing dibuat dengan kasus penggunaan tertentu.

  • Beberapa opsi ini jelas tidak tumpang-tindih dengan proposal ini karena hanya mengizinkan penyimpanan data dalam jumlah yang sangat kecil, seperti cookie, atau Web Storage API yang terdiri dari mekanisme sessionStorage dan localStorage.
  • Opsi lain sudah tidak digunakan lagi karena berbagai alasan seperti File and Directory Entries API atau WebSQL.
  • File System Access API memiliki platform API yang serupa, tetapi penggunaannya adalah untuk melakukan antarmuka dengan sistem file klien dan memberikan akses ke data yang mungkin berada di luar asal atau bahkan kepemilikan browser. Fokus yang berbeda ini disertai dengan pertimbangan keamanan yang lebih ketat dan biaya performa yang lebih tinggi.
  • IndexedDB API dapat digunakan sebagai backend untuk beberapa kasus penggunaan Storage Foundation API. Misalnya, Emscripten menyertakan IDBFS, sistem file persisten berbasis IndexedDB. Namun, karena IndexedDB pada dasarnya adalah penyimpanan nilai kunci, IndexedDB memiliki batasan performa yang signifikan. Selain itu, mengakses subbagian file secara langsung bahkan lebih sulit dan lebih lambat di IndexedDB.
  • Terakhir, antarmuka CacheStorage didukung secara luas dan disesuaikan untuk menyimpan data berukuran besar seperti resource aplikasi web, tetapi nilainya tidak dapat diubah.

Storage Foundation API adalah upaya untuk menutup semua kesenjangan opsi penyimpanan sebelumnya dengan memungkinkan penyimpanan file besar yang dapat diubah dan berperforma tinggi yang ditentukan dalam origin aplikasi.

Kasus penggunaan yang disarankan untuk Storage Foundation API

Contoh situs yang dapat menggunakan API ini meliputi:

  • Aplikasi produktivitas atau kreativitas yang beroperasi pada data video, audio, atau gambar dalam jumlah besar. Aplikasi tersebut dapat men-offload segmen ke disk, bukan menyimpannya di memori.
  • Aplikasi yang mengandalkan sistem file persisten yang dapat diakses dari Wasm dan memerlukan lebih banyak performa dari yang dapat dijamin IDBFS.

Apa itu Storage Foundation API?

Ada dua bagian utama API:

  • Panggilan sistem file, yang menyediakan fungsi dasar untuk berinteraksi dengan file dan jalur file.
  • Handle file, yang memberikan akses baca dan tulis ke file yang ada.

Panggilan sistem file

Storage Foundation API memperkenalkan objek baru, storageFoundation, yang berada di objek window dan menyertakan sejumlah fungsi:

  • storageFoundation.open(name): Membuka file dengan nama yang diberikan jika ada, dan jika tidak, membuat file baru. Menampilkan promise yang diselesaikan dengan file yang dibuka.
  • storageFoundation.delete(name): Menghapus file dengan nama yang diberikan. Menampilkan promise yang di-resolve saat file dihapus.
  • storageFoundation.rename(oldName, newName): Mengganti nama file dari nama lama ke nama baru secara otomatis. Menampilkan promise yang di-resolve saat file diganti namanya.
  • storageFoundation.getAll(): Menampilkan promise yang diselesaikan dengan array semua nama file yang ada.
  • storageFoundation.requestCapacity(requestedCapacity): Meminta kapasitas baru (dalam byte) untuk digunakan oleh konteks eksekusi saat ini. Menampilkan promise yang diselesaikan dengan jumlah kapasitas yang tersisa.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): Merilis jumlah byte yang ditentukan dari konteks eksekusi saat ini, dan menampilkan promise yang di-resolve dengan kapasitas yang tersisa.
  • storageFoundation.getRemainingCapacity(): Menampilkan promise yang diselesaikan dengan kapasitas yang tersedia untuk konteks eksekusi saat ini.

Handle file

Penggunaan file dilakukan melalui fungsi berikut:

  • NativeIOFile.close(): Menutup file, dan menampilkan promise yang diselesaikan saat operasi selesai.
  • NativeIOFile.flush(): Menyinkronkan (yaitu, menghapus) status file dalam memori dengan perangkat penyimpanan, dan menampilkan promise yang diselesaikan saat operasi selesai.
  • NativeIOFile.getLength(): Menampilkan promise yang diselesaikan dengan panjang file dalam byte.
  • NativeIOFile.setLength(length): Menetapkan panjang file dalam byte, dan menampilkan promise yang di-resolve saat operasi selesai. Jika panjang baru lebih kecil dari panjang saat ini, byte akan dihapus mulai dari akhir file. Jika tidak, file akan diperluas dengan byte bernilai nol.
  • NativeIOFile.read(buffer, offset): Membaca konten file pada offset yang diberikan melalui buffer yang merupakan hasil transfer buffer yang diberikan, yang kemudian dibiarkan terpisah. Menampilkan NativeIOReadResult dengan buffer yang ditransfer dan jumlah byte yang berhasil dibaca.

    NativeIOReadResult adalah objek yang terdiri dari dua entri:

    • buffer: ArrayBufferView, yang merupakan hasil transfer buffer yang diteruskan ke read(). Jenis dan panjangnya sama dengan buffer sumber.
    • readBytes: Jumlah byte yang berhasil dibaca ke dalam buffer. Jumlah ini mungkin kurang dari ukuran buffer, jika terjadi error atau jika rentang baca melampaui akhir file. Nilai ini ditetapkan ke nol jika rentang baca berada di luar akhir file.
  • NativeIOFile.write(buffer, offset): Menulis konten buffering yang diberikan ke dalam file pada offset yang diberikan. Buffer ditransfer sebelum data ditulis, sehingga buffer tidak terikat. Menampilkan NativeIOWriteResult dengan buffer yang ditransfer dan jumlah byte yang berhasil ditulis. File akan diperpanjang jika rentang tulis melebihi panjangnya.

    NativeIOWriteResult adalah objek yang terdiri dari dua entri:

    • buffer: ArrayBufferView yang merupakan hasil transfer buffer yang diteruskan ke write(). Jenis dan panjangnya sama dengan buffer sumber.
    • writtenBytes: Jumlah byte yang berhasil ditulis ke buffer. Jumlah ini mungkin lebih kecil dari ukuran buffer jika terjadi error.

Contoh lengkap

Agar konsep yang diperkenalkan di atas lebih jelas, berikut dua contoh lengkap yang memandu Anda melalui berbagai tahap dalam siklus proses file Storage Foundation.

Membuka, menulis, membaca, menutup

// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
  // Request 100 bytes of capacity for this context.
  await storageFoundation.requestCapacity(100);

  const writeBuffer = new Uint8Array([64, 65, 66]);
  // Write the buffer at offset 0. After this operation, `result.buffer`
  // contains the transferred buffer and `result.writtenBytes` is 3,
  // the number of bytes written. `writeBuffer` is left detached.
  let result = await file.write(writeBuffer, 0);

  const readBuffer = new Uint8Array(3);
  // Read at offset 1. `result.buffer` contains the transferred buffer,
  // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
  // detached.
  result = await file.read(readBuffer, 1);
  // `Uint8Array(3) [65, 66, 0]`
  console.log(result.buffer);
} finally {
  file.close();
}

Membuka, mencantumkan, menghapus

// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();

Demo

Anda dapat mencoba demo Storage Foundation API di penyematan di bawah. Membuat, mengganti nama, menulis ke dalam, dan membaca dari file, serta melihat kapasitas yang tersedia yang telah Anda minta untuk diperbarui saat Anda membuat perubahan. Anda dapat menemukan kode sumber demo di Glitch.

Keamanan dan izin

Tim Chromium mendesain dan menerapkan Storage Foundation API menggunakan prinsip inti yang ditentukan dalam Mengontrol Akses ke Fitur Platform Web yang Efisien, termasuk kontrol pengguna, transparansi, dan ergonomi.

Dengan mengikuti pola yang sama seperti API penyimpanan modern lainnya di web, akses ke Storage Foundation API terikat asal, yang berarti bahwa asal hanya dapat mengakses data yang dibuat sendiri. Hal ini juga terbatas pada konteks yang aman.

Kontrol pengguna

Kuota penyimpanan akan digunakan untuk mendistribusikan akses ke kapasitas disk dan mencegah penyalahgunaan. Memori yang ingin Anda isi harus diminta terlebih dahulu. Seperti API penyimpanan lainnya, pengguna dapat mengosongkan ruang yang digunakan oleh Storage Foundation API melalui browser mereka.

Link bermanfaat

Ucapan terima kasih

Storage Foundation API ditentukan dan diterapkan oleh Emanuel Krivoy dan Richard Stotz. Artikel ini ditinjau oleh Pete LePage dan Joe Medley.

Gambar hero melalui Markus Spiske di Unsplash.