htaccess caching for specific file extensions? - performance

I'm trying to optimize my site using yslow and I scored an F for "Add Expires Headers" I currently have my index page set to no-cache for users logging in so my question is, is it possible to add a filematch for other file types like images, css, and js to my htaccess file?
<META HTTP-EQUIV="Pragma" CONTENT="no-cache"/> <!-- Important for security -->
<META HTTP-EQUIV="Expires" CONTENT="-1"/>
If so will this impact or override my no-cache setting?
Thanks,
-Paul

Have a read of the section that starts "Never Expire" Policy in Chapter 3 of the Book of Speed - http://www.bookofspeed.com/chapter3.html

Related

Single Page Applications and Open Graph

I'm writing a SPA that uses underscore templating. The app searches for and rates music albums and returns the result via ajax. If facebook open graph metatags cannot be altered dynamically and the url of the page is constant regardless of search result, how can i make it so users can share that they rated a certain album.
ie)
<meta property="fb:app_id" content="118454308341351" />
<meta property="og:url" content="http://www.appurl.com" />
<meta property="og:title" content="Fleetwood Mac's Rumors" />
<meta property="og:image" content="AppImg.jpg" />
and update those properties to reflect a given search result.
The way I handle this is to create a dynamic page which I use as my open graph object, which is simply populated from the url parameters and redirects back to my SPA using the meta redirect.
<meta http-equiv="refresh" content="0;URL=http://YOUR_WEBSITE_WITH_DYNAMIC_CONTENT">
Thanks to this tutorial I found a solution: https://speakerdeck.com/sienatime/facebook-sharing-for-single-page-apps?slide=15
I send only meta tags if the user-agent of the http request includes "facebookexternalhit".
Here is some code for a backend with node and express:
app.get('/', (req,res) => {
if(req.header('user-agent').includes('facebookexternalhit'){
res.send(`
<meta property="og:title" content="The Slits' Cut" />
`);
} else {
res.sendFile(index.html);
}
})
You could also write your own middleware for that.
Our solution was to use Netlify pre-rendering, which pre-renders and then caches the rendered HTML to serve to crawlers and bots specifically.
This seems to work well. It allows us to dynamically update the OG meta tags, which are then cached by Netlify and served to crawlers, so they see the correct content.
It was easy to setup too, so if you are using Netlify this may be a good solution for you.

How do I correctly ENABLE browser caching using codeigniter?

Every time I do I search on this I get information about how to disable the browser cache.
Never anything about enabling it.
How do I get the back button to use the cache and not regenerate the page?
As far as I know you can control to force a browser to reload the data by means of these meta tags:
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Expires" content="0">
but you cannot force it to read from cache. The browser itself will do that for you if you don't explicitly specify to ignore the cache, and the page data are in fact cached and not expired.
This does not depend on CodeIgniter because it's client-side, but you might want to use the meta() function included in CI's html helper, which will simply output the corresponding meta tag. e.g:
echo meta('Cache-control', 'no-cache', 'http-equiv');
would generate the second code line above.
Note:
The 1st meta tag is specified for http/1.0 while the 2nd one is for http/1.1 but both are used to allow backwards compatibility.
If you're using xhtml instead of html remember to close the meta tags with />
Browser caching has nothing to do with codeigniter. You can use html meta tags to instruct the browser specifically not to cache pages or you can set a cache expiry for an individual page like so:
<meta http-equiv="expires" content="Mon, 10 Dec 2001 00:00:00 GMT" />
You could use a bit of php to drop tomorrows date in there. The browser (depending on settings) will usually pull as much as it can from the cache automatically, including when clicking the back button - the cache for the back button will work the same as if you were coming in from any other link.
You could set expires headers through your htaccess using something like the following on an apache server (you would have to ask about how to do this on other server types) to tell the browser that is should cache certain types of content for a given periods of time:
ExpiresByType text/html "access plus 60 seconds"
This will tell the browser to store anything of mime type text/html for 60 seconds (this includes codeigniter output) BUT DONT DO THIS if your dealing with dynamic content It will stop any dynamic page content being loaded and will stop any changes to your content being loaded by returning visitors (Obviously this second part is not such an issue with a 60 second cache).
The key thing to realise is that Your page is not one thing, it's made up of lots of parts, some of these parts should be called from cache (js, css, images, etc.) some should not (often html will fall into this category).
The browser will automatically call all the parts of your page from the cache where the cache has not expired.
Usually you would use .htaccess (or similar method) to cache your css, images, etc. (using versioning in filenames to force a reload when they change).
You should also take advantage of server side caching - codeigniter does this for whole pages but I dont tend to find this very helpful for any kind of dynamic site so I would take a look at for using phil sturgeons partial caching library for ci if you are interested in ss caching:
https://github.com/philsturgeon/codeigniter-cache
This wont stop a request being sent to the server but will mean that request requires less processing and can be served as one or several pieces of static content.

IE10 renders in IE7 mode. How to force Standards mode?

On microsoft's site they claim that simple doctype declaration is enough. But even a document as short as this falls back to IE7 mode:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
</body>
</html>
http://d.pr/i/fvzb+
Internet Explorer makes the assumption that most webpages were written to target earlier versions of IE and looks at the doctype, meta tags and HTML to determine the best compatibility mode (sometimes incorrectly). Even with a HTML5 doctype IE will still place your website in compatibility mode if it's an intranet site.
To ensure that your website always uses the latest standards mode you can either make sure Display intranet sites in Compatibly is turned off. However you have to do this on each machine local to the web server (instructions are below).
Alternatively, and better yet, you can use the X-UA-Compatible header to turn this off from the server. It's important to note that using the meta tag will not work!
<!-- Doesn't always work! -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
Throughout MSDN it's mentioned that using a host header or a meta tag should override even intranet sites. The article Understanding compatibility modes in internet explorer 8 says the following.
A large number of internal business web sites are optimized for Internet Explorer 7 so this default exception preserves that compatibility.
...
Again if a Meta tag or http header is used to set a compatibility mode to the document it will override these settings.
However, in practice this will not work, using a host header is the only option that works. The comments section of the article also shows numerous examples of this exact issue.
Using a Meta tag also has several other issues such as ignoring the tag if it's not directly under the <head> tag or if there is too much data before it (4k). It may also trigger the document to be reparsed in some versions of IE which will slow down rendering. You can read more about these issues at the MSDN article Best Practice: Get your HEAD in order.
Adding the X-UA-Compatible header
If you are using .NET and IIS you can add this to the web.config, you could also do this programmatically:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="X-UA-Compatible" value="IE=edge" />
</customHeaders>
</httpProtocol>
</system.webServer>
If you're not using IIS it's easy to do in any language. For example, here's how to do it in PHP:
header('X-UA-Compatible: IE=edge');
As long as the X-UA-Compatible header is present with the HTML5 doctype, a site will always run in the latest standards mode.
Turning off Compatibility View
It may still be useful to turn off Compatibility View. To do so untick Display all intranet sites in compatibility view in the Compatibility View Settings.
You can bring this up by hitting Alt to get the menu.
Edit
This answer also pertains to IE9.
This works for me..
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
Try adding the following tag to the head
<meta http-equiv="X-UA-Compatible" content="IE=11,IE=10,IE=9,IE=8" />
The meta tag doesn't do anything for intranet sites and my issue was IE10 rendering in IE10 compatibility mode. What tackled the issue for me was taking #Jeow's answer further and using that value in an http header by adding the following to web.config under IIS:
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<!-- <add name="X-UA-Compatible" value="IE=edge" /> not good enough -->
<add name="X-UA-Compatible" value="IE=11,IE=10,IE=9,IE=8" />
</customHeaders>
</httpProtocol>
</system.webServer>
For IE purposes, intranet sites include public-facing sites that are not routed to externally - for example a Stackoverflow employee working from the office would probably see stackoverflow.com in compatibility mode.
It worked perfectly for me when i did the folowing:
On http://msdn.microsoft.com/en-us/library/gg699338(v=vs.85).aspx
Used the exact example they provide in the first box(added the missing </html> at the bottom), opened it in IE10 and standards was forced, i think you may need actual content in the html for it to force standards not sure though.
My suggestion would be to replace your empty code with actual content(something simple) and see what it does.

Setting the character encoding in Day CQ

I've got some markup that I'm adding to a page component in Day CQ that was UTF-8 encoded by the author. Initially I couldn't save it in CRXDE, b/c the editor was set to save in ISO-8859-1. I found the setting to change this, but now when the page using this component is rendered to the browser, some of the characters appear to be using a different encoding. Is there a setting for the CQ web server, or servlet engine that I need to change? I'm running CQ 5.3 on Windows 7.
Edit: The HTTP Headers have Content-Type: text/html;charset=UTF-8 and there is a meta tag that specifies meta http-equiv="Content-type" content="text/html; charset=utf-8"
I believe the solution was to add pageEncoding="UTF-8" to all JSP's that are part of rendering this page. I also modified the web.xml file per this link: http://www.coderanch.com/t/87264/Tomcat/Character-Encoding-Tomcat, and restarted the server a number of times.

IE8 compatibility mode...help?

I'm trying to setup compatibility mode in one of our web products however I cannot get compatiblity mode to work via a particular server.
To recount what I've done so far:
I've set the the HTTP header X-UA-Compatible in IIS to IE=7
I've set also addded the meta element as the first element in the head element to the master page:
Using fiddler I've checked the HTTP traffic and I can see the header value and the meta element. Using the same browser (different tab) when I point to our staging server the document renders as IE7 brower mode and IE7 document mode. Which is great. Unfortunately when I point to the live server which is configured in the same way as the staging server the document renders as IE8 browser mode and IE7 document mode.
As a result when I check the dev tools the CSS which is being applied to the html element is
" ie ie8 CSS1Compat Win32"
vs
" ie ie7 CSS1Compat Win32"
Has anyone got any suggestions what I might have missed?
Note there is a blank line before DOCTYPE instruction (which is meaningful).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:b="http://www.backbase.com/2006/btl"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:e="http://www.backbase.com/2006/xel"
xmlns:c="http://www.backbase.com/2006/command" xmlns:d="http://www.backbase.com/2006/tdl"
xmlns:x="http://woodmac.com/x">
<head><meta http-equiv="X-UA-Compatible" content="IE=7" /><meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /><meta http-equiv="expires" content="-1" /><meta name="robots" content="index,follow" />
<script type="text/javascript" src="Backbase/engine/boot.js"></script>
<link href="App_Themes/MANDA/print_style.css" type="text/css" rel="stylesheet" /><link href="App_Themes/MANDA/screen_style.css" type="text/css" rel="stylesheet" /></head>
<body>
Thanks,
Philip
Take a look at this site and see if you missed anything. It may be related to the doctype, but it looks like the meta tags should override that.
What url are you using to access each server? IE8 has an option which is enabled by default which will force "intranet", or single-name, domains to render in compatibility mode regardless of your XUA and other header settings (Tools > Compatibility View Settings > Display intranet sites in compatibility view).
If this setting is enabled and you are accessing one or the other of your staging and prod sites with something like http://servername, then this may be causing them to render differently regardless of your setting.
Recently I was faced with this issue and ended up requiring all servers to be accessed with a domain extension (e.g. http://servername.company.com), and set the XUA header to IE7. Now everything renders in IE7 mode regardless of the server its running on.

Resources