Browser loads JS files from cache, but not CSS files - google-chrome

When navigating my site, my browser is loading the JS files from cache, but not the CSS files. This happens both running a local server and on the live site (to me and apparently to other users, which is apparent since the logs show mostly .css files getting loaded).
I've tried the other solutions (example): I am clicking around on hyperlinks (not refreshing) and my Chrome Devtools do not have "Disable Cache" checked.
Here is the initial request (using CTRL+F5 for a hard refresh):
Then navigating back to that page creates another request:
(Note: there is no Cache-Control sent in the second request, proving that I indeed did not refresh)
As expected, the server responds with a 304 Not-Modified for the .css file, but I don't understand why it's making a trip to the server at all (notice below the .js file is retrieved without a server request).
I believe you can look at the issue first-hand on your own machine by going to https://up.codes. I'm using Chrome 71.0.
Why are the CSS files not being cached?

#Allen found the issue (Vary header included cookie and the cookie was changing between requests), but I'll show how to fix it for the case of Flask for posterity. You can use Flask's #app.after_request() hook to make sure Flask does not add cookie when it hits this line:
#app.after_request
def add_header(response):
url = request.url
if ('.css' in url or '.js' in url or '.svg' in url or '.png' in url or
'.gif' in url) :
# Flask adds to the header `Vary: cookie` meaning the client should
# re-download the asset if the cookie changed. If you look at the Flask
# source code that comes next after the below return, it will add
# `Vary: cookie` if and only if session.accessed is true.
session.accessed = False
return response

Your server responded with different session cookie when requesting these css files, and your header set with Vary: Cookie, which caused the browser to send request again because of the session cookie change.

Check out for your web.config's compilation attribute, if its:
<compilation debug=”true”/>
CSS will get continually downloaded by clients on each pageview request and not cached locally within the browser.
If its set to false, the resource is only downloaded once to the client and cached there.
Check out this post: Chrome will not cache CSS files. .js files work fine

Chrome uses multiple types of caches.
Blink (the rendering engine that Chrome uses) uses an in memory cache and a disk cache. It uses this cache for images, fonts and js files.
As long as a file of that type is still in the memory cache or the file cache it will be loaded from there and skip the WebRequest API, this means that no call is made to the server.
I don't know exactly why css files are not being cached by Blink, but this is the reason why you see an HTTP request for css files and not for js ones.
Note, that if, for some reason, the js file is evicted from the memory cache and the disk cache you will see an HTTP request for the js files also.

Related

How can HTML assets be download before HTML content has finished dowloading

I am trying to improve my site load speed. When checking on the network requests, there is something that doesn't make sense to me:
How can the content that is going to be requested (css and js files) is being download before the html content has been downloaded?
I have tried with a hard reload and empty cache from chrome, but this has happened again. Morover, the files seem to be dowload from the server and not from the cache.
Another thing I don't get, is why chrome is pating the bar chart almost all with blue, when the majority of the time is waiting for the server to respond (TTFB).
Thanks in advance!
There's a couple of possibilities:
The HTML doesn't download all at once. It's possible for the server to send part of the page, pause, then send the rest. If the part that's sent first contains references to CSS, JS, image, font, or other files, the browser can start downloading those files as soon as it sees them referenced.
HTTP 2.0 supports "server push", a scheme where the web server can indicate to the client through HTTP headers that it should start downloading specific other files. Judging from some of the file names in your network tab, you're using Cloudflare; they use server push for some features, including "Rocket Loader".

Browser continue querying resources that must be cached from CDN

We store only index.html on our server and turned off caching for it. When we deploy application we upload all resources to CDN and replaced links in index.
Instead of XHRs file downloads browser fetches content from cache, but for files directly linked from index.html browser sends requests to CDN and got 'Not modified' response.
How to force browser use cached files referenced from not cached index.html?
Reproduced in Chrome at least.
That is normal behavior. '304 Not modified' means that the copy in the Browser Cache is still valid (etag) and a download is not needed.
If you clear the clients browser cache then the file from the cdn will be fetched with a "200 ok"

Access Uncached Files with HTML5's AppCache?

I have been trying to figure out HTML5's new AppCache, but I feel extremely limited here.
Let's assume that I have a website with four pages:
index.html
about.html
portfolio.html
contact.html
I have the above resources outlined in the manifiest, along with all of the website's resources. The manifest looks like the below:
CACHE MANIFEST
# 2013-05-23 2:33 PM
# Master Manifest
index.html
about.html
portfolio.html
contact.html
styles/reset.css
styles/styles.css
NETWORK:
*
I have added the appcache file type to the server configuration and have used the correct HTML tag attribute on each page listed above. Just for the record, the element looks like so:
<html lang="en" manifest="example.appcache">
I have tested this setup out on my mobile device, and everything works perfectly fine... Unless I don't load every page. It seems that I have to go to each page and cache it via my mobile browser, after which I may turn off DATA and go offline for my device to be able to browse the APPCACHE'd website.
But, here's my question - How do I setup AppCache to allow me to go to index.html, cache that page, and cache the rest of the resources in the manifest? Without having to visit and manually cache each resource?
If you cannot, then I would have to ask; doesn't that sort of defeat the idea behind AppCache and Offline Accessibility?
Thank you so much for the help all! :)
You shouldn't need to visit every page. I know you mentioned you've set the MIME type in Apache, but are you 100% certain it's working correctly?
You can check it by opening your manifest in a browser and checking the Response Headers in Chrome Web Inspectors's Network tab:
Content-Type should be text/cache-manifest
It's a bit hard to debug without having access to your site, but here's some instructions for how to interpret what happens in Chrome's Web Inspector with AppCache to help you debug the problem yourself:
The Resources tab will show you the contents and status of the Application Cache. It looks like this whilst it's downloading files:
The console will also log events when it's downloading:
Application Cache Progress event (0 of 48) http://cachedfile.url
Once it's done downloading it'll look like this and show you the list of cached files:
When you go back it'll log three events (assuming there aren't any changes):
Document was loaded from Application Cache with manifest http://manifest.url
Application Cache Checking event
Application Cache NoUpdate event
And then when you're offline it looks like this:
Hopefully between the console and the appcache table you'll be able to figure out what's happening.
The manifest file is correct and you do not need to visit each page to get in cache in your mobile. You could try if this is a problem with your mobile or browser and if you have defined in your server text/cache-manifest MIME type.
The appcache will only store the cache the first time it's downloaded. It's just a list of files that says, when it's downloaded the first time, cache it.
What you could do is after load in the background do an ajax call to load each of the intended resources but it's not particularly pretty.
So looks to me like it's acting how it should be.
CACHE:
This is the default section for entries. Files listed under
this header (or immediately after the CACHE MANIFEST) will be
explicitly cached after they're downloaded for the first time.
http://www.html5rocks.com/en/tutorials/appcache/beginner/
Ahmed
I get the following when visiting your site:
Creating Application Cache with manifest
http://www.iamaaron.com/appcache/example.appcache
Application Cache Checking event
Application Cache Downloading event
Application Cache Progress event (0 of 6)
http://www.iamaaron.com/appcache/styles/reset.css
Application Cache Progress event (1 of 6)
http://www.iamaaron.com/appcache/index.html
Application Cache Progress event (2 of 6)
http://www.iamaaron.com/appcache/contact.html
Application Cache Progress event (3 of 6)
http://www.iamaaron.com/appcache/attendees.html
Application Cache Progress event (4 of 6)
http://www.iamaaron.com/appcache/events.html
Application Cache Progress event (5 of 6)
http://www.iamaaron.com/appcache/styles/styles.css
Application Cache Error event: Resource fetch failed (404)
http://www.iamaaron.com/appcache/styles/styles.css
So, it looks like it's working correctly despite the Content-Type being empty, except for the CSS file which seems to be missing (the URL is wrong, it should be main.css by the looks of things).
BUT my developer tools don't show the app cache being filled and it doesn't work when it's offline.
Try and fix your 404 error with the CSS and make sure your apache it configured correctly to return the correct Content-Type, I reckon that's what's causing issues.

HTML5 application cache - cached files do not update, even when manifest is updated

I have a versioned cache manifest:
#version = e5b4271
Every time this version changes, my webapp loads the new manifest, but it never loads update files from the server. Even when I clear the browser cache (not the application cache itself), or hit Ctrl+Shift+R to force it to fetch a new version, it still loads the files from the old appcache.
The only way I can get it to update is to clear the browser's application cache in settings, but obviously this is unacceptable because I need it to update for regular users.
Any ideas why this would happen?
Just figured it out. I'm using Flask's development server, and it seems by default (via werkzeug) it sends cache headers for 12 hours for static files. Adding the following to my flask config solved this:
SEND_FILE_MAX_AGE_DEFAULT = -1
If anyone else has this issue, check your server config to make sure cache headers are not sent with static files. You can check this in the network tab in chrome during the first load of the file.

Offline app in asp.net

I am trying create an app which has offline features. The manifest file that I have created looks like this-
CACHE MANIFEST
# version 1.0.0
CACHE:
/ShareBill.Web-Offline/
/ShareBill.Web-Offline/Groups
/ShareBill.Web-Offline/Content/Site.css
/ShareBill.Web-Offline/Content/jquery-ui.css
/ShareBill.Web-Offline/Scripts/ShareBill.js
/ShareBill.Web-Offline/Scripts/lib/jquery-1.7.2.min.js
/ShareBill.Web-Offline/Scripts/lib/jquery-ui.min.js
/ShareBill.Web-Offline/Scripts/TransactionsIndex.js
/ShareBill.Web-Offline/Content/Images/ajax-loader.gif
/ShareBill.Web-Offline/Content/Images/br_down_icon.png
NETWORK:
/ShareBill.Web-Offline/Transactions/Filters
What I expect is when I view this url /ShareBill.Web-Offline/Groups. My browser should not make any requests to the server else the whole purpose of being offline would be void.
But as I can observe using fiddler is that, the browser makes a request for the manifest file every time i refresh the page. I made sure that I see the cached resources in the Chrome dev tools.
Now when I turn my IIS off and make a request like this, I end making my AppCache status as OBSOLETE. Then on the very next page refresh, I get a 404 response. Am I missing something in terms of implementation?
I applied the Expires header to request that was asking for the Manifest file. And that worked :)