From 65b2315702c40cb2ceb8effcb14a1a43547accdb Mon Sep 17 00:00:00 2001 From: pubkey <8926560+pubkey@users.noreply.github.com> Date: Fri, 10 May 2024 21:30:54 +0200 Subject: [PATCH 01/15] ADD article --- .../localstorage-indexeddb-cookies-opfs-sqlite-wasm.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md diff --git a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md new file mode 100644 index 00000000000..eb672740240 --- /dev/null +++ b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md @@ -0,0 +1,10 @@ +# Localstorage vs. IndexedDB vs. Cookies vs. OPFS vs. Wasm-SQLite + + + +### Things this does not talk about +WebSQL +session storage. +Web Storage API + + From 501718a64eb3e137e43fbc25c1b6eba2f00dfd83 Mon Sep 17 00:00:00 2001 From: pubkey <8926560+pubkey@users.noreply.github.com> Date: Tue, 14 May 2024 01:20:53 +0200 Subject: [PATCH 02/15] ADD content --- ...rage-indexeddb-cookies-opfs-sqlite-wasm.md | 92 ++++++++++++++++++- docs-src/docs/articles/localstorage.md | 2 +- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md index eb672740240..2d9207aa28b 100644 --- a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md +++ b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md @@ -1,10 +1,100 @@ # Localstorage vs. IndexedDB vs. Cookies vs. OPFS vs. Wasm-SQLite +So it is 2024 and you want to build your this awesome Web Application. To make you app fast and even work [offline](../offline-first.md), you want to store all data on the client device and run operations there, instead of awaiting requests to a backend server. +But there is a problem: -### Things this does not talk about +> Browser are slow and weren't made to run huge database operations. + +Or are they? Over the last few years, a lot of features have been added to JavaScript. New storage APIs such as OPFS and new features like the BroadcastChannel are here to let us reach the limits of JavaScript performance. + +In this article we have look at all previous and new technologies to store and query data in a browser. We will run performance tests and combine many performance hacks to find out how fast we can write and read a **huge amount of data** in a Web App. + + +## What is localstorage +## What is indexeddb +## What are cookies +## What is OPFS +## What is wasm sqlite + +## Things this does not talk about WebSQL session storage. Web Storage API + + +## Feature comparison + +### Multitab support + +A big difference when building a Web App compared to Electron or React-Native, is that the user will open and close the app in multiple browser tabs at the same time. Therefore you have not only one JavaScript process running, but many of them can exist and might have to share state changes between each other to not show outdated data to the user. + +Not all storage APIs support a way to automatically share write events between tabs. Only localstorage has the [storage-event](./localstorage.md#localstorage-vs-indexeddb) which can be used to observe changes. + +```js +// localStorage can observe changes with the storage event. +// This feature is missing in IndexedDB and others +addEventListener("storage", (event) => {}); +``` + +To workaround this problem, there are two solutions: +The first option is to use the [BroadcastChannel API](https://github.com/pubkey/broadcast-channel) which can send messages across browser tabs. So whenever you do a write to the storage, you also send a notification to other tabs to inform them about these changes. + +The other solution is to use the [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker) and do all writes inside of the worker. All browser tabs can then subscribe to messages from that SharedWorker and know about changes. + +### Indexing +- IndexedDB does not support boolean indexes +#### iterable indexes +#### secondary indexes +### Storing complex JSON documents + +### Worker Support + +- Localstorage and Cookies [cannot be used in WebWorker or SharedWorker](https://stackoverflow.com/questions/6179159/accessing-localstorage-from-a-webworker). + +- OPFS with the fast `createSyncAccessHandle` method can **only** [be used in a WebWorker](../rx-storage-opfs.md#opfs-limitations). + +## Performance Comparison + +Now that we know about the basics of the various storage solutions, lets compare their performance. As mentioned above, we not only want to store a few documents, instead lets store **many** of them and run **heavy and complex queries**. + +TODO add github repo url with performance tests. + +### Running many small operations + +One aspect of performance is the latency. The time to run a small database operation, either read or write. +Depending on your use case, it might be relevant that many small operations run fast, like when you have a browser game and want to store the game's state. + +### Running single big operations + +### Initial page load +How fast does the first query load when there are many documents +stored already. + + + + +## Lets reach the limits of client side storage performance with RxDB +- indexeddb optimizations +- compression with keycompression +- spliting work load with WebWorker +- sharding +- memory mapped/synced stuff + +- Store metadata in localstorage +- fix initial page load for new tabs with the SharedWorker (only chrome can spawn WebWorkers inside of a SharedWorker) + +- is OPFS faster then indexeddb? + + + +## Read further + +TODO fix links +- Check out the [hackernews discussion of this article](https://news.ycombinator.com/item?id=39745993) +- Shared/Like my [announcement tweet](https://twitter.com/rxdbjs/status/1769507055298064818) + +- Learn how to use RxDB with the [RxDB Quickstart](../quickstart.md) +- Check out the [RxDB github repo](https://github.com/pubkey/rxdb) and leave a star ⭐ diff --git a/docs-src/docs/articles/localstorage.md b/docs-src/docs/articles/localstorage.md index aa5552020f3..b5910a73b7b 100644 --- a/docs-src/docs/articles/localstorage.md +++ b/docs-src/docs/articles/localstorage.md @@ -92,7 +92,7 @@ While **localStorage** serves as a reliable storage solution for simpler data ne complex queries can pose a challenge with IndexedDB, and while its performance is acceptable, IndexedDB can be [too slow](../slow-indexeddb.md) for some use cases. ```js -// localStorage can observe chanes with the storage event. +// localStorage can observe changes with the storage event. // This feature is missing in IndexedDB addEventListener("storage", (event) => {}); ``` From 5386bbd8ccb7bf8fa0683ee9c4bdc7a655fbcaf8 Mon Sep 17 00:00:00 2001 From: pubkey <8926560+pubkey@users.noreply.github.com> Date: Wed, 15 May 2024 14:23:44 +0200 Subject: [PATCH 03/15] chore --- ...alstorage-indexeddb-cookies-opfs-sqlite-wasm.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md index 6946baf747a..162d0ccab5a 100644 --- a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md +++ b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md @@ -47,17 +47,27 @@ The first option is to use the [BroadcastChannel API](https://github.com/pubkey/ The other solution is to use the [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker) and do all writes inside of the worker. All browser tabs can then subscribe to messages from that SharedWorker and know about changes. ### Indexing -- IndexedDB does not support boolean indexes + +The big difference between a database and storing data in a plain file, is that a database is writing data in a format that allows running operations over indexes to facilitate fast queries. + #### iterable indexes +- IndexedDB does not support boolean indexes + #### secondary indexes +- Only IndexedDB and SQLite WASM has secondary indexes + + ### Storing complex JSON documents +- IndexedDB can store JSON natively +- SQLite can [store JSON](https://www.sqlite.org/json1.html) from version 3.38.0 (2022-02-22). + ### Worker Support - Localstorage and Cookies [cannot be used in WebWorker or SharedWorker](https://stackoverflow.com/questions/6179159/accessing-localstorage-from-a-webworker). - OPFS with the fast `createSyncAccessHandle` method can **only** [be used in a WebWorker](../rx-storage-opfs.md#opfs-limitations). - + 2 ## Performance Comparison Now that we know about the basics of the various storage solutions, lets compare their performance. As mentioned above, we not only want to store a few documents, instead lets store **many** of them and run **heavy and complex queries**. From c1647ea1ce965ef58625bf3ead77feb5cbcefcc0 Mon Sep 17 00:00:00 2001 From: pubkey <8926560+pubkey@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:39:34 +0200 Subject: [PATCH 04/15] CHORE content --- ...rage-indexeddb-cookies-opfs-sqlite-wasm.md | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md index 162d0ccab5a..ff47dbe2b20 100644 --- a/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md +++ b/docs-src/docs/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.md @@ -1,22 +1,39 @@ # Localstorage vs. IndexedDB vs. Cookies vs. OPFS vs. Wasm-SQLite -So it is 2024 and you want to build your this awesome Web Application. To make you app fast and even work [offline](../offline-first.md), you want to store all data on the client device and run operations there, instead of awaiting requests to a backend server. -But there is a problem: +Welcome to 2024, a time when building powerful, responsive web applications has never been more exciting. As developers, we constantly seek ways to make our apps faster and more efficient, and one crucial aspect of this is data storage. To ensure our apps not only perform well but also work seamlessly [offline](../offline-first.md), we aim to store data on the client device, minimizing the need to interact with backend servers. -> Browser are slow and weren't made to run huge database operations. +However, a common belief persists: -Or are they? Over the last few years, a lot of features have been added to JavaScript. New storage APIs such as OPFS and new features like the BroadcastChannel are here to let us reach the limits of JavaScript performance. +> Browser are slow and weren't designed to run extensive database operations. -In this article we have look at all previous and new technologies to store and query data in a browser. We will run performance tests and combine many performance hacks to find out how fast we can write and read a **huge amount of data** in a Web App. +Is this really the case? Over recent years, JavaScript has evolved significantly. New storage APIs like the Origin Private File System (OPFS) and new features like the BroadcastChannel have pushed the boundaries of what JavaScript can achieve in terms of performance. +In this article, we will delve into the various technologies available for storing and querying data in a browser. We'll explore traditional methods like Cookies, LocalStorage and IndexedDB, and newer solutions such as OPFS and Wasm-SQLite. Through performance tests we aim to uncover how fast we can write and read **a huge amount of data** in a web application with the various methods. And because you are reading this in the [RxDB](/) docs, we will utilize multiple RxDB plugins that contain innovative hacks to reach the performance limits of a browser in terms of database operations. + +