A Primer on the Different Types of Browser Storage
In back-end development, storage is a common task. Application data is stored in a database, files are stored in an object store, and temporary data is stored in a cache... The methods of storing various data seem endless. But data storage is not limited to the backend. The front-end (browser) is also equipped with many options for storing data. We can leverage this storage to improve application performance, save user preferences, maintain application state across multiple sessions and even different computers.
This article will introduce different ways to store data in a browser. We will cover three use cases for each approach to understand its pros and cons. Finally, you will be able to decide which storage is best for your use case. Let's get started!
localStorage API
localStorage is one of the most popular storage options in the browser and is the first choice for many developers. Data is stored across sessions, never shared with the server, and is available for all pages under the same protocol and domain. Storage limit is approximately 5MB.
Surprisingly, the Google Chrome team does not recommend this option because it blocks the main thread and it cannot be accessed by the web worker and service worker. They launched an experimental KV storage as a better version, but this is just an experiment and seems to have no progress yet.
The localStorage API is available as window.localStorage and can only save UTF-16 strings. We must make sure that the data is converted to a string before saving it to localStorage. The three main functions are:
-
setItem('key', 'value')
-
getItem('key')
-
removeItem('key')
They are all synchronous, which makes them easy to use, but they block the main thread.
It is worth mentioning that localStorage has a twin brother named sessionStorage. The only difference is that the data stored in sessionStorage is only valid in the current session, but the API is the same.
Let's see its practical application. The first example demonstrates how to use localStorage to store user preferences. In this case, this is a Boolean property that is used to turn on or off the dark theme of our website.
You can select the check box and refresh the page to see if the status is saved across sessions. Check out the save and load functions to see how I convert the value to a string and how I parse it. It is important to remember that we can only store strings.
The second example loads the Pokémon name from the Poké API.
We use fetch to send a GET request and list all names in the ul element. Once the response is received, we cache it into localStorage so that our next access can be faster and even work offline. We have to convert the data to a string using JSON.stringify and read it from the cache using JSON.parse.
In this last example, I demonstrate a use case where users can browse between different Pokémon pages and the current page is saved for the next visit.
In this case, the problem with localStorage is that the state is saved locally. This behavior does not allow us to share the required pages with friends. Later, we will see how to overcome this problem.
We will also use these three examples in the next storage options. I forked Pens and changed only the related functions. The overall framework of all methods is the same.
IndexedDB API
IndexedDB is a modern storage solution in the browser. It can store a lot of structured data – even files and blobs. Like every database, IndexedDB indexes data to run queries efficiently. Using IndexedDB is more complicated. We have to create a database, table, and use transactions.
IndexedDB requires more code than localStorage. In the example, I use a native API with a Promise wrapper, but I highly recommend using a third-party library to help you. My suggestion is localForage, as it uses the same localStorage API, but implements it in a progressively enhanced way, which means if your browser supports IndexedDB, it will use it; if not, it will fall back to localStorage.
Let's write the code and go to our user preferences example!
idb is a Promise wrapper we use instead of using a low-level event-based API. They are almost the same, so don't worry. The first thing to note is that every access to the database is asynchronous, which means we won't block the main thread. This is a major advantage compared to localStorage.
We need to open the database connection so that it can be used for reading and writing throughout the application. We named the database my-db, the schema version is 1, and an update function to apply changes between different versions. This is very similar to database migration. Our database schema is simple: there is only one object store, preferences. Object storage is equivalent to SQL tables. To write to or read a database, we must use transactions. This is a tedious part of using IndexedDB. View new save and load functions in the demo.
There is no doubt that IndexedDB has a much greater overhead and a steeper learning curve than localStorage. For key-value use cases, it may make more sense to use localStorage or a third-party library that helps us increase productivity.
Application data (for example in our Pokémon example) is a strong point of IndexedDB. You can store hundreds of megabytes or even more data in this database. You can store all Pokémons in IndexedDB and make them available offline, or even indexed! This is definitely the best choice for storing application data.
I skipped the implementation of the third example because IndexedDB does not make any difference in this case compared to localStorage . Even with IndexedDB, users still cannot share selected pages with others or bookmark them for future use. None of them are the right choice for this use case.
Cookies
Using cookies is a unique storage option. It is the only storage that is also shared with the server. Cookies are sent as part of each request. This may occur when users browse pages in our application or send Ajax requests. This allows us to create a shared state between the client and the server and share the state between multiple applications in different subdomains. The other storage options described in this article cannot do this. A warning: cookies are sent with each request, which means we must keep the cookie size to maintain a reasonable request size.
The most common use of cookies is authentication, which is beyond the scope of this article. Like localStorage, cookies can only store strings. The cookie is concatenated into a semicolon-delimited string and sent in the requested cookie header. You can set many attributes for each cookie, such as expiration time, allowed domains, allowed pages, and more.
In the example, I showed how to manipulate cookies through the client, but also can change them in your server-side application.
If the server can take advantage of it in some way, then saving user preferences in cookies might be a good option. For example, in the topic use case, the server can provide relevant CSS files and reduce potential package sizes (if we are doing server-side rendering). Another use case might be to share these preferences across multiple subdomain applications without the need for a database.
Reading and writing cookies with JavaScript is not as simple as you think. To save a new cookie, you need to set the document.cookie - see the save function in the example above. I set the dark_theme cookie and added the max-age attribute to it to make sure it does not expire when the tag is closed. In addition, I added the SameSite and Secure properties. These are necessary because CodePen uses iframes to run the examples, but in most cases you don't need them. Reading cookies requires parsing the cookie string.
The cookie string looks like this:
<code>key1=value1;key2=value2;key3=value3</code>
So first, we have to split the string with a semicolon. Now we have an array of cookies of form key1=value1, so we need to find the correct element in the array. Finally, we split by equal sign and get the last element in the new array. It's a bit tedious, but once you implement the getCookie function (or copy it from my example :P), you can forget about it.
Saving application data in cookies can be a bad idea! It greatly increases request size and reduces application performance. Furthermore, the server cannot benefit from this information because it already has an stale version of this information in its database. If you use cookies, make sure they are kept small.
The pagination examples are not suitable for cookies, either, like localStorage and IndexedDB. The current page is a temporary state we want to share with others, and none of these methods can implement it.
URL Storage
The URL itself is not a storage, but it is a great way to create a shareable state. Actually, this means adding query parameters to the current URL that can be used to recreate the current state. The best examples are search queries and filters. If we search for flexbox terms on CSS-Tricks, the URL will be updated to https://www.php.cn/link/ada9e980b20ac07f6a938ef15106c224 URL, how easy is it to share a search query? Another advantage is that you can simply click the refresh button to get newer results for the query, or even bookmark it.
We can only save strings in URLs, and their maximum length is limited, so we don't have much space. We will have to keep our form smaller. No one likes long and scary URLs.
Similarly, CodePen uses an iframe to run the examples, so you can't see that the URL actually changes. Don't worry, because all the parts are there, so you can use it anywhere.
We can access the query string through window.location.search, and luckily, we can parse it using the URLSearchParams class. No more complex string parsing is required. When we want to read the current value, we can use the get function. When we want to write, we can use set. Setting the value is not enough; we also need to update the URL. This can be done using history.pushState or history.replaceState depending on the behavior we want to implement.
I do not recommend saving user preferences in URLs because we have to add this status to every URL the user visits, and we cannot guarantee it; for example, if the user clicks on a link in Google Search.
Just like cookies, we cannot save application data in URLs because we have limited space. Even if we manage to store it, the URL will be long and inconvenient to click. It might look like some kind of phishing attack.
Just like our paging example, temporary application state is best suited for URL query strings. Again, you can't see the URL changes, but every time you click on a page, the URL is updated with the ?page=x query parameter. When the web page loads, it looks for this query parameter and gets the correct page accordingly. Now we can share this URL with friends so they can enjoy our favorite Pokémon.
Cache API
The Cache API is a network-level storage. It is used to cache network requests and their responses. The Cache API fits perfectly with the service worker. The service worker can intercept each network request and use the Cache API, which can easily cache requests. The service worker can also return an existing cache entry as a network response instead of getting it from the server. By doing this, you can reduce network loading time and make your application work even when offline. Initially, it was created for service worker, but in modern browsers, the Cache API is also available in window, iframe, and worker contexts. This is a very powerful API that can greatly improve the user experience of your application.
Like IndexedDB, there are no limits on Cache API storage, and you can store hundreds of megabytes or even more data if you need it. The API is asynchronous, so it won't block your main thread. And it can be accessed through the global property caches.
To learn more about the Cache API, the Google Chrome team made a great tutorial.
Chris created a great Pen with a practical example that combines the service worker and the Cache API.
Open Demo### Attached: Browser Extensions
If you build a browser extension, there is another option to store data. I found it while developing my extension daily.dev. It can be used via chrome.storage or browser.storage (if you use Mozilla's polyfill). Make sure to request storage permissions in your inventory to access.
There are two types of storage options, local and synchronous. Local storage is self-explanatory; this means it is not shared, but is locally reserved. Sync Storage is synchronized as part of your Google account, wherever you use the same account to install the extension, this storage will be synchronized. If you ask me, this is a cool feature. Both have the same API, so it's very easy to switch if needed. It is asynchronous storage, so it does not block the main thread like localStorage. Unfortunately, I can't create a demo for this storage option because it requires a browser extension, but it's very easy to use, almost like localStorage. For more information on the exact implementation, see the Chrome documentation.
in conclusion
The browser has many options to store our data. According to the Chrome team's recommendation, our preferred storage should be IndexedDB. It is asynchronous storage, with enough space to store everything we want. LocalStorage is discouraged, but it is easier to use than IndexedDB. Cookies are a great way to share client state with servers, but are mainly used for authentication.
If you want to create a page with a shareable state (such as a search page), use the URL's query string to store this information. Finally, be sure to read about chrome.storage if you build an extension.
The above is the detailed content of A Primer on the Different Types of Browser Storage. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



If you’ve recently started working with GraphQL, or reviewed its pros and cons, you’ve no doubt heard things like “GraphQL doesn’t support caching” or

The Svelte transition API provides a way to animate components when they enter or leave the document, including custom Svelte transitions.

How much time do you spend designing the content presentation for your websites? When you write a new blog post or create a new page, are you thinking about

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

npm commands run various tasks for you, either as a one-off or a continuously running process for things like starting a server or compiling code.

The article discusses using CSS for text effects like shadows and gradients, optimizing them for performance, and enhancing user experience. It also lists resources for beginners.(159 characters)

No matter what stage you’re at as a developer, the tasks we complete—whether big or small—make a huge impact in our personal and professional growth.

I was just chatting with Eric Meyer the other day and I remembered an Eric Meyer story from my formative years. I wrote a blog post about CSS specificity, and
