All Projects → knadh → indexed-cache

knadh / indexed-cache

Licence: MIT license
A tiny Javsacript library for sideloading static assets on pages and caching them in the browser's IndexedDB for longer-term storage.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to indexed-cache

async
A lightweight and high performance async CSS and script loader for frontend optimization.
Stars: ✭ 17 (-69.64%)
Mutual labels:  script-loader, css-loader
Cash
HTTP response caching for Koa. Supports Redis, in-memory store, and more!
Stars: ✭ 122 (+117.86%)
Mutual labels:  caching, cdn
powered-cache
The most powerful caching and performance suite for WordPress.
Stars: ✭ 31 (-44.64%)
Mutual labels:  caching, cdn
Awesome Wp Speed Up
Plugins and resources to speed up and optimize your WordPress site.
Stars: ✭ 375 (+569.64%)
Mutual labels:  caching, cdn
node-version-assets
Version your static assets with MD5 hashes using node.js
Stars: ✭ 65 (+16.07%)
Mutual labels:  caching, cdn
simple-image-server
Host Your Own Image Server based on MongoDB, Azure Blob Storage or Google Drive
Stars: ✭ 29 (-48.21%)
Mutual labels:  cdn
EasyTask MVVM Kotlin
Todo app based on MVVM, Kotlin Coroutines, Navigation Component, Room Database, Retrofit, Data Binding
Stars: ✭ 49 (-12.5%)
Mutual labels:  caching
go-fastly-cli
CLI tool for interacting with Fastly CDN services via official REST API.
Stars: ✭ 14 (-75%)
Mutual labels:  cdn
Fetch
A resource based network abstraction based on Alamofire.
Stars: ✭ 24 (-57.14%)
Mutual labels:  caching
retrocache
This library provides an easy way for configure retrofit for use a 2 layer cache (RAM and Disk)
Stars: ✭ 35 (-37.5%)
Mutual labels:  caching
media-delivery
This collection of samples demonstrates best practices to achieve optimal video quality and performance on Intel GPUs for content delivery networks. Check out our demo, recommended command lines and quality and performance measuring tools.
Stars: ✭ 26 (-53.57%)
Mutual labels:  cdn
image-upload-app
A simple image upload application using React and Node, which explores multiple ways to upload an image including using multer as a middleware, a CDN system and converting an image to a string and storing it.
Stars: ✭ 35 (-37.5%)
Mutual labels:  cdn
cache warmup
Generiert den Cache vorab, so dass die Website bereits beim Erstaufruf performant läuft
Stars: ✭ 36 (-35.71%)
Mutual labels:  caching
plugin-intellij
jsDelivr plugin for JetBrains IntelliJ based editors
Stars: ✭ 18 (-67.86%)
Mutual labels:  cdn
micro-requirejs
⛔️ [DEPRECATED] Tiny asynchronous dependency loader, that does not require modification of dependent scripts
Stars: ✭ 22 (-60.71%)
Mutual labels:  script-loader
Johnny
Melodic Caching for Swift
Stars: ✭ 36 (-35.71%)
Mutual labels:  caching
core
An advanced and highly optimized Java library to build frameworks: it's useful for scanning class paths, generating classes at runtime, facilitating the use of reflection, scanning the filesystem, executing stringified source code and much more...
Stars: ✭ 100 (+78.57%)
Mutual labels:  caching
cdnupload
Upload your site's static files to a directory or CDN, using content-based hashing
Stars: ✭ 41 (-26.79%)
Mutual labels:  cdn
express-expeditious
flexible caching middleware for express endpoints
Stars: ✭ 42 (-25%)
Mutual labels:  caching
CloudflareSpeedTest
🌩「自选优选 IP」测试 Cloudflare CDN 延迟和速度,获取最快 IP (IPv4 / IPv6)!另外也支持其他 CDN / 网站 IP ~
Stars: ✭ 5,092 (+8992.86%)
Mutual labels:  cdn

indexed-cache.js

indexed-cache is a tiny Javascript library that "sideloads" static assets (script, link, and img tags) on webpages using the fetch() API and caches them in an IndexedDB store to eliminate the dependency on the standard browser static asset cache, and to eliminate HTTP requests on subsequent page loads. Javascript, CSS, and image assets are stored in IndexedDB as Blob()s.

For very specific scenarios only

This library is only meant to be used in very specific scenarios.

Unlike the browser's asset cache, IndexedDB is not cleared automatically, providing a longer term static file storage on the client side. The lib uses ES6 (and IndexedDB) and is only expected to work on recent versions of modern browsers. Ideally, this should have been handled with ServiceWorkers, but they don't work in mobile webviews.

Use if at least a few of these are true:

  • There are large static files (JS, CSS) that rarely change.
  • High traffic from a large number of returning users who access web pages with the same assets regularly and frequently.
  • The pages are mostly inside mobile webviews where browser cache gets evicted (OS pressure) causing the same assets to be fetched afresh over and over wasting bandwidth.
  • Bandwidth is a concern.

Features

  • Supports script, img, link tags.
  • Respects defer / async on script tags.
  • Can invalidate cached items with a TTL per tag.
  • Can invalidate cached items with a simple random hash per tag.

Gotchas

  • CORS.
  • First-paint "flash" (needs to be handled manually) as scripts and styles only load after HTML is fetched and rendered by the browser.
  • Browser compatibility.
  • Empty space or line breaks between the opening and closing <script data-src="remote.js"></script> tags will be executed as an inline script by the browser, after which the browser will not load the remote script when applied. Ensure that the opening and closing script tags have nothing between then.
  • Scripts that rely on the document.onload event will need the event to be triggered for them manually once indexed-cache loads with a document.dispatchEvent(new Event("load"));

Usage

To cache and sideload static assets:

  • Change the original src (href for CSS) attribute on tags to data-src.
  • Give tags a unique ID with data-key. The cached items are stored in the database with this key. The actual filenames of the assets can change freely, like in the case of JS build systems.
  • Load and invoke indexed-cache at the end.

Example

<!DOCTYPE html>
<html>
<head>
    <title>indexed-cache</title>
    <meta charset="utf-8" />

    <script data-key="bundle" data-src="bundle_file1234.js"></script>

    <link rel="stylesheet" type="text/css"
        data-key="style.css"
        data-src="style.css" />
</head>
<body>
    <h1>indexed-cache</h1>

    <script src="normal-non-side-loaded.js"></script>

    <!--
        Whenever the value of data-hash changes (eg: from a build system)
        or the expiry (optional) is crossed, the file is re-fetched
        and re-cached.
    //-->
    <script data-src="sideloaded.js"
        data-key="mybigsideloadedscript"
        data-hash="randomhash"
        data-expiry="2029-03-25T12:00:00-06:30">
    </script>

    <img data-src="thumb.png"
        data-key="thumb.png"
        data-hash="randomhash" />

    <!--
        Always include and invoke indexed-cache at the end, right before </body>.
        Use the unpkg CDN or download and host the script locally (dist/indexed-cache.min.js).
    !-->
    <script src="https://unpkg.com/@knadh/[email protected]/dist/indexed-cache.min.js" nomodule></script>

    <!-- Use this if you are supporting old browsers which doesn't support ES6. -->
    <!-- <script src="https://unpkg.com/@knadh/[email protected]/dist/indexed-cache.legacy.min.js" nomodule></script> -->

    <script>
        const ic = new IndexedCache();
        ic.init().then(function() {
            ic.load();
        }).catch(function(err) {
            console.log("error loading indexed-cache", err)
        })
    </script>
</body>
</html>

Load modern and legacy bundle conditionally

Here is an example on how to load modern(ESM) bundle and legacy bundle conditionally based on browser support.

    <!-- Only modern browsers understand type=module and legacy browsers will skip this script -->
    <script type="module">
        // Use ESM bundle.
        import IndexedCache from "https://unpkg.com/@knadh/[email protected]/dist/indexed-cache.esm.min.js";
        const ic = new IndexedCache();
        ic.init().then(function() {
            ic.load();
        }).catch(function(err) {
            console.log("error loading indexed-cache", err)
        })
    </script>

    <!-- This will only be executed on legacy browsers which doesn't support ES6 modules.
    Modern browsers ignore the script if its tagged `nomodule`. -->
    <script src="https://unpkg.com/@knadh/[email protected]/dist/indexed-cache.legacy.min.js" nomodule></script>
    <script nomodule>
        const ic = new IndexedCache();
        ic.init().then(function() {
            ic.load();

            // Optionally trigger `onload` if there are scripts that depend on it.
            // document.dispatchEvent(new Event("load"))
        }).catch(function(err) {
            console.log("error loading indexed-cache", err)
        })
    </script>

Optional configuration

One or more of these optional params can be passed during initialization. Default values are shown below.

new IndexedCache({
    tags: ["script", "img", "link"],
    dbName: "indexed-cache",
    storeName: "objects",

    // If this is enabled, all objects in the cache with keys not
    // found on elements on the page (data-key) will be deleted.
    // This can be problematic in scenarios where there are multiple
    // pages on the same domain that have different assets, some on
    // certain pages and some on other.
    prune: false,

    // Default expiry for an object in minutes (default 3 months).
    // Set to null for no expiry.
    expiry: 131400
}).load();
  • load() can be called with a DOM Node or NodeList. When none are given, it scans the entire DOM.
  • To manually prune all objects in the database except for a given list of keys, after await init(), call .prune([list of keys]).

Licensed under the MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].