- Dec 2023
-
pythonspeed.com pythonspeed.com
-
Rebuild your images regularly
If you want both the benefits of caching, and to get security updates within a reasonable amount of time, you will need two build processes:
- The normal image build process that happens whenever you release new code.
- Once a week, or every night, rebuild your Docker image from scratch using
docker build --pull --no-cache
to ensure you have security updates.
-
Disabling caching
That suggests that sometimes you’re going to want to bypass the caching. You can do so by passing two arguments to docker build:
- --pull: This pulls the latest version of the base Docker image, instead of using the locally cached one.
- --no-cache: This ensures all additional layers in the Dockerfile get rebuilt from scratch, instead of relying on the layer cache.
If you add those arguments to docker build you will be ensured that the new image has the latest (system-level) packages and security updates.
-
As long as you’re relying on caching, you’ll still get the old, insecure packages distributed in your images
-
caching means no updates
-
caching can lead to insecure images.
-
- Nov 2023
-
en.itpedia.nl en.itpedia.nl
-
All about Caching: Strategies, Challenges and Optimization
Caching is a crucial technique in modern #webservices, helping to improve #performance, reduce #latency, and minimize the load on servers and networks. The principle is simple: storing copies of data in a more quickly accessible location to enable faster access to that data. But, as with many technologies, the devil is in the details. In fact, creating a good configuration is very difficult and the smallest mistake can be very detrimental to the performance of our #website.
caching
-
- Sep 2023
- Aug 2023
-
joyofcode.xyz joyofcode.xyz
Tags
Annotators
URL
-
-
datatracker.ietf.org datatracker.ietf.org
-
datatracker.ietf.org datatracker.ietf.org
Tags
- http:header=cdn-cache-control:no-cache
- http
- http:header=cdn-cache-control:must-revalidate
- http:header=cdn-cache-control:private
- http:header=cdn-cache-control:max-age
- http:header=cdn-cache-control:no-store
- cdn
- urn:ietf:rfc:9213
- http:header=cdn-cache-control
- wikipedia:en=HTTP_caching
- caching
Annotators
URL
-
-
datatracker.ietf.org datatracker.ietf.org
Tags
- http:code=206
- http:header=cache-control:max-age
- http:header=cache-control:no-transform
- http:header=cache-control:only-if-cached
- http:header=cache-control:must-revalidate
- http:header=if-range
- http:header=cache-control:min-fresh
- http:header=cache-control:s-maxage
- http:header=cache-control:proxy-revalidate
- http:header=if-match
- http:header=cache-control:no-store
- http:header=cache-control:must-understand
- http:header=cache-control:public
- http:header=cache-control:no-cache
- caching
- http:header=if-none-match
- http:header=cache-control:max-stale
- http
- http:header=cache-control:private
- urn:ietf:rfc:9111
- http:header=pragma
- http:header=age
- http:header=cache-control
- http:header=if-modified-since
- http:header=warning
- http:code=304
- wikipedia:en=HTTP_caching
- http:header=if-unmodified-since
- http:header=expires
Annotators
URL
-
- Jul 2023
-
github.com github.com
Tags
Annotators
URL
-
- Jun 2023
-
developer.chrome.com developer.chrome.com
-
Tags
Annotators
URL
-
-
gist.github.com gist.github.com
-
```js 'use strict';
// --------------------------------------------------------------------
class Cache extends Map { constructor(key) { super() this._key = key this.load() }
set(k, v) { if (!this.has(k) || v !== this.get(k)) { super.set(k, v) this.save() } }
delete(k) { if (super.has(k)) { super.delete(k) this.save() } }
clear() { if (super.size() > 0) { super.clear() this.save() } }
json() { let obj = Object.create(null)
for (let k of this.keys()) { obj[k] = this.get(k) } return obj
}
save() { const data = this.json() this._save(this._key, data) this.dump({ data, event: 'SAVE' }) }
load(s) { const data = this._load(this._key)
if (typeof data !== 'object') { return } super.clear() for (let k of Object.keys(data)) { super.set(k, data[k]) } this.dump({ data, event: 'LOAD' })
}
_save(key, data) {} _load(key) {}
edit() { let res = window.prompt('Edit cached package URLs', JSON.stringify(this.json(), null, 2))
if (res !== null) { try { const data = JSON.parse(res) super.clear() for (let k of Object.keys(data)) { super.set(k, data[k]) } this.save() } catch (ex) { console.warn('Failed to update cache data: %s %o', ex.toString(), ex) } }
}
toString() { return
${this.constructor.name}<${this._key}>: keys=[ ${this.keys().sort().join(', ')} ]
}dump({ data, event }) { console.group(
${this.constructor.name}<${this._key}>: ${event || 'STATE'}:
) console.info(JSON.stringify(data || this.json(), null, 2)) console.groupEnd() } }// --------------------------------------------------------------------
class GMCache extends Cache { _save(key, data) { GM_setValue(key, JSON.stringify(data || {})) }
_load(key) { return JSON.parse(GM_getValue(key) || '{}') } }
// --------------------------------------------------------------------
class StorageCache extends Cache { constructor(key, session) { super(key)
this.storage = session ? window.sessionStorage : window.localStorage this.load()
}
_save(key, data) { this.storage.setItem(key, JSON.stringify(data || {})) }
_load(key) { if (this.storage) { return JSON.parse(this.storage.getItem(key) || '{}') } } }
// --------------------------------------------------------------------
let c = new StorageCache('test-data') // c.set('jshint-summary', { name: 'jshint-summary', homepage: 'https://github.com/spiralx/jshint-summary' }) ```
-
-
learn.microsoft.com learn.microsoft.com
-
www.akamai.com www.akamai.com
-
-
blog.cloudflare.com blog.cloudflare.com
-
Tags
Annotators
URL
-
- May 2023
-
developer.mozilla.org developer.mozilla.orgIf-Match1
-
stackoverflow.com stackoverflow.com
-
stackoverflow.com stackoverflow.com
-
github.com github.com
-
Figured it out. Cache-Control header is required.
js const headers = { 'Cache-Control': 'public, max-age=604800' }; const request = new Request('https://foobar.com/') const cacheResponse = new Response('bar',{ headers }) const cache = caches.default await cache.put(request, cacheResponse) const response = await cache.match(request);
-
- Mar 2023
-
developer.mozilla.org developer.mozilla.org
-
developer.mozilla.org developer.mozilla.org
-
www.mnot.net www.mnot.net
-
-
simonhearne.com simonhearne.com
-
developers.cloudflare.com developers.cloudflare.com
-
<table><tbody><tr><th colspan="4" rowspan="1">Status</th><th colspan="4" rowspan="1">Description</th></tr><tr><td colspan="5" rowspan="1">HIT</td><td colspan="5" rowspan="1">The resource was found in Cloudflare’s cache.</td></tr><tr><td colspan="5" rowspan="1">MISS</td><td colspan="5" rowspan="1">The resource was not found in Cloudflare’s cache and was served from the origin web server.</td></tr><tr><td colspan="5" rowspan="1">NONE/UNKNOWN</td><td colspan="5" rowspan="1">Cloudflare generated a response that denotes the asset is not eligible for caching. This may have happened because:
- A Worker generated a response without sending any subrequests. In this case, the response did not come from cache, so the cache status will be
none/unknown
.- A Worker request made a subrequest (
fetch
). In this case, the subrequest will be logged with a cache status, while the main request will be logged withnone/unknown
status (the main request did not hit cache, since Workers sits in front of cache).- A Firewall rule was triggered to block a request. The response will come from the edge network before it hits cache. Since there is no cache status, Cloudflare will log as
none/unknown
.- A redirect page rule caused the edge network to respond with a redirect to another asset/URL. This redirect response happens before the request reaches cache, so the cache status is
</td></tr><tr><td colspan="5" rowspan="1">EXPIRED</td><td colspan="5" rowspan="1">The resource was found in Cloudflare’s cache but was expired and served from the origin web server.</td></tr><tr><td colspan="5" rowspan="1">STALE</td><td colspan="5" rowspan="1">The resource was served from Cloudflare’s cache but was expired. Cloudflare could not contact the origin to retrieve an updated resource.</td></tr><tr><td colspan="5" rowspan="1">BYPASS</td><td colspan="5" rowspan="1">The origin server instructed Cloudflare to bypass cache via a Cache-Control header set tonone/unknown
.no-cache
,private
, ormax-age=0
even though Cloudflare originally preferred to cache the asset. BYPASS is returned when enabling Origin Cache-Control. Cloudflare also sets BYPASS when your origin web server sends cookies in the response header.</td></tr><tr><td colspan="5" rowspan="1">REVALIDATED</td><td colspan="5" rowspan="1">The resource is served from Cloudflare’s cache but is stale. The resource was revalidated by either anIf-Modified-Since
header or anIf-None-Match header
.</td></tr><tr><td colspan="5" rowspan="1">UPDATING</td><td colspan="5" rowspan="1">The resource was served from Cloudflare’s cache and was expired, but the origin web server is updating the resource. UPDATING is typically only seen for very popular cached resources.</td></tr><tr><td colspan="5" rowspan="1">DYNAMIC</td><td colspan="5" rowspan="1">Cloudflare does not consider the asset eligible to cache and your Cloudflare settings do not explicitly instruct Cloudflare to cache the asset. Instead, the asset was requested from the origin web server. Use Page Rules to implement custom caching options.</td></tr></tbody></table> - A Worker generated a response without sending any subrequests. In this case, the response did not come from cache, so the cache status will be
-
-
www.builder.io www.builder.io
Tags
Annotators
URL
-
-
blog.bitsrc.io blog.bitsrc.io
-
blog.cloudflare.com blog.cloudflare.com
-
www.cloudflare.com www.cloudflare.com
-
alistapart.com alistapart.com
-
www.youtube.com www.youtube.com
Tags
Annotators
URL
-
-
www.youtube.com www.youtube.com
Tags
Annotators
URL
-
-
stackoverflow.com stackoverflow.com
-
donavon.com donavon.com
Tags
Annotators
URL
-
-
sergiodxa.com sergiodxa.com
-
Send the 304 Not Modified response
```js import etag from "etag"; import { renderToString } from "react-dom/server"; import type { EntryContext, HandleDataRequestFunction } from "remix"; import { RemixServer } from "remix";
export default function handleRequest( request: Request, status: number, headers: Headers, remixContext: EntryContext ) { let markup = renderToString( <RemixServer context={remixContext} url={request.url} /> );
headers.set("Content-Type", "text/html"); headers.set("ETag", etag(markup));
// check if the
If-None-Match
header matches the ETag if (request.headers.get("If-None-Match") === headers.get("ETag")) { // and send an empty Response with status 304 and the headers. return new Response("", { status: 304, headers }); }return new Response("<!DOCTYPE html>" + markup, { status, headers }); }
export let handleDataRequest: HandleDataRequestFunction = async ( response: Response, { request } ) => { let body = await response.text();
if (request.method.toLowerCase() === "get") { response.headers.set("etag", etag(body)); // As with document requests, check the
If-None-Match
header // and compare it with the Etag, if they match, send the empty 304 Response if (request.headers.get("If-None-Match") === response.headers.get("ETag")) { return new Response("", { status: 304, headers: response.headers }); } }return response; }; ```
-
All Together
```js import etag from "etag"; import { renderToString } from "react-dom/server"; import type { EntryContext, HandleDataRequestFunction } from "remix"; import { RemixServer } from "remix";
export default function handleRequest( request: Request, status: number, headers: Headers, remixContext: EntryContext ) { let markup = renderToString( <RemixServer context={remixContext} url={request.url} /> );
headers.set("Content-Type", "text/html"); headers.set("ETag", etag(markup));
return new Response("<!DOCTYPE html>" + markup, { status, headers }); }
export let handleDataRequest: HandleDataRequestFunction = async ( response: Response ) => { let body = await response.text(); response.headers.set("etag", etag(body)); return response; }; ```
-
Using ETags for document requests
```js import etag from "etag"; import { renderToString } from "react-dom/server"; import type { EntryContext } from "remix"; import { RemixServer } from "remix";
export default function handleRequest( request: Request, status: number, headers: Headers, remixContext: EntryContext ) { let markup = renderToString( <RemixServer context={remixContext} url={request.url} /> );
headers.set("Content-Type", "text/html"); // add the Etag header using the markup as value headers.set("ETag", etag(markup));
return new Response("<!DOCTYPE html>" + markup, { status, headers }); } ```
-
Using ETags for data requests
```js import etag from "etag"; import type { HandleDataRequestFunction } from "remix";
export let handleDataRequest: HandleDataRequestFunction = async ( response: Response, { request } ) => { let body = await response.text(); // parse the response body as text
// only add the ETag for GET requests if (request.method.toLowerCase() === "get") { response.headers.set("etag", etag(body)); // and use it to create the ETag }
return response; // return the response }; ```
-
-
-
www.npmjs.com www.npmjs.com
-
```js import { renderToString } from "react-dom/server"; import { RemixServer } from "remix"; import type { EntryContext } from "remix"; import { etag } from 'remix-etag';
export default function handleRequest( request: Request, responseStatusCode: number, responseHeaders: Headers, remixContext: EntryContext ) { const markup = renderToString( <RemixServer context={remixContext} url={request.url} /> );
responseHeaders.set("Content-Type", "text/html");
const response = new Response("<!DOCTYPE html>" + markup, { status: responseStatusCode, headers: responseHeaders, }); return etag({ request, response }); } ```
Tags
Annotators
URL
-
-
support.cloudflare.com support.cloudflare.com
-
developer.mozilla.org developer.mozilla.orgETag1
-
tkdodo.eu tkdodo.eu
Tags
Annotators
URL
-
-
www.smashingmagazine.com www.smashingmagazine.com
-
www.keycdn.com www.keycdn.com
Tags
Annotators
URL
-
-
www.youtube.com www.youtube.com
-
frederik-braun.com frederik-braun.com
-
developer.mozilla.org developer.mozilla.org
-
www.w3.org www.w3.org
Tags
Annotators
URL
-
-
Tags
Annotators
URL
-
-
developers.cloudflare.com developers.cloudflare.com
-
developer.mozilla.org developer.mozilla.org
-
gist.github.com gist.github.com
-
You'll notice that for the app/routes/jokes/$jokeId.tsx route in addition to Cache-Control we've also set Vary header to Cookie. This is because we're returning something that's specific to the user who is logged in. So we want the cache to associated to that particular Cookie value and not shared with different users, so the browser and CDN will not deliver the cached value if the cookie is different from the cached response's cookie.
-
-
-
Tags
Annotators
URL
-
-
www.youtube.com www.youtube.com
-
- Feb 2023
-
mxstbr.com mxstbr.com
Tags
Annotators
URL
-
-
suspense.vercel.app suspense.vercel.app
-
suspense-npm.vercel.app suspense-npm.vercel.app
- Jan 2023
-
blog.cloudflare.com blog.cloudflare.com
- Dec 2022
-
blog.archive.org blog.archive.org
-
blog.cloudflare.com blog.cloudflare.com
- Aug 2022
-
stackoverflow.com stackoverflow.com
-
Using git remote set-head has the advantage of updating a cached answer, which you can then use for some set period. A direct query with git ls-remote has the advantage of getting a fresh answer and being fairly robust. The git remote show method seems like a compromise between these two that has most of their disadvantages with few of their advantages, so that's the one I would avoid.)
-
-
codeontime.com codeontime.com
-
-
-
stackoverflow.com stackoverflow.com
- Jul 2022
-
tanstack.com tanstack.com
- Apr 2022
-
developers.cloudflare.com developers.cloudflare.com
-
blog.opstree.com blog.opstree.com
-
developers.cloudflare.com developers.cloudflare.com
-
Cache using fetch
Determine how to cache a resource by setting TTLs, custom cache keys, and cache headers in a fetch request.
```js async function handleRequest(request) { const url = new URL(request.url);
// Only use the path for the cache key, removing query strings // and always store using HTTPS, for example, https://www.example.com/file-uri-here const someCustomKey =
https://${url.hostname}${url.pathname}
;let response = await fetch(request, { cf: { // Always cache this fetch regardless of content type // for a max of 5 seconds before revalidating the resource cacheTtl: 5, cacheEverything: true, //Enterprise only feature, see Cache API for other plans cacheKey: someCustomKey, }, }); // Reconstruct the Response object to make its headers mutable. response = new Response(response.body, response);
// Set cache control headers to cache on browser for 25 minutes response.headers.set('Cache-Control', 'max-age=1500'); return response; }
addEventListener('fetch', event => { return event.respondWith(handleRequest(event.request)); }); ```
Caching HTML resources
Setting the cache level to Cache Everything will override the default cacheability of the asset. For time-to-live (TTL), Cloudflare will still rely on headers set by the origin.
js // Force Cloudflare to cache an asset fetch(event.request, { cf: { cacheEverything: true } });
-
- Mar 2022
-
marmelab.com marmelab.com
-
www.fastly.com www.fastly.com
- Feb 2022
-
web.dev web.dev
-
- Jan 2022
- Dec 2021
-
spectrum.chat spectrum.chat
-
Currently starting to read https://github.com/substack/stream-handbook, maybe I just need a deeper understanding of streams
According to @xander76 on Twitter the code would have to use a Transform stream, which looks something like this:
let cacheEntry = ""; renderToNodeStream(<Frontend/>) .pipe(new Transform({ transform(chunk, enc, callback) { cacheEntry += chunk; callback(chunk); }, flush(callback) { redis.set(req.path, cacheEntry); } }) .pipe(res);
-
-
developers.google.com developers.google.com
- Jul 2021
-
github.com github.com
-
To cache the result of calling use guix
Tags
Annotators
URL
-
- Jun 2021
-
kit.svelte.dev kit.svelte.dev
-
When fetch runs on the server, the resulting response will be serialized and inlined into the rendered HTML. This allows the subsequent client-side load to access identical data immediately without an additional network request.
-
- Feb 2021
-
www.reddit.com www.reddit.com
-
Space: Suppose we had infinite memory, then cache all the data; but we don't so we have to decide what to cache that is meaningful to have the cache implemented (is a ??K cache size enough for your use case? Should you add more?) - It's the balance with the resources available.
-
Time: Suppose all your data was immutable, then cache all the data indefinitely. But this isn't always to case so you have to figure out what works for the given scenario (A person's mailing address doesn't change often, but their GPS position does).
-
You have to guess when the data is not likely to be needed in memory. It can't be too short that the cache is useless, and too long that you'll get a memory leak.
-
-
www.computers.wtf www.computers.wtf
-
There’s only one hard thing in Computer Science: human communication. The most complex part of cache invalidation is figuring out what the heck people mean with the word cache. Once you get that sorted out, the rest is not that complicated; the tools are out there, and they’re pretty good.
-
Cache and caching are some of the most ambiguous words in the IT world, and that’s because we can have multiple types of caching working in parallel and affecting content independently.
-
- Jan 2021
-
redfin.engineering redfin.engineering
-
v1 tabs tightly couple to their v1 Cache; v2 tabs tightly couple to their v2 Cache. This tight coupling makes them “application caches.” The app must be completely shut down (all tabs closed) in order to upgrade atomically to the newest cache of code.
-
-
redfin.engineering redfin.engineering
-
Service Workers are the hot new thing in web APIs. They’re designed to be like the HTML5 Application Cache, but without being objectionable.
-
-
alistapart.com alistapart.com
- Dec 2020
-
github.com github.com
-
I have a feeling that this functionality is scuppered by #415 - since my browser caches the page for 10 minutes, meaning that the page is never hit and thus the preload is never run, regardless of whether session has been changed or not.
Tags
Annotators
URL
-
-
-
I'd instinctively associate a this.cache() inside preload with the preloaded data only -- meaning no matter what crazy thing I did inside preload, the returned data would be cached locally, where local means either the client or server.
-
-
-
Say I have a separate API server that provides content for a Sapper route. I could just query that API in my route's preload function, but if the content changes rarely, I don't want to incur that cost for every page load and would much rather cache responses from the API on the Sapper side.
-
// app/middleware/cache.js,`use`ed in app/server.js import LRU from 'lru-cache'; const _cache = new LRU({ max: 500, maxAge: 1000 * 60 * 60 }); async function cache(req, res, next) { req.cache = _cache; next(); }
-
-
jamstack.org jamstack.org
-
Popular architectures deal with heavy traffic loads by adding logic to cache popular views and resources.
-
- Nov 2020
-
-
Service Workers are also helpful for offline caching and performance. You can write code to cache your application shell to work offline and populate its content using JavaScript.
-
- Oct 2020
-
-
use an intercepting proxy server with a built-in cache
-
Take responsibility for your outgoing network traffic If you install software that interacts with other sites over the network, you should be aware how it works and what kind of traffic it generates. If it has the potential to make thousands of requests to other sites, make sure it uses an HTTP cache to prevent inflicting abuse on other sites.
-
-
-
-
It is not appropriate to use these document types for live content. These are made available only for download, to support local use in development, evaluation, and validation tools. Using these versions directly from the W3C server could cause automatic blockage, preventing them from loading. If it is necessary to use schemata in content, follow guidelines to avoid excessive DTD traffic. For instance, use caching proxies to avoid fetching the schema each time it is used, or ensure software uses a local cache, such as with XML catalogs.
-
- Aug 2020
-
github.com github.com
-
Expected behavior Response should include Vary: Accept to show that the response differs due to content negotiation. Actual behavior All responses are considered equal to the user agent, leading to caching issues. See these bugs:
Tags
Annotators
URL
-
- Jun 2020
-
medium.com medium.com
-
Caching is dangerous if not done correctly. For example, making decisions based on outdated data as if it was current.
-
Don’t apply caching if the process is expected to react to changes during the caching period. i.e. Don’t cache when mixing reads and writes.
-
An example candidate for caching might be a nightly billing task which aggregates billing data for the past month. That kind of task is likely not expecting last minute updates while it runs. It assumes that the state of the world remains constant while processing.
-
-
stackoverflow.com stackoverflow.com
- May 2020
-
intercom.help intercom.help
-
Caching is a very complex set of systems that can easily cause conflicts between scripts. Make sure to always clear all your caches once a plugin, theme and the WordPress core has been updated.
-
-
stackoverflow.com stackoverflow.com
-
If you update your pages and push to github, people revisiting the pages who have already got cached copies will not get the new pages without actually cleaning their browser cache. How can a script running in a page determine that it is stale and force an update?
-
-
You can use the window.applicationCache.swapCache() to update the cached version of your website without the need for manually reloading the page. This is a code example from HTML5 Rocks explaining how to update users to the newest version of your site:
-
-
stackoverflow.com stackoverflow.com
-
for me it was because the browser use cached data(old styles) so i opend other brwser
-
-
webapps.stackexchange.com webapps.stackexchange.com
-
www.addictivetips.com www.addictivetips.com
-
The context menu will have three options; Normal Reload, Hard Reload, and Empty Cache and Hard Reload. The third option is what you’re looking for. Click ‘Empty Cache and Hard Reload’ to clear the cache for a particular website.
-
-
superuser.com superuser.com
-
After opening up the developer tools (usually by pressing F12) Click + Hold on the "Reload Page" button. From the popup list, choose "Empty Cache and Hard Reload".
-
- Mar 2020
-
-
to be fully compliant, this leads to having to check for consent on every request server-side, which is not cacheable/scalable at all. Maybe having caches vary on consent-related properties of a request would solve that, but not without an explosion in cache storage requirements (if nothing else) and nightmares when it comes to cache invalidation(s).
-
- Jan 2020
-
inlehmansterms.net inlehmansterms.net
- Apr 2019
-
developers.google.com developers.google.com
- Nov 2018
- Oct 2018
-
developer.mozilla.org developer.mozilla.org
- Jun 2018
-
cachix.org cachix.org
-
-
www.domenkozar.com www.domenkozar.com
- Dec 2017