My Blog

contains PHP and other web related content. (Sometimes there are some off topic things - don't freak out!)

Archive for the ‘Misc Web Design’ Category

Javascript and CSS Compression and Cache

Thursday, February 25th, 2010

I’ve been researching caching and compression techniques for my external resources for some time. My first design of JEMDiary was very greedy with HTTP connections. Couple that with having a less-than-perfect host (Dreamhost bleh…), users could feel the burn. I didn’t like it because it would even take ME forever to use my own website. I went on to discover many different key points I use when creating sites now – the Steps to Optimize Assets.

Steps to Optimize Assets

There are a few steps I live by when I design my websites now.

  • Use a subdomain for images, js and css. While I don’t go overkill with this (see: not 5 page brochure website), I do try to separate assets over multiple subdomains. The important thing is not to have too many – but none what so ever limit your user from loading your site as quick as possible. I generally use one for my assets and one for user submitted assets.
  • Use sprites. Whenever possible, reduce the amount of HTTP requests by combining images. It is faster to load an image that is 3x the size of the one you’re displaying than to open 2 more HTTP connections after you download the first image.
  • Cache non changing elements as long as possible. One of the biggest things I noticed on my dreamhost server was the misconfiguration of e-tags. After disabling them, I went and looked further into caching techniques. I found that most of my assets didn’t change – so I cached them up to a year.
  • Compress away white space. After you edit the source of your css, it doesn’t need to be pretty. In fact, things like comments and white space in css and javascript are just wasted bytes… bytes you could remove… but bytes you shouldn’t remove from your source. I deal with this by making a compressed copy on build.

These are my main rules. This article, however, is going to focus on how I deal with Javascript and CSS.

Disclaimer: The methods I’m going to describe here can be labor intensive. When you build your own system, you should strive to make some of these automated.

Preparing CSS for deployment

The first thing I do is create that subdomain. For my site example.com, users can visit http://example.com for the content. I create a subdomain called assets.example.com which is where I expect to get my content from. I generally create a server alias in the main config. This technically means that duplicate content could be served at both assets.example.com and example.com. I finish up by adding the following lines to the .htaccess file:

?View Code APACHE
1
2
3
4
5
6
#make sure assets load properly
RewriteCond %{HTTP_HOST} ^assets.example.com
RewriteCond %{REQUEST_URI} !^/css
RewriteCond %{REQUEST_URI} !^/js
RewriteCond %{REQUEST_URI} !^/images
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

This make sure that if the host is assets.example.com and the content is not coming form the css, js or images folder, to redirect with a 301 to the main domain. This will stop duplicate content.

Enough about this, what about my CSS?

I actually hold my css in a different folder in my architecture – not some place that is world readable. I usually call it the public_source folder – which is at the same level in the source tree as say the www or html folder. In this example, I’m going to call my example file main.css. So it is actually located at /var/www/public_source/main.css.

Next, I’ll create a file called dev.php in the assets folder where I plan to test my css from. So, this file is located at /var/www/html/css/dev.php. It may contain this content:

1
2
header ('Content-type: text/css');
readfile('/var/www/public_source/main.css');

So, now when I load my website, I can do the following to load my source css:

1
<link rel="stylesheet" type="text/css" href="http://assets.example.com/css/dev.php" />

Of course, when the website is built and deployed, we will be using a different URL.

Next, lets talk about compression of the CSS. I use CSS Tidy to compress my code. The code to invoke this is pretty simple.

1
2
3
4
5
6
7
8
9
10
11
require 'csstidy-1.3/class.csstidy.php';
$cssSource = file_get_contents('/var/www/public_source/main.css');
 
$css = new csstidy();
$css->load_template('highest_compression');
$css->set_cfg('remove_last_;',TRUE);
$css->set_cfg('sort_properties', TRUE);
$css->parse($cssSource);
$cssFinished = $css->print->plain();
 
file_put_contents('/var/www/html/css/main.1.css', $cssFinished);

You’ll notice that I named the file main.1.css. The number will be explained later (its used for caching).

So, the CSS is read, compressed and cleaned, and outputted to a location that the webserver can serve it from. Now, instead of using dev.php as the source, we’ll use main.1.css. Congratulations – a smaller CSS file!

The final thing to do is adjust the caching of this script. Whenever we change the CSS on the development platform, we’re reading it in new using dev.php. However, when this is built and deployed, it should be a built version (or compressed) of the file. This means every code deploy requires this build system. And with release numbers on main software, we’re also going to increment our file name. So our second deployment of the software package (if the CSS source has changed) will now be built using main.2.css – and the link statement will be pointed towards that.

The caching then can make the assumption that this file will never change. The CSS may change but the file is a new name then. And since we can’t just load portions of a file whenever there is a change, even a small change in a non-cached file will make the entire file load. So with this in mind, I cache my CSS files for one year. I put the following in my config:

?View Code APACHE
1
2
3
ExpiresActive On
#1 yr
ExpiresByType text/css A31536000

This means that the file will be cached one year from the first time it is accessed. So, if the source HTML continues to point at the same CSS file (say… main

hCard – should I care?

Saturday, January 23rd, 2010

So lately, I’ve been looking into the semantic tools available on the web. I want to make sure that my online identity is easily searchable and undeniably accurate. Using semantic tools such as XFN, FOAF and hCard may help me.

I can’t help but seeing some of these and thinking ‘flash in the pan’ though. What I really want to see is a big – or a giant – company come through and make use of these. For example, LiveJournal is exporting FOAF information – but who cares? Where can I actually find value out of that information that was previously consumed? If I search ‘Aaron Saray’ on Google, will my friends show up along the sidebar?

At any rate, I did implement a very basic FOAF RDF file on my home page. I am reluctant to do anything further, however. Like I said, I’m not seeing much value as of yet. However, I did want to look at another alternative, hCard.

What is hCard

hCard is just an expansion on the vCard standard. The website says it has a 1:1 representation of the vCard properties. Plus, it goes further by allowing itself to be embedded into web properties. So basically, its a vCard that I show on my website, right? Isn’t this already what my contact page does? (Yes – but the argument is this is a standardized form so that it can be machine readable – I get it I get it).

Who is using hCard

More and more libraries are using hCard. The number one thing that caught my eye was the possible implementation by drupal (see http://groups.drupal.org/node/1898. Yet, I’m seeing many people put out the information to be consumed, but I’m not seeing many groups actually doing the consuming.

How can I use it?

Well besides looking at the specs, you can use the following two libraries in PHP:
phpMicroformats
Microformats Parser

So what did you do?

Ok so after all this complaining, I have to admit – I’m still guilty… I implemented it on my contact page :)

Friend of a Friend: FOAF

Wednesday, January 20th, 2010

So I added my own FOAF link on my home page. The RDF file is here:
http://assets.aaronsaray.com/assets/foaf.rdf

For those who aren’t familiar, Friend of a Friend is a protocol defined to help machines read relationships between entities (persons) on the internet. The relationships are set up in RDF file. (Mine is severely limited – either I have no friends – or am just lazy – you tell me!) For more info, check out http://www.foaf-project.org/.

By far, the best library I’ve found for parsing FOAF files is located here: http://gna.org/projects/phoaf

Protect Your Image from Download

Wednesday, December 16th, 2009

I came across a great idea dealing with protecting image downloads from the site. Now, this is not fool-proof. There are lots of other ways to download the image, but this may stop the casual downloader. Nope, its not disabling the right click or using java. It requires one single transparent gif. Let’s see how.

(more…)

Auto Failover for CDN based Javascript

Monday, November 30th, 2009

Using my javascript error reporter code helps me get a better understanding of what my clients are experiencing when visiting my website. One thing I did notice was the failures from time to time of Google’s CDN based Jquery.

To solve this issue, I decided to keep a local copy as well. For the most part, Google’s version is going to be faster and have a better cache method. However, I’d rather have an uncached version of it loaded into the user’s browser than nothing at all! So, in the very rare case that the user’s browser fails to load the Google javascript, I load a local copy of it.

First Step: Load JQuery From Google

The very first thing I do is to include jQuery from google’s code base using the following tag:

1
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

This will retrieve the latest version (1.3.2) from Google with the proper compression and cache response I like.

However, this sometimes was failing – well according to my error reporting script. What to do?

Test for a successful load of jQuery

Since the SCRIPT tag does not have an ‘onerror’ standard notifier like our image, the next best thing to do is test for the jQuery object right after the page loads. Since we’re using inline javascript, the first request to the external javascript will block while loading. When it completes, this small snippet will then execute.

I’ll jump ahead one more step though before code.

If no jQuery found, load it dynamically

If the jQuery object is not found, a new script element is created dynamically. The source is pointed to my local version of the script. Finally, it is appended to the head. Hopefully this will load the jquery. If it fails here, well then – the client has some issues!

This is the full inline javascript after the external javascript reference:

?View Code JAVASCRIPT
1
2
3
4
5
6
if (typeof jQuery == 'undefined') {
	var e = document.createElement('script');
	e.src = '/js/noncdn-jquery-1.3.2.js';
	e.type='text/javascript';
	document.getElementsByTagName("head")[0].appendChild(e);
}

In this case, the path http://mydomain.com/js/noncdn-jquery-1.3.2.js contains my local javascript.

The results?

Before this fix, I saw a failed jQuery load about once a day. I have not seen a single one yet. I have yet to see this error reported. If anyone finds a better way to do this, please let me know!

Trim down your content – it is a MUST

Friday, September 18th, 2009

A while ago, I was reading a usability book – and the author suggested that every time you create your content, remove half of the words. Then remove half of them again. So, by the time you’re done, you really have 1/4th of your content – and it should still make sense.

I didn’t really think this was that useful, until I made my first version of project I was developing called Where Is The Band (the picture on the left). As you can see, the general idea was the same, but it was very busy and verbose. The new version (the picture on the right) shows the exact same interface, but measurably less content.

This is how I did it:

Take out assumptions

Part of the extra wording I did was to explain “what would happen.” The hope is, however, that if a user is taking the time to sign up for your website, they already trust you enough to know that you’ll do those things you’ve promised. So, there is no need for me to spit out all of this information right away. (see: If you have a page, we’ll search for it! – they should trust that this happens already).

Trust Common Sense

Another area I was too verbose was the zip code box search. I realized that most people will know that a band is at a venue. Also, I planned on showing both results – as a combined search – here are venues near by with their associated bands. So, this new combo message worked better.

Elevator Pitch Ax

Elevator pitches in the real world are about 30 seconds max. In the web world, you have 3 seconds. Any longer than that, they move on. I imagined my elevator pitch – the part below the zip code search – as being my 3 main points said in one second each.

Value whitespace

In areas where I didn’t know what to cut, I decided I must have enough whitespace (or in this case, blue space). I then forced my words to work around that space that I had cut out.

Thesaurus.com and Lingo/Slang

Last but not least, check out the thesaurus. Also, from time to time, I used real words that people use – not the proper written words. This helped shorten the content.

The Examples

The left picture is the original design. The right picture is the trimmed version.

Rely on Google for your Javascript?

Thursday, February 26th, 2009

After reviewing the Google Javascript API project, I am torn. Pro’s and cons below… What do YOU think?

PRO

  • Proper caching done
  • Shared javascript location – no need to redownload if multiple sites use same library
  • Easy to include method, can be as specific as needed for versioning (you can include major, major.minor, etc.)

CON

  • If google goes down, you go down. Well, if caching is done right that doesn’t matter. Plus I’m sure you rely on your host not to go down either…
  • If google ends the service, like they shut down other services, you have to re-architect again.

So, are YOU going to use it?

Name CSS Classes More Descriptive

Thursday, October 30th, 2008

One thing I remember being pounded into my head is to not create CSS classes after their physical attributes. So, for example, if your error text is red, do not call the class red. Instead, be more descriptive of the content.

BAD!

1
.red { color: red }
1
<span class="red">There was an error!</span>

Instead, I was always encouraged to give the class something more descriptive, such as ‘error’.

GOOD!

1
.error { color: red; }
1
<span class="error">There was an error!</span>

Well, that seems pretty cut-n-dry for a simple example like that. However, in my most recent design, I’ve come across some more complex situations. For example, when you’re visiting the webpage, the background of an element might be a really dark grey. When you’re an authenticated user, however, I need it to be a medium grey (hey don’t ask – just wait for WhereIsTheBand.com to be done!).

Of course, during design, I went to the dark side right away:

BAD!

1
2
.darkGrey { color: #101011 }
.mediumGrey { color: #212122 }

Now, I know I should come up with some descriptive name, perhaps something like “userLoggedIn” or something, but I plan on using these classes in different areas as well. They might not be dependent on the user being logged in – just might look better that way. I didn’t want to make a lot of duplicate CSS code either.

The compromise: be semi descriptive.

COMPROMISE!

1
2
.lowContrastBackground { color: #101011 }
.mediumContractBackground { color: #212122 }

Not perfect, but seems like a better alternative.

Don’t focus me, bro!

Saturday, September 20th, 2008

I hate filling out login forms to discover that half of my password is in the username box. Lets talk about why – and then a solution.

Why?

Slow Loading Pages

Slow loading pages, or sites with a lot of content on the login page (see: a no-no for login pages), take a while to finish loading the content. The ‘onload’ handler is usually the whole on-load and not just the domloaded event. Tons of extra content delay the onload handler.

Dialup

Yes, people still have this. Even with the smallest amount of extra content, dialup users will experience some delay.

So what is happening?

People who jump the gun – like me (and 93% of everyone else) are clicking in the username box, filling it in, and then tabbing to the password box. While typing in the password, the page finally finishes loading, and focuses the username. We don’t notice, so we keep typing.

What is the solution

Quickly: activeElement

Firefox 3, and IE4+ support activeElement. (there are other ways around this for other browsers – see the end of this article). Check to see if the body is the active element – before focusing the username. If it is, means that they haven’t started typing anywhere.

Give me an example?

Ok! You should use a better ‘onload’ handler – but I’m being lazy just for this example.

?View Code JAVASCRIPT
1
2
3
4
5
6
function loginFormInit()
{
  if (document.activeElement == document.body) {
    document.getElementById('username').focus();
  }
}
1
2
3
4
5
6
7
8
<body onload="loginFormInit()">
<h1>Login</h1>
<form>
username: <input type="text" id="username" name="username" /><br />
password: <input type="password" id="password" name="password" /><br />
<input type="submit" />
</form>
</body>

Oh Noes! I need to support more than IE4 and FF3

No worries, citizen! If you need to support something else, besides those two lovely browsers, you could write a function to getElementsByTagName(‘input’) and add an onfocus element. That element could set a global variable to ‘true’. Finally, your onload function could check to make sure that that variable is not true – and then do the focus.

dtemplate: dynamic template system for static designed files

Tuesday, September 16th, 2008

One of the biggest time wasters I deal with is parsing out static web designs given to me by designers. They don’t know programming, so they design it with static HTML in mind. Even if you’re using a tool like dreamweaver, updating static pages can be a hassle. Then, a lot of times, they have to remove their ‘lorem ipsum’ text and send it to me – and then I continue to chop it up. Now, I’m talking about smaller 5 to 10 page sites here, not huge sites like JEMDiary or something. However, that idea birthed…

Welcome dtemplate!

The purpose of dtemplate was to read in an existing design from a designer or a static site that already exists, and make certain parts parse-able for replacement content. This way the designer can give the developer a complete xhtml package and move on. As long as the files are verified as valid xhtml, they’re good to go. Then the developer will write whatever programming/content needs to be replaced. It would be even possible for the designer to put basically all ‘lorem ipsum’ if necessary – and it could all be replaced.

How does it work?

dtemplate takes existing URLs and rewrites them to be used in the template. The template then reads in the xhtml files, looks for any specified IDs or classes, and replaces the content. It finally renders the content out to the screen. Any non .html file gets rewritten to be found in the new directory.

Implementation Steps

Its easy to put dtemplate into use. If all else fails, check out the comments in the files.

Create source directory

In order to have the content be read in by the template file correctly, you must make a new folder at the base of the site called dtemplate_sourcehtml. Move all of the files in the current root into that folder.

Modify .htaccess

The last line of the .htaccess file specifies the real URL of the site. In our example, its http://myrx8.local. You need to change this to be your site. Put this in the root of the site.

Add additional files

Place the dtemplate_controller.php, dtemplate folder and the verify folder in the root of the site.

Verify each xhtml file

Before surfing to the site, you should visit http://yoursite.com/verify and upload each file, and check for any id’s and classes that you’d like to replace. This way you know if the file will parse fine and if the required classes and IDs are located in the file.

Modify the dtemplate_build_content() function in dtemplate_controller.php

This function is made to replace any content for your file. It is commented – plus you can see an example in the download. It is recommended that you create your own class(es) and use this function only for adding the content to the template when needed – don’t place all your logic in this file.

Surf!

You should be good to go! If you want, you can remove the ‘verify’ folder.

Example

I’ve included a really simple frames website as an example with the download. This was originally on http://myrx8.local as a test.

Todo and Known Issues

- make sure you don’t have to edit out the website in .htaccess
- support multiple directories for html files.
- is pretty rewrite intensive.

The download

dtemplate.zip

  • twitter loader

Follow me on twitter: @aaronsaray

The views on this website are my own and do not reflect the opinions of my employer or clients.
Creative Commons License Home | Open Source | Book | Music | Art | Bio | Resume | Contact
My Baby