Calendar
|
|
September '10 | |||||
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | ||
Quicksearch
Interesting Sites
Archives
Categories
Syndicate This Blog
Creative Commons
SWFObject 2.x and Zoomify
Zoomify is a software company/product that allows for continuous zooming on extremely large image data (JPEG2000) by first separating the original image in to many parts, and then using Flash (and XML) to dynamically piece them together again within a viewer. It works quite well (you can see an example from their website). They have a free "express" version; a version that comes bundled as part of Adobe Photoshop (CS3 or above - File -> Export -> Zoomify); a version that allows you to modify the look and feel of the view with XML (retail product), a version that contains the FLA source code (retail), and their flagship product, the Enterprise version which allows you to house everything necessary for simplistic creation all on the server...including everything all of the other versions offer, as well as more features and the ability to simply upload images directly to the server for parsing.
SWFObject is a JavaScript utility used for dynamically (or statically assisted) inserting of Flash media to a web page. If a user does not have Flash (or the correct version), it will automatically prompt them to download and install it. If they do not have JavaScript enabled, whatever content you were originally going to replace with the JavaScript will simply show instead. It also is unobtrusive, is Adobe's recommended way of embedding Flash to a web page, and has been time-tested to cover many edge-cases of its use.
Zoomify is a great tool to use in places where fine detail is needed to be viewed, but either a slow connection or speedy access is required to the content (plus, who wants to wait over 30 seconds for an image to load?). With working in a library, I've found it's an excellent tool for displaying historic images - such as digital archives. These high resolution images are not really useful in a regular web-centric view, but once you add the ability to zoom in to see detail, such as a person's face from something which was originally a 1.5"x3" panoramic scene - well, even I was in awe. ...and it's quick!
The problem with Zoomify is that by default, the free tools (for download from their website, or the one included in Photoshop) export an HTML page with EMBED and OBJECT tags directly in the HTML. If you work for a local/federal government or state owned library in the US, you are legally obliged to follow standards, and the EMBED tag is not an HTML standard and therefore breaks standards compatibility. What to do? Use SWFObject - it dynamically inserts the necessary code to get your browser to render the Flash movie on the page. Unfortunately, there's little information (if any?) on getting Zoomify to work with SWFObject out there on the web. Before I discovered I had a typo in my code, I emailed Zoomify support to ask about it and they emailed me back with Adobe's own version of AC_RunActiveContent.js - however Adobe recommends the use of SWFObject over their own JS implementation. I intend to thank Zoomify for trying, and giving them a link to this article entry. After all, they're more specialized as Flash developers so I can't fault them and their product really does seem to be the best (perhaps they accidentally attached the wrong project archive, who knows). Microsoft's Seadragon claimed to be revolutionary, and I had already been using Zoomify for about a year, and Zoomify felt more responsive and more people use Flash. Oh well, Microsoft. It's still cool.
Sorry for my rambling, on to some substance.
Zoomify provides the following HTML code by default in the HTML template that it creates for you:
So ignoring all of the classid, codebase, and other junk we don't completely care about, let's look at the actual values being passed to the browser through the PARAM tags within the OBJECT tag. These are the values we'll need to pass to SWFObject.
SWFObject separates its value passing to two variables, flashvars and params. FlashVars, found above, is its own PARAM variable, containing multiple values URL encoded. In this example, we have the variable zoomifyImagePath with a value of "example_img", and zoomifyNavigator set to false. The navigator is a small box that hovers over your image (full opacity) showing where you're viewing within the overall aspect of the original image. That takes care of the flashvars values, not to the params which is everything else. bgcolor is, of course, the background color for the flash stage, which will be covered up by your image data, so you can optionally ignore it if you'd like. menu...to be honest I don't know what this does, I changed the values and saw no difference and even removed it. src is the source, or location of the Zoomify viewing flash application that is used to actually view your data. This is a relative path to your viewer file. If you will be using this script in more than a single place on your website, I strongly recommend you only use one viewer and point all of them to that single viewer. Also notice the HEIGHT and WIDTH attributes to both the EMBED and OBJECT tags here. You can change them if you don't care about standards support and SWFObject, but they must match.
So how do we set up SWFObject with the knowledge now in our hands? Well, let's take a look at a standard (dynamic) SWFObject call.
So going from the example there, and the data we've collected, it seems pretty simple! But wait, what exactly is the zoomifyImagePath? Should that have some sort of file extension? Well, no, and that's what threw me, honestly (quite silly, really). The Flash file knows to look for the XML file in the folder that you're telling it to look in, so all you need to do is send the location of the folder (relative URL) and it'll do the rest. So let's see what that would look like:
The flashvars and params variables expected by swfobject.embedSWF are JavaScript objects, not simple variables (or rather, variables with object notation) as the variables themselves hold variables.
That's it. Keep in mind that the example above didn't use the bgcolor, or menu values. I also didn't use the "attributes" variable that can be passed to SWFObject where you can define the id, name, class, and align values. It's unnecessary for this example so I skipped it, as is showing a callback method (unnecessary that is).
Mix that together with a little modal magic and you have something a little bit nicer, such as what I did in the following page:
Honoring Saratoga County Veterans
Enjoy!
SWFObject is a JavaScript utility used for dynamically (or statically assisted) inserting of Flash media to a web page. If a user does not have Flash (or the correct version), it will automatically prompt them to download and install it. If they do not have JavaScript enabled, whatever content you were originally going to replace with the JavaScript will simply show instead. It also is unobtrusive, is Adobe's recommended way of embedding Flash to a web page, and has been time-tested to cover many edge-cases of its use.
Zoomify is a great tool to use in places where fine detail is needed to be viewed, but either a slow connection or speedy access is required to the content (plus, who wants to wait over 30 seconds for an image to load?). With working in a library, I've found it's an excellent tool for displaying historic images - such as digital archives. These high resolution images are not really useful in a regular web-centric view, but once you add the ability to zoom in to see detail, such as a person's face from something which was originally a 1.5"x3" panoramic scene - well, even I was in awe. ...and it's quick!
The problem with Zoomify is that by default, the free tools (for download from their website, or the one included in Photoshop) export an HTML page with EMBED and OBJECT tags directly in the HTML. If you work for a local/federal government or state owned library in the US, you are legally obliged to follow standards, and the EMBED tag is not an HTML standard and therefore breaks standards compatibility. What to do? Use SWFObject - it dynamically inserts the necessary code to get your browser to render the Flash movie on the page. Unfortunately, there's little information (if any?) on getting Zoomify to work with SWFObject out there on the web. Before I discovered I had a typo in my code, I emailed Zoomify support to ask about it and they emailed me back with Adobe's own version of AC_RunActiveContent.js - however Adobe recommends the use of SWFObject over their own JS implementation. I intend to thank Zoomify for trying, and giving them a link to this article entry. After all, they're more specialized as Flash developers so I can't fault them and their product really does seem to be the best (perhaps they accidentally attached the wrong project archive, who knows). Microsoft's Seadragon claimed to be revolutionary, and I had already been using Zoomify for about a year, and Zoomify felt more responsive and more people use Flash. Oh well, Microsoft. It's still cool.
Sorry for my rambling, on to some substance.
Zoomify provides the following HTML code by default in the HTML template that it creates for you:
So ignoring all of the classid, codebase, and other junk we don't completely care about, let's look at the actual values being passed to the browser through the PARAM tags within the OBJECT tag. These are the values we'll need to pass to SWFObject.
SWFObject separates its value passing to two variables, flashvars and params. FlashVars, found above, is its own PARAM variable, containing multiple values URL encoded. In this example, we have the variable zoomifyImagePath with a value of "example_img", and zoomifyNavigator set to false. The navigator is a small box that hovers over your image (full opacity) showing where you're viewing within the overall aspect of the original image. That takes care of the flashvars values, not to the params which is everything else. bgcolor is, of course, the background color for the flash stage, which will be covered up by your image data, so you can optionally ignore it if you'd like. menu...to be honest I don't know what this does, I changed the values and saw no difference and even removed it. src is the source, or location of the Zoomify viewing flash application that is used to actually view your data. This is a relative path to your viewer file. If you will be using this script in more than a single place on your website, I strongly recommend you only use one viewer and point all of them to that single viewer. Also notice the HEIGHT and WIDTH attributes to both the EMBED and OBJECT tags here. You can change them if you don't care about standards support and SWFObject, but they must match.
So how do we set up SWFObject with the knowledge now in our hands? Well, let's take a look at a standard (dynamic) SWFObject call.
So going from the example there, and the data we've collected, it seems pretty simple! But wait, what exactly is the zoomifyImagePath? Should that have some sort of file extension? Well, no, and that's what threw me, honestly (quite silly, really). The Flash file knows to look for the XML file in the folder that you're telling it to look in, so all you need to do is send the location of the folder (relative URL) and it'll do the rest. So let's see what that would look like:
The flashvars and params variables expected by swfobject.embedSWF are JavaScript objects, not simple variables (or rather, variables with object notation) as the variables themselves hold variables.
That's it. Keep in mind that the example above didn't use the bgcolor, or menu values. I also didn't use the "attributes" variable that can be passed to SWFObject where you can define the id, name, class, and align values. It's unnecessary for this example so I skipped it, as is showing a callback method (unnecessary that is).
Mix that together with a little modal magic and you have something a little bit nicer, such as what I did in the following page:
Honoring Saratoga County Veterans
Enjoy!
Style Switcher with jQuery
While developing an Adobe AIR application using CSS/HTML/JS, I decided I wanted to allow for templating of the application. The default template has the ability to switch view states (horizontal, or vertical). Since I'm building the application with CSS, HTML and JavaScript (with jQuery), I thought that in order to create this effect, I'd use a style switcher.
I then thought...hey, I wonder if this would work in browsers other than the WebKit version I've been testing under?!
It worked in Firefox 3.6.3, Opera 10.51, Chrome 5.0.342.8 beta, and Internet Explorer 6 (although my test CSS was broken in IE6). Opera 10.50 (tested first) had an issue with loading the secondary CSS on first attempt, but had it cached after that. 10.51 loaded everything just fine, but I can't be sure if it was still cached from the attempt with 10.50, or if 10.51 fixed an unknown issue to help fix it.
So, how did I do it?
Back in the day, Firefox had a little-known and not-often-used feature that allowed web-designers to incorporate multiple CSS layouts/designs right in the site, and the users could choose on-the-fly which UI they'd like to use (on each session) by going to View, Page Style, and then choose the style you wanted - if more than a single style was available from within the code. To give users this option, you include secondary stylesheets after the first, but in the link element, you specify that it's an alternative stylesheet, as so:
I originally started with this concept and tried swapping out the primary for the secondary and vice versa. Unfortunately this had some issues during development that may have been related to some other problems, but I dropped this attempt (but if Opera has a problem with caching, this route would solve that). Instead, I simply changed the href property of the link element. It was easier to target with jQuery without using URL matching/REGEX, or arbitrary naming of the rel property.
Anyhow, here's the code that I used (in this example, I am clicking on a button with ID of "switch"):
What this is doing:
...and we now have our style swapped out (quickly and easily) for an entirely new style.
I then thought...hey, I wonder if this would work in browsers other than the WebKit version I've been testing under?!
It worked in Firefox 3.6.3, Opera 10.51, Chrome 5.0.342.8 beta, and Internet Explorer 6 (although my test CSS was broken in IE6). Opera 10.50 (tested first) had an issue with loading the secondary CSS on first attempt, but had it cached after that. 10.51 loaded everything just fine, but I can't be sure if it was still cached from the attempt with 10.50, or if 10.51 fixed an unknown issue to help fix it.
So, how did I do it?
Back in the day, Firefox had a little-known and not-often-used feature that allowed web-designers to incorporate multiple CSS layouts/designs right in the site, and the users could choose on-the-fly which UI they'd like to use (on each session) by going to View, Page Style, and then choose the style you wanted - if more than a single style was available from within the code. To give users this option, you include secondary stylesheets after the first, but in the link element, you specify that it's an alternative stylesheet, as so:
I originally started with this concept and tried swapping out the primary for the secondary and vice versa. Unfortunately this had some issues during development that may have been related to some other problems, but I dropped this attempt (but if Opera has a problem with caching, this route would solve that). Instead, I simply changed the href property of the link element. It was easier to target with jQuery without using URL matching/REGEX, or arbitrary naming of the rel property.
Anyhow, here's the code that I used (in this example, I am clicking on a button with ID of "switch"):
What this is doing:
- Bind an onClick event to the element with an id of "switch"
- find the LINK element of a media type of screen that contains an href property and assign it to the variable "cssStyle"
- fade out the application (or a website wrapper?)
- swap the CSS style for another (inline), depending on what's currently loaded
- fade the application (or website wrapper) back in with new style
...and we now have our style swapped out (quickly and easily) for an entirely new style.
jQuery Printed Footer Links
I was randomly perusing the web and stumbled across an older interesting List Apart article (September 19, 2005 to be exact). In it, the author used JavaScript to create a list of all links found on the page, and then create a footer with a footnote-like list. I was using simple CSS to display the URL of the hyperlink in print display media, but that doesn't work in some browsers (IE), and worse off it can really mess up the visual order of the page.
Inspired by the article's intentions, I decided to use some jQuery to whip up a similar solution and I took the opportunity to use jQuery 1.4's new syntax for object creation (so this is 1.4 code only - see comments for a 1.3.x solution). Differences? I exclude hyperlinks set to the hash symbol (#) which shouldn't be found anyway (graceful degredation people!), "mailto" links, and I don't find link element's citations (blockquote "cite" property). I also believe his script would grab image information, but I'm not entirely sure, mine only searches hyperlinks. I also opted not to exclude listings of duplicate hyperlink values. If it's found twice, it lists it in the footer twice. Less JS processing, and more clear to the visitor (in my opinion).
Expected Issues: It requires JavaScript (and the jQuery library included on your page). If JavaScript is enabled but CSS is disabled, the hidden content will be visible to the user.
On to the code!
First thing's first, we should find the links in our code that we'd like to target. For my situation, I have a content class defined on my page for all content, and the column that contains the actual body is called ".col2_right" (yes, I know, ignore the fact of the poor naming scheme). So, in jQuery, we're going to target all hyperlinks found in the col2_right and content classes, but we don't want to include links to hashes or mailto links. I've also removed listing to nofollow links, but that is my choice (probably not a good one, but I digress).
We'll also need some sort of container to keep these found links wrapped in. I chose to use a fieldset and legend, you could just as easily create a DIV and a H2 or other tags for your own purposes. I also want to create an ordered list to match the found hyperlinks.
Here comes the real center, meaty goodness of the script: looping through our list of found hyperlinks, creating a little notification text next to the hyperlink's text, and add the hyperlink URL itself to the footnote section in the ordered list as a list item.
We use jQuery's each() method to loop through the items in the array, grab the link's URL so that we can do some testing on it, and modify it's value for inclusion in to the footnotes. Some links may be relative URLs, but that doesn't mean much to someone who doesn't know what a relative URL is. In fact, it would probably confuse me too at first. I happen to know that my domain forces www for the subdomain so I've added that in, fix that up as you like. I then create a span tag to hold the associated footnote number (the ListApart article used a superscript tag, I found regular text is more easily readable), add a class to it so it's only visible when printed, and create my list item element with the URL from our link, and place those elements in to the document in the appropriate places with the appendTo jQuery function.
Last but not least, we append our entire footnote to the end of our content body section. The full code is below.
Note the added "if" statement to check the length of the links variable. If it is empty, we did not find any links and don't want to create any extra markup when printing the page.
Oh, and the CSS: ".print_only { display:none; }" This should be placed in your normal style sheet, and leave it out from your print style sheet. If you don't have a print style sheet, extend it a bit: @media print { .print_only { display:none; } }
Note: Thanks to Stiles to provide some fixes and compatibility changes for jQuery 1.3.x.
Inspired by the article's intentions, I decided to use some jQuery to whip up a similar solution and I took the opportunity to use jQuery 1.4's new syntax for object creation (so this is 1.4 code only - see comments for a 1.3.x solution). Differences? I exclude hyperlinks set to the hash symbol (#) which shouldn't be found anyway (graceful degredation people!), "mailto" links, and I don't find link element's citations (blockquote "cite" property). I also believe his script would grab image information, but I'm not entirely sure, mine only searches hyperlinks. I also opted not to exclude listings of duplicate hyperlink values. If it's found twice, it lists it in the footer twice. Less JS processing, and more clear to the visitor (in my opinion).
Expected Issues: It requires JavaScript (and the jQuery library included on your page). If JavaScript is enabled but CSS is disabled, the hidden content will be visible to the user.
On to the code!
First thing's first, we should find the links in our code that we'd like to target. For my situation, I have a content class defined on my page for all content, and the column that contains the actual body is called ".col2_right" (yes, I know, ignore the fact of the poor naming scheme). So, in jQuery, we're going to target all hyperlinks found in the col2_right and content classes, but we don't want to include links to hashes or mailto links. I've also removed listing to nofollow links, but that is my choice (probably not a good one, but I digress).
We'll also need some sort of container to keep these found links wrapped in. I chose to use a fieldset and legend, you could just as easily create a DIV and a H2 or other tags for your own purposes. I also want to create an ordered list to match the found hyperlinks.
Here comes the real center, meaty goodness of the script: looping through our list of found hyperlinks, creating a little notification text next to the hyperlink's text, and add the hyperlink URL itself to the footnote section in the ordered list as a list item.
We use jQuery's each() method to loop through the items in the array, grab the link's URL so that we can do some testing on it, and modify it's value for inclusion in to the footnotes. Some links may be relative URLs, but that doesn't mean much to someone who doesn't know what a relative URL is. In fact, it would probably confuse me too at first. I happen to know that my domain forces www for the subdomain so I've added that in, fix that up as you like. I then create a span tag to hold the associated footnote number (the ListApart article used a superscript tag, I found regular text is more easily readable), add a class to it so it's only visible when printed, and create my list item element with the URL from our link, and place those elements in to the document in the appropriate places with the appendTo jQuery function.
Last but not least, we append our entire footnote to the end of our content body section. The full code is below.
Note the added "if" statement to check the length of the links variable. If it is empty, we did not find any links and don't want to create any extra markup when printing the page.
Oh, and the CSS: ".print_only { display:none; }" This should be placed in your normal style sheet, and leave it out from your print style sheet. If you don't have a print style sheet, extend it a bit: @media print { .print_only { display:none; } }
Note: Thanks to Stiles to provide some fixes and compatibility changes for jQuery 1.3.x.
YSlow: Getting a better score and a faster site.
I decided that it was finally time I took a serious look at increasing the YSlow score for our websites. I was under the impression that browsers would automatically cache (by default anyway) certain graphic elements to save on bandwidth, but our staff website has a repeating background image for a left hand navigation bar, and it would disappear for a fraction of a second while reloading the other page; this told me that something was not right, and YSlow might be the answer I was looking for (and that my PHP framework of choice was not to blame).
YSlow:
Initial Score: 67
I choose the smallest size images exported from Photoshop, and if I ever use a PNG, I use a great tool called "PNGGuantlet" (Windows only) which compresses PNGs while also removing the alpha channel problems that make PNGs appear with different colors than they were intended to. I also have compressed my main JS file, and CSS file(s). All XHTML should be valid (unless I updated a link and forget to escape an ampersand), the DOCTYPE is listed, character set is given, and all non-background images contain height and width properties. Oh, I also have a default favicon.ico file. These are all good recommendations to do regardless, and in doing so YSlow gave me a pretty decent score (albeit, not that great if it was a test in school).
Two modifications to YSlow's scoring:
1. I am not Amazon. I don't necessarily need a CDN for my content.
2. I don't need a subdomain to house my CSS, JS, and images. If I end up storing videos, that already has a subdomain set up and ready.
Therefore, I modified YSlow's grading scheme. To do so, there is a dropdown menu to the right of the 4 tabs in the YSlow toolbar, it is labelled "YSlow(V2)". Click the "Edit" button to the immediate right of that. In my scheme, I disabled "Use a Content Delivery Network (CDN)" and "Use cookie-free domains". You cannot overwrite the rule set, so you have to save it as something else, I named mine "SSPL" since that is the website domain that I care about (for work). Different websites have different criteria, so it only makes sense to name it something related to the website you are concerned about. Go through and uncheck what you don't believe applies to you. If you're uncertain, leave it checked. This little configuration raises my grade up already - that was easy.
Here are the .htaccess rules I've added to raise my own score, what they're for and why I chose to make them:
Enable GZip'ing of components:
The AddOutputFilterByType DEFLATE [list of mimetypes] was the command I used to gzip the particularly listed files that have such a MIME-Type: html, txt, js, css, js (variation), json, json (variation). Some browsers read JSON and JavaScript as an application mime-type whereas others read it as a text type, I figured I would simply cover my bases. Although these are ASCII types, you could just as easily gzip binary types, such as GIF, JPG, or PDF (though theoretically they should already be compressed and you're just adding extra work for the server).
Configure ETags:
From what I have read, ETags are a mixed breed. They can have some benefits, but they can also have some detractions. Again, considering that I'm not Amazon and I will be enabling the Expires heading, I opted to simply disable ETags. You can disable ETags in Apache under an .htaccess file with the unset rule above, along with the FileETag None to cover most supporting browsers (one would hope). I wasn't able to find any examples on how to properly "configure" ETags so that YSlow would not complain other than to simply turn them off. ETags, from what I've read, are a variation on telling the browser to cache certain files in a certain manner, but it doesn't work on any website that is run on multiple servers for the same content. Either way, I opted for the Expires heading which made ETags rather redundant from what I could tell.
Enabling an Expires Heading:
It appears that in Apache, by default, Expires headings are disabled, and just like mod_rewrite, you must explicitly tell Apache that you wish to use it, so the first thing you have to do is turn it on: "ExpiresActive On". Once that is done, there are a few ways to set the expiry time; I opted to use a human readable implementation, and YSlow expects a "far future" date (from the date last modified). As one of my sites is currently built with HTML files pulling in a template, the original files won't typically be modified for a long time, so I had to make my future date a FAR future date (10 years from last modification) - your experience may vary. For further information on Expires, take a look at the Apache documentation for mod_expires.
Additional speed enhancements:
I recently read that if you have a framework that may take some time figuring out what data must be displayed prior to even getting it to the server, it may be a good idea to flush the buffer so that the data that can be sent to the browser can be sent prior to everything else - such as the document head which contains the page title, CSS, and sometimes JS. That way, while the rest of the page is being rendered by the server, the JS/CSS has time to download. This is actually why I decided to leave my JS at the top of my website rather than placing it in the footer. I live by graceful degredation, but if the page loads before the JS does, it can also cause a screen flicker which is against accessibility guidelines for HTML. In this case, it was possible speed for accessibility - I choose accessibility. I personally really don't want me, or my client(s) getting sued for accessibility issues because "Oh hey, it loads a second faster now!". If you had an interactive rich website such as Facebook or MySpace, I'd imagine you'd have to place JS in the footer and have a separate, accessible domain for others...if that's even easily possible. Anyway, what I did with flushing the output buffer was to (in PHP) modify my template file, I called PHP's flush() function after the closing HEAD tag in the HTML template file.
Anyway, with those small tweaks and tricks, I was able to get my score up to 96. I have a B in 3 categories:
1. Expires header issue (CDN of ajax.googleapis.com, it won't recognize my CDN) as a CDN has a non-far future expiration date in the called JS file.
2. Minify CSS and JS - it is minified, so I'm not sure what it wants from me. The filesize is probably too large for an A.
3. Put JavaScript at the Bottom - I already explained why I don't want to do this, but I've left the rule in anyway.
Now my site seems to be a bit more responsive, and the background image I mentioned before no longer disappears and reappears (unless I press refresh really, really fast, confusing the browser's cache I guess).
YSlow:
Initial Score: 67
I choose the smallest size images exported from Photoshop, and if I ever use a PNG, I use a great tool called "PNGGuantlet" (Windows only) which compresses PNGs while also removing the alpha channel problems that make PNGs appear with different colors than they were intended to. I also have compressed my main JS file, and CSS file(s). All XHTML should be valid (unless I updated a link and forget to escape an ampersand), the DOCTYPE is listed, character set is given, and all non-background images contain height and width properties. Oh, I also have a default favicon.ico file. These are all good recommendations to do regardless, and in doing so YSlow gave me a pretty decent score (albeit, not that great if it was a test in school).
Two modifications to YSlow's scoring:
1. I am not Amazon. I don't necessarily need a CDN for my content.
2. I don't need a subdomain to house my CSS, JS, and images. If I end up storing videos, that already has a subdomain set up and ready.
Therefore, I modified YSlow's grading scheme. To do so, there is a dropdown menu to the right of the 4 tabs in the YSlow toolbar, it is labelled "YSlow(V2)". Click the "Edit" button to the immediate right of that. In my scheme, I disabled "Use a Content Delivery Network (CDN)" and "Use cookie-free domains". You cannot overwrite the rule set, so you have to save it as something else, I named mine "SSPL" since that is the website domain that I care about (for work). Different websites have different criteria, so it only makes sense to name it something related to the website you are concerned about. Go through and uncheck what you don't believe applies to you. If you're uncertain, leave it checked. This little configuration raises my grade up already - that was easy.
Here are the .htaccess rules I've added to raise my own score, what they're for and why I chose to make them:
Enable GZip'ing of components:
The AddOutputFilterByType DEFLATE [list of mimetypes] was the command I used to gzip the particularly listed files that have such a MIME-Type: html, txt, js, css, js (variation), json, json (variation). Some browsers read JSON and JavaScript as an application mime-type whereas others read it as a text type, I figured I would simply cover my bases. Although these are ASCII types, you could just as easily gzip binary types, such as GIF, JPG, or PDF (though theoretically they should already be compressed and you're just adding extra work for the server).
Configure ETags:
From what I have read, ETags are a mixed breed. They can have some benefits, but they can also have some detractions. Again, considering that I'm not Amazon and I will be enabling the Expires heading, I opted to simply disable ETags. You can disable ETags in Apache under an .htaccess file with the unset rule above, along with the FileETag None to cover most supporting browsers (one would hope). I wasn't able to find any examples on how to properly "configure" ETags so that YSlow would not complain other than to simply turn them off. ETags, from what I've read, are a variation on telling the browser to cache certain files in a certain manner, but it doesn't work on any website that is run on multiple servers for the same content. Either way, I opted for the Expires heading which made ETags rather redundant from what I could tell.
Enabling an Expires Heading:
It appears that in Apache, by default, Expires headings are disabled, and just like mod_rewrite, you must explicitly tell Apache that you wish to use it, so the first thing you have to do is turn it on: "ExpiresActive On". Once that is done, there are a few ways to set the expiry time; I opted to use a human readable implementation, and YSlow expects a "far future" date (from the date last modified). As one of my sites is currently built with HTML files pulling in a template, the original files won't typically be modified for a long time, so I had to make my future date a FAR future date (10 years from last modification) - your experience may vary. For further information on Expires, take a look at the Apache documentation for mod_expires.
Additional speed enhancements:
I recently read that if you have a framework that may take some time figuring out what data must be displayed prior to even getting it to the server, it may be a good idea to flush the buffer so that the data that can be sent to the browser can be sent prior to everything else - such as the document head which contains the page title, CSS, and sometimes JS. That way, while the rest of the page is being rendered by the server, the JS/CSS has time to download. This is actually why I decided to leave my JS at the top of my website rather than placing it in the footer. I live by graceful degredation, but if the page loads before the JS does, it can also cause a screen flicker which is against accessibility guidelines for HTML. In this case, it was possible speed for accessibility - I choose accessibility. I personally really don't want me, or my client(s) getting sued for accessibility issues because "Oh hey, it loads a second faster now!". If you had an interactive rich website such as Facebook or MySpace, I'd imagine you'd have to place JS in the footer and have a separate, accessible domain for others...if that's even easily possible. Anyway, what I did with flushing the output buffer was to (in PHP) modify my template file, I called PHP's flush() function after the closing HEAD tag in the HTML template file.
Anyway, with those small tweaks and tricks, I was able to get my score up to 96. I have a B in 3 categories:
1. Expires header issue (CDN of ajax.googleapis.com, it won't recognize my CDN) as a CDN has a non-far future expiration date in the called JS file.
2. Minify CSS and JS - it is minified, so I'm not sure what it wants from me. The filesize is probably too large for an A.
3. Put JavaScript at the Bottom - I already explained why I don't want to do this, but I've left the rule in anyway.
Now my site seems to be a bit more responsive, and the background image I mentioned before no longer disappears and reappears (unless I press refresh really, really fast, confusing the browser's cache I guess).
Enabling SSL (HTTPS) via htaccess Only if Matching a Specific Domain
I had a momentary stumble today that I (somehow) couldn't get through my head. Perhaps it's just because it's been so long since I've worked with mod_rewrite, but regardless of that, here's the situation and the solution:
"The Situation" said that the situation is:
I had multiple conditions that needed to be met before a rule should be run, otherwise it should be ignored.
I am running (and require) SSL on my production server.
I am not running SSL on my development box.
I didn't want multiple .htaccess files in my SVN repository.
The solution:
"Duh." Multiple RewriteCond in a row (separated by a newline) all must be met before the RewriteRule is run.
The resulting .htaccess took the following form:
The last 3 lines dealing with rewrite in my .htaccess file are related to the code library I'm using, and are not pertinent to the problem here. The important lines are as follows:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^staff\.sspl\.org [NC]
RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L]
The first condition tests to see if SSL (https protocol) is not being used in the request.
The second condition tests that the domain's host is "employees.sspl.org" (URL changed to protect the innocent).
If both tests pass, then I redirect the user to the host (and path "/$1") while using the https protocol (SSL). Done.
"The Situation" said that the situation is:
I had multiple conditions that needed to be met before a rule should be run, otherwise it should be ignored.
I am running (and require) SSL on my production server.
I am not running SSL on my development box.
I didn't want multiple .htaccess files in my SVN repository.
The solution:
"Duh." Multiple RewriteCond in a row (separated by a newline) all must be met before the RewriteRule is run.
The resulting .htaccess took the following form:
The last 3 lines dealing with rewrite in my .htaccess file are related to the code library I'm using, and are not pertinent to the problem here. The important lines are as follows:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^staff\.sspl\.org [NC]
RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [R,L]
The first condition tests to see if SSL (https protocol) is not being used in the request.
The second condition tests that the domain's host is "employees.sspl.org" (URL changed to protect the innocent).
If both tests pass, then I redirect the user to the host (and path "/$1") while using the https protocol (SSL). Done.
(Page 1 of 8, totaling 37 entries)
» next page

