Caching and Sessions


People who come to a site want to get a quick load time. If your webserver can respond with the same exact content every time, then it can be cached by the webserver, a reverse proxy, and content-delivery network (CDN), the browser itself, or even in a bundle of static assets (HTML, CSS, JS, images, etc.) downloaded as part of your app and loaded in a WebView.

The Vary header is sent by web servers in response to different requests, and informs caches of what request headers might need to trigger a different response. If request headers use the same HTTP verb, the same URL, and all the headers previously mentioned by Vary remain the same, then one of the above caching layers can simply return the result, without telling your server. (Keep in mind that this may affect any analytics you gather on the server side.)

If you were starting a new web app now, you might want to build it entirely out of a bundle of static resources (HTML, CSS, Javascript) and then have Javascript dynamically go and interface with various APIs on the Internet (including Web3 gateways, for interacting with a blockchain). Then you can think of website back-ends as mere “web services”, rather than “web sites”. This is the approach we begun to advocate two years ago:


Since Qbix Platform was started many years ago, it still relies on PHP to render the initial pages, using include() to render headers and footers, etc. However, modern apps built with Qbix can be cached with a CDN, making them essentially equivalent to bundles of static files. We even have a scripts/Q/bundle.php script that can bundle up resources for distribution on app stores (iOS, Android, etc.) There’s no real need to use a static site generator, if you can just cache resources as they are requested, essentially generating a static site from a dynamic one.

Developers of web apps have several options to “opt-in” to better caching and static file generation. One is to gather all “dynamic” content in one channel and separate it from the “static” content. Qbix supports this with the Q/sessionExtras hook. What this essentially means is that the very first request from first-time visitors (coming with no cookies) will result in the server sending a completely static resource, with no Set-Cookie directives. This resource can be cached by intermediate layers. Then, Javascript loaded in the browser leaps into action and makes an AJAX request for session-specific information, which triggers the Q/sessionExtras hook. This time, the server might call Q_Response::setScriptData() in order to add stuff like Q.Users.loggedInUser and `Q.Users.roles". The client would then use this data to modify what it presents to the user.

Some more sophisticated solutions can be developed by relying on “edge-side” scripting at CDNs, such as Amazon Lambda + CloudFront, CloudFlare Workers or plain old edge-side includes on local Varnish caches.

In any case, the session needs to be persisted on the client. With third-party cookies being eliminated, the browser will refuse to set them. (This is already true in iframes hosted by sites you never visited, like a chat widget embedded inside a site). While Apple’s ITP does allow the Storage Access API, as of this writing, Chrome still has it “in development”. And besides, there may be a better way.

Service Workers introduce an additional layer of Javascript that runs “underneath” websites and intercept network traffic to and from them, including fetch (pull), as well as background events such as push and sync. Qbix has begun using service workers to enable “cookies” in websites, although this is just to support a familiar way to persist data. In environments where cookies are not available anymore (such as in a third-party iframe), Qbix simulates the http-only cookies by handling them inside the Service Worker, never storing them on the client side, but instead storing them on on the server side, in a database table called users_cookie. Qbix generates a non-extractable public key in each browser and sends it with requests to serve as the index into this table. The Service Workers can also intercept, hash and sign requests to the server. They may omit really large payloads, like video uploads.

Qbix Platform handles all this and more for you, so you can focus on building your apps. It even lets your apps manage access to certain community resources, rather than having to rely on security through obscurity – storing them at long and random URLs that you hope people won’t share with others.