One thing to consider (hey, i looked at the net tab this time is changing your caching strategy. Since your site is generating the markup for these profile images, you can make sure they are unique, and versioned.
Set a cache control public on them with a 1 yr expire. The browsers won't have to ask the server if they've been modified, it will speed up the page load even more and reduce network requests. If the user then changes their icon, make sure the url to the image changes, and you should be good. Looks like they are hashes right now, so i assume if they uploaded a new one it would have a new hash... looks like all you need to do is set the cache control headers
1. All of the images are unique and served with maximal browser caching headers so browsers should not reload them once they are in the cache. Just as @ddumont suggests.
2. We do settle on 100x100 icons and use them everywhere. We'd rather serve one larger image than multiple versions of the same image.
3. The images themselves should serve very fast. My browser shows between 55-120ms per image. Again, this is only once.
So @422's issue is something that needs to be worked out, but not a fundamental problem with vanillicon itself.
I changed the way static and autostatic send back cache headers. We were using nginx's "expires max" directive, but I change it to "expires 1M". When given "expires max", nginx actually breaks the RFC which states that things can be cached for max 1 year. So perhaps some browsers saw that invalid Expires header and discarded it.
Took the wrong request trace, the vanillaicon.com headers look good except you need Cache-Control: public ( I don't believe you need a maxage with public and expires header)
Just so you know, the browser has 4 modes of operation with regard to caching:
1) Empty cache - Everything is requested fresh from the origin servers by necessity.
2) Hard refresh - Most things are re-requested from the origin servers, but some things like previously received 301 redirects may still be cached.
3) Regular refresh - The cache is respected, but some things that exist in cache will cause a query to the remote that results in a 304.
4) Regular navigation - The cache, if it has a valid entry for the requested resource, short circuits any requests, so 304s aren't even performed.
I just did some testing and all the cache controls seem to be working fine under regular browsing conditions. Even Vanillicon. I adjusted the max-age down to one month and the browser seems to prefer that.
http://bayimg.com/FAKNDaaDP I know, Tim. I'm not trying to be argumentative. But you're using 3. I would argue it's not necessary (because of the unique name every icon will get when uploaded).
It would also perform much better to use 4. As you can see here, there's a server request for each image. It happens to be fast, but there's a handful. The image doesn't render until the 304 is gotten, and the request could be avoided entirely by setting cache-control to public and providing a 1 yr expires header.
BTW. I work at IBM. I do this kind of stuff all the time, I currently am working on a project to optimize dojo 1.7 with a back-end service that does stuff crazy fast and efficiently.
The web applications we design are on a no-page-refresh model, where everything is ajax and app code is downloaded as needed.
I'd love to see Vanilla move more to this model where the php side of it is mostly for server processing and initial page load, but all app code is build on a robust js framework.
If you guys have plans to do this, it would be nice to talk about them with you
I think we agree here, but we had an error with our response headers where the max-age was more than a year which would then cause a lot of browsers to disregard the cache entirely.
@ddumont, do you think it's better to have Cache-Control: public rather than Cache-Control: max-age=2592000? Do you think we can put both items in?
We've had cases in the past where we've thought that our stuff had the right headers and then someone's old proxy server screwed the content.
For what it's worth (probably not much) this is almost exactly what my network panel shows.
[Edit] Pfftffpt. That's what it shows when I refresh (304s). When I click into the discussion it loads from cache and I see what Tim is seeing. When I hard-refresh I get 200s. Expected.
The expiration time of an entity MAY be specified by the origin server using the Expires header (see section 14.21). Alternatively, it MAY be specified using the max-age directive in a response.
It goes on to say setting maxage and Expires will have maxage override Expires according to the spec, and maxage seems to imply public.
I don't know which combinations you've tested with but the most common one at work I've seen is public with an expires 1 yr out.
I tested what @jspautsch and what I'm seeing agrees. No request when clicking on the page, but it checks on refresh for a 304. So... I guess maybe chrome changed their behavior... I recall having to ctrl+f5 to force a cache-control public resource...
Oh well... If what you're doing is working for you, I don't think any of this matters a bunch. (It's alot better than what I thought was happening based on my refresh network log)
My comments about no page refresh webapp model still stand though
I wonder if Expires, Cache-Control: max-age and Cache-Control: public conflict if they're all specified?
The reason is because nginx has an 'expires' directive which sets both Cache-Control: max-age and Expires: to values that correspond (the Expires: occurs exactly max-age seconds after current time). It would be annoying to have to manually set Expires.
Nah, Tim the behavior I'm seeing (when clicking around instead of refreshing is fine. I hadn't tried that because I was used to being able to refresh and see no requests outbound.
I think there's something going on with maxage, though. Here's an image from one of our servers: Cache-Control:public Date:Wed, 16 Nov 2011 20:56:48 GMT Expires:Thu, 15 Nov 2012 20:56:46 GMT Last-Modified:Tue, 25 Oct 2011 18:35:02 GMT
On refresh I still get no 304 result (always pulled from cache) unless I ctrl-f5 So I guess chrome didn't change.
Either way, I think you're already cutting out 95% of the unnecessary traffic doing what you're doing
Answers
added Image ( cache cleared ) via tools in FF
There was an error rendering this rich post.
There was an error rendering this rich post.
Vanilla Forums COO [GitHub, Twitter, About.me]
What did you end up changing to help 422's browsing?
There was an error rendering this rich post.
Set a cache control public on them with a 1 yr expire. The browsers won't have to ask the server if they've been modified, it will speed up the page load even more and reduce network requests. If the user then changes their icon, make sure the url to the image changes, and you should be good. Looks like they are hashes right now, so i assume if they uploaded a new one it would have a new hash... looks like all you need to do is set the cache control headers
There was an error rendering this rich post.
1. All of the images are unique and served with maximal browser caching headers so browsers should not reload them once they are in the cache. Just as @ddumont suggests.
2. We do settle on 100x100 icons and use them everywhere. We'd rather serve one larger image than multiple versions of the same image.
3. The images themselves should serve very fast. My browser shows between 55-120ms per image. Again, this is only once.
So @422's issue is something that needs to be worked out, but not a fundamental problem with vanillicon itself.
Vanilla Forums COO [GitHub, Twitter, About.me]
Request Method:GET
Status Code:304 Not Modified
Request Headers
Cache-Control:max-age=0
If-Modified-Since:Thu, 10 Mar 2011 21:39:30 GMT
Response Headers
Cache-Control:max-age=2592000
Expires:Fri, 16 Dec 2011 15:58:42 GMT
Last-Modified:Thu, 10 Mar 2011 21:39:30 GMT
I shouldn't, ideally, be seeing a 304 at all. That's a round trip to the server for each image.
Try setting:
Cache-Control: public
Expires: (1 year in the future)
There was an error rendering this rich post.
There was an error rendering this rich post.
1) Empty cache - Everything is requested fresh from the origin servers by necessity.
2) Hard refresh - Most things are re-requested from the origin servers, but some things like previously received 301 redirects may still be cached.
3) Regular refresh - The cache is respected, but some things that exist in cache will cause a query to the remote that results in a 304.
4) Regular navigation - The cache, if it has a valid entry for the requested resource, short circuits any requests, so 304s aren't even performed.
I just did some testing and all the cache controls seem to be working fine under regular browsing conditions. Even Vanillicon. I adjusted the max-age down to one month and the browser seems to prefer that.
Vanilla Forums COO [GitHub, Twitter, About.me]
I know, Tim. I'm not trying to be argumentative. But you're using 3. I would argue it's not necessary (because of the unique name every icon will get when uploaded).
It would also perform much better to use 4.
As you can see here, there's a server request for each image. It happens to be fast, but there's a handful. The image doesn't render until the 304 is gotten, and the request could be avoided entirely by setting cache-control to public and providing a 1 yr expires header.
There was an error rendering this rich post.
The web applications we design are on a no-page-refresh model, where everything is ajax and app code is downloaded as needed.
I'd love to see Vanilla move more to this model where the php side of it is mostly for server processing and initial page load, but all app code is build on a robust js framework.
If you guys have plans to do this, it would be nice to talk about them with you
There was an error rendering this rich post.
@ddumont, do you think it's better to have Cache-Control: public rather than Cache-Control: max-age=2592000? Do you think we can put both items in?
We've had cases in the past where we've thought that our stuff had the right headers and then someone's old proxy server screwed the content.
When I go to the root discussion list and then click into this discussion, my network panel shows this:
That, to me, looks like optimal performance, and as you can see by the response headers, I have not changed anything.
Vanilla Forums COO [GitHub, Twitter, About.me]
[Edit] Pfftffpt. That's what it shows when I refresh (304s). When I click into the discussion it loads from cache and I see what Tim is seeing. When I hard-refresh I get 200s. Expected.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html It goes on to say setting maxage and Expires will have maxage override Expires according to the spec, and maxage seems to imply public.
I don't know which combinations you've tested with but the most common one at work I've seen is public with an expires 1 yr out.
I tested what @jspautsch and what I'm seeing agrees. No request when clicking on the page, but it checks on refresh for a 304. So... I guess maybe chrome changed their behavior... I recall having to ctrl+f5 to force a cache-control public resource...
Oh well... If what you're doing is working for you, I don't think any of this matters a bunch. (It's alot better than what I thought was happening based on my refresh network log)
My comments about no page refresh webapp model still stand though
There was an error rendering this rich post.
The reason is because nginx has an 'expires' directive which sets both Cache-Control: max-age and Expires: to values that correspond (the Expires: occurs exactly max-age seconds after current time). It would be annoying to have to manually set Expires.
Vanilla Forums COO [GitHub, Twitter, About.me]
I think there's something going on with maxage, though.
Here's an image from one of our servers:
Cache-Control:public
Date:Wed, 16 Nov 2011 20:56:48 GMT
Expires:Thu, 15 Nov 2012 20:56:46 GMT
Last-Modified:Tue, 25 Oct 2011 18:35:02 GMT
On refresh I still get no 304 result (always pulled from cache) unless I ctrl-f5
So I guess chrome didn't change.
Either way, I think you're already cutting out 95% of the unnecessary traffic doing what you're doing
There was an error rendering this rich post.
There was an error rendering this rich post.