Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1631 lines (1535 sloc) 180 KB
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>Aaron K. Murray's Blog on software, dev life, and the Internet</title>
<meta name='description' content='AaronKMurray.com is a blog about software technology, developer life, and the Internet.'>
<meta name='author' content='Aaron K. Murray, akmurray@gmail.com, @aaronkmurray'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width'>
<link rel='icon' href='favicon.png' type='image/png'>
<link rel='stylesheet' href='css/blog-reset.css'>
<link rel='stylesheet' href='css/blog.css'>
<link rel='stylesheet' href='css/blog-logo.css'>
<link rel='stylesheet' href='css/sprites/blog-icons-all.css'>
<link rel='stylesheet' href='css/sprites/sprite-logo.css'>
<link rel='stylesheet' href='css/sprites/post-screenshot-thumbs-all.css'>
<link rel="stylesheet" href="css/gist-embed.css">
<script defer='true' type='text/javascript' src='js/XMLHttpRequest.2012.09.02.js'></script>
<script defer='true' type='text/javascript' src='js/prototype-extensions.js'></script>
<script defer='true' type='text/javascript' src='js/akm-math.js'></script>
<script defer='true' type='text/javascript' src='js/akm-util.js'></script>
<script defer='true' type='text/javascript' src='js/akm-gist.js'></script>
<script defer='true' type='text/javascript' src='js/akm-blog.js'></script>
<script defer='true' type='text/javascript' src='js/akm-blog-post-29.js'></script>
</head>
<body>
<div id='wrapper-body'>
<div id='wrapper-site-header'>
<div id='wrapper-site-header-words'>
<h1>Aaron K. Murray's Blog</h1>
<h2>Purpose: Show the world how to build a complete website starting with a single index.html page</h2>
</div>
<div id='wrapper-site-header-icons'>
<a href='http://aaronkmurray.com/feeds/feed-rss.xml' target='_blank' title='Subscribe via RSS'><img src='img/blog/clear.gif' class='img-icon-rss-32' alt='RSS icon'></a>
<a href='https://twitter.com/aaronkmurray' target='_blank' title='Follow me on Twitter @aaronkmurray'><img src='img/blog/clear.gif' class='img-icon-twitter-32' alt='Twitter icon'></a>
<a href='https://github.com/akmurray' target='_blank' title='View the code for this site on GitHub'><img src='img/blog/clear.gif' class='img-icon-github-32' alt='GitHub icon'></a>
</div>
<div id='wrapper-logo'>
<div id='logo-cube' class='show-side-1'>
<figure class='side-2'><img src='img/blog/clear.gif' class='logo img-logo-2-128' alt='site logo'></figure>
<figure class='side-3'><img src='img/blog/clear.gif' class='logo img-logo-3-128' alt='site logo'></figure>
<figure class='side-4'><img src='img/blog/clear.gif' class='logo img-logo-4-128' alt='site logo'></figure>
<figure class='side-5'><img src='img/blog/clear.gif' class='logo img-logo-5-128' alt='site logo'></figure>
<figure class='side-6'><img src='img/blog/clear.gif' class='logo img-logo-6-128' alt='site logo'></figure>
<figure class='side-1'><img src='img/blog/clear.gif' class='logo img-logo-1-128' alt='site logo'></figure>
</div>
</div>
</div>
<!--
images for future posts:
/img/blog/posts/post-x-dev-tools-http-req-js-one-by-one.jpg
/img/blog/posts/post-x-dev-tools-http-req-js-loader.jpg
/img/blog/posts/post-x-dev-tools-http-req-js-concat.jpg
-->
<div id='wrapper-blog-posts'>
<!-- Someday we'll have a database for these posts and I won't need this copy/paste template :) -->
<!--
<article class='blog-post' id='blog-post-?????'>
<div class='blog-post-header'>
<h2>Post ?????: </h2>
<span class='commit-link'><a href='#' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github' /></a></span>
</div>
<div class='blog-post-body'>
<p>
<p>
<h3></h3>
<p>
<p>
<h3></h3>
<p>
<p>
<figure>
<img src='img/blog/posts/post-?????-.jpg' alt=''>
<figcaption></figcaption>
</figure>
<p>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'></span>, <span class='post-tag'></span>, <span class='post-tag'></span></span>
<span class='post-timestamp'>?</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-?????.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-?????-thumb-100' alt='Screenshot of site after post #?????' /></a></span>
</div>
<div class='blog-post-guid'></div>
</article>
????? REMINDER for Mr. No Database: Add an entry to the Posts section of the menu on the right
-->
<article class='blog-post' id='blog-post-29'>
<div class='blog-post-header'>
<h2>Post 29: Understanding Javascript Numbers</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/170f2a329d50c8b7559f88cdafdf54da5cb99838' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Javascript is a great scripting language. It is simple to learn, (obviously) runs in a browser for quick development tests, and is flexible enough to allow for some powerful code to be created. That flexibility does come at a cost however.
<p>One of the confusing aspects of Javascript is type coercion and what that means with respect to dealing with numbers. The problem is not that Javascript is flaky, it is that there are more rules to understand when dealing with a loosly-typed scripting language than a compiled language like C.
<h3>Enough horseplay, show me examples</h3>
<p>Let&#39;s make a simple function that takes a string and left-pads it with zeroes to a certain number of places.
<p><pre class='code'>
function zeropad(text, numPlaces) {
while(text.length < numplaces)
text = &quot;0&quot; + text;
return text;
} </pre>
<p>Here is the output with various inputs:
<p><pre class='code'>
//Output that I expected
zeropad(&quot;foo&quot;, 5); //returns <span style='color:green'>&quot;00foo&quot;</span>
zeropad(&quot;foo&quot;, 1); //returns <span style='color:green'>&quot;foo&quot;</span>
zeropad(&quot;123&quot;, 7); //returns <span style='color:green'>0000123</span>
zeropad(&quot;$19.99&quot;, 7); //returns <span style='color:green'>&quot;0$19.99&quot;</span>
//Output that I might not have expected, or that is a case that I did not plan for
zeropad(123, 7); //returns <span style='color:orange'>123</span>
zeropad(234.56, 7); //returns <span style='color:orange'>234.56</span>
zeropad(false, 7); //returns <span style='color:orange'>false</span>
zeropad([], 7); //returns <span style='color:orange'>&quot;0000000&quot;</span>
zeropad([1], 7); //returns <span style='color:orange'>&quot;0000001&quot;</span>
zeropad([1,2,3], 7); //returns <span style='color:orange'>&quot;001,2,3&quot;</span>
zeropad({}, 7); //returns <span style='color:orange'>&quot;Object {}&quot;</span>
zeropad(new Function(), 7); //returns <span style='color:orange'>&quot;0function anonymous() { }&quot;</span>
//Exceptions thrown
zeropad(null, 7); //returns <span style='color:red'>TypeError: Cannot read property &quot;length&quot; of null</span>
zeropad(undefined, 7); //returns <span style='color:red'>TypeError: Cannot read property &quot;length&quot; of undefined</span>
</pre>
<p>This illustrates type coercion in action. You can see from the results that the <code>text</code> argument can actually be any type, and the way that variable gets handled when being added to a string is different.
<p>Strings behave as expected with zeroes simply being prepended. Numbers will actually coerce the &#39;0&#39; into a Number however, and result in the value of <code>text</code> never actually changing. Other types behave more-or-less as expected with the exception perhaps being arrays. Since the coercion process will call <code>.toString()</code> on the object, arrays will return a comma-delimited string when this happens, and an empty array will return an empty string, which will then have zeroes prepended to it.
<h3>Rounding Numbers</h3>
<p>There are many times when whole numbers are needed to be parsed from user input. Tax forms are a good example of this. The government does not care much about pennies on tax forms so they want everything in whole dollars. There are many ways to do this in Javascript. Given a number <code>x</code>, we could use:
<ul>
<li><code>Math.round(x)</code> //round to closest whole number</li>
<li><code>Math.ceil(x)</code> //round up</li>
<li><code>Math.floor(x)</code> //round down</li>
<li><code>parseInt(x)</code> //parse an int from any type</li>
<li><code>x.toFixed(0)</code> //trim the fractional portion from a known number type</li>
<li><code>x|0</code> //bitwise OR with 0 which converts x to an int first and returns x</li>
<li><code>x.toString()</code> with substring math...the list goes on and on</li>
</ul>
<p>Here is a grid showing the results of these methods applied to various types and values as inputs, as well as a few custom toInt() methods I wrote for the <code>akm.math</code> lib:
<p><div id='blog-post-29-output'></div>
<p>As you can see from the grid, the results from using these different methods varies based on the data type of the input. The only (built-in) reliable method that will return an actual Number type with a useful (non-NaN) value is &quot;bitwise OR zero&quot; (x|0).
<p>The <code>akm.math</code> functions I solve the problem of both always wanting to return a useful Number, and also have somewhat intelligent parsing of values that include spaces, commas, and dollar signs. Unlike the results returned by parseInt, ex: <code>parseInt('123,456') === 123</code>
<p>Other important notes that may not be obvious:
<ul>
<li><code>typeof NaN === 'number'</code> //NaN is a numeric type...just not a known number</li>
<li><code>(NaN != NaN) === true</code> //one NaN may not be equal to another NaN...even itself. NaN is basically an unknown number</li>
<li><code>isNaN(parseInt(Infinity)) === true</code> //parseInt(Infinity) returns NaN, not Infinity</li>
<li>Not all browsers render these results the same. Especially <code>parseInt()</code>. The default &#39;base&#39; value is changing from 8 to 10</li>
</ul>
<p>Working with numbers in Javascript can be frustrating at times. Understanding the data types that you will be working with and what options you have for conversion will help you make good decisions up front and reduce the headache from seemingly random input bugs months after you developed that webform (or game engine).
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>javascript</span>, <span class='post-tag'>math</span>, <span class='post-tag'>rounding</span></span>
<span class='post-timestamp'>Posted on May 24, 2013 @ 12:30PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-29.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-29-thumb-100' alt='Screenshot of site after post #29'></a></span>
</div>
<div class='blog-post-guid'>db9dbec9-4f04-4357-808e-2a0a71709eaa</div>
</article>
<article class='blog-post' id='blog-post-28'>
<div class='blog-post-header'>
<h2>Post 28: CSS Preprocessing using SASS</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/be8daa61dd6d8dcee80ecf9045a7cad8f31ebb54' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>It feels like it has been an eternity since I posted last. Turns out that 3 months have gone by - wow! Let&#39;s get to it.
<p>This post is on a topic that has been on my mind for a while to talk about here: <a href='http://en.wikipedia.org/wiki/Preprocessor' target='_blank' rel='nofollow'>Preprocessing</a>. Specifically for this post, I will cover CSS Preprocessing using <a href='http://sass-lang.com/' target='_blank' rel='nofollow'>SASS</a>, but the concept can and should be applied to much more than just CSS.
<h3>What is CSS Preprocessing?</h3>
<p>Put simply, CSS preprocessing is a way that we can write css-like code, run it through a converter, and then get actual css output. Doing this adds an extra step between writing css, and seeing the results in a browser, but there are some excellent benefits.
<h3>What are the benefits?</h3>
<p>In my view, there are a couple of major benefits to using a preprocessor over writing the raw code: convenience and abstraction.
<p>On the convenience front, simple things like the ability to use variables for colors and fonts is worth the cost of admission on big projects. This is available now without having to wait for the W3C to figure out the final spec and then rely on your target audience to update their browsers to the latest versions.
<figure>
<img src='img/blog/posts/post-28-sass-variables.png' alt='Example using SASS variables'>
<figcaption>Example using SASS variables</figcaption>
</figure>
<p>More powerful though is the ability to deal with an abstraction layer that better enables you to express your <em>intentions</em> instead of the solely functional bits that make browsers do your bidding.
<h3>Ugh, still not convinced. Can you give me an example?</h3>
<p>Computers run by processing <a href='http://en.wikipedia.org/wiki/Binary_code' target='_blank' rel='nofollow'>binary code</a>. Only 1s and 0s. Writing anything beyond simple math equations is madness. Quickly humans realized they needed a way to write code more efficiently, thus <a href='http://en.wikipedia.org/wiki/Assembly_language' target='_blank' rel='nofollow'>assembly language</a> is born. Instead of figuring out the exact binary code that a processor needs to run, we could write code that looked slightly less cryptic. Code that captured the intent of the programmer better.
<p>This pattern continues and we get <a href='http://en.wikipedia.org/wiki/C_(programming_language)' target='_blank' rel='nofollow'>higher</a> <a href='http://en.wikipedia.org/wiki/C%2B%2B' target='_blank' rel='nofollow'>level</a> <a href='http://en.wikipedia.org/wiki/C_Sharp_(programming_language)' target='_blank' rel='nofollow'>languages</a> as a result. The code gets more abstracted from how it actually runs on the processor, and programmers become more efficient and can express themselves more easily. Another benefit is that compilers are created and most of the time that higher level code can be run on many different processors instead of having to write code specific to each one, like the old days.
<figure>
<img src='img/blog/posts/post-28-binary-wormhole.jpg' alt='Binary wormhole'>
</figure>
<h3>Writing raw CSS is like writing binary code for styling</h3>
<p>15 years ago, the simple act of using a stylesheet in a website was an advanced technique. Windows accounted for nearly all of the browser-based web traffic. Most users had a <a href='img/blog/posts/post-28-monitor-resolutions.png' target='_blank' rel='nofollow'>monitor that had 4:3 aspect ratio</a> so we simply targeted a &quot;safe&quot; width for our sites. We primarily struggled with two very different browsers and got used to hacking our styles in order to get our sites looking decent in both browsers. Folks were only using our site from computers that had a keyboard and mouse. People still used modems to tie up their phone lines in order to connect to the internet. Dev life was simpler.
<p>As new browsers gained favor with the masses, our stylesheets were amended to accomodate the newcomers. Sadly we were so heads-down focused on getting work done that we missed the massive wrong turn we were taking. We just got used to making specific hacks that addressed some issue in some combination of os-browser-resolution-bandwidth-input. We tried so hard to make every single page work for all combinations that we just ended up chasing the wrong paradigm. The paradigm that said we should be able to keep up with the ever-growing matrix of ways users could use our sites; that a good developer should be able to learn every hack for every bug that the collective developer &quot;we&quot; ran across.
<h3>It is time to level-up</h3>
<p>In order to keep up with expanding requirements, we need to get out of the code weeds and outsource some of our efforts to the machines at our fingertips. Ideally we would use some sort of higher level language or tool across our entire web development chain so that we can gain access to new language features while reducing our efforts. This will also help us bring a great experience to all of our users instead of endlessly shovelling the lowest common denominator at them.
<h3>Other ways to use preprocessors</h3>
<p>If you have a fairly simple static content site, and you don&#39;t have or want a build step to run between modifying your CSS and viewing it in a browser, look into setting up <a href='https://github.com/krschmidt/SassWatcher' target='_blank' rel='nofollow'>file</a> <a href='http://www.sublimetext.com/forum/viewtopic.php?f=2&t=8975#p36442' target='_blank' rel='nofollow'>system</a> <a href='http://stackoverflow.com/questions/11901067/auto-compile-scss-files-in-sublime-text-2' target='_blank' rel='nofollow'>watchers</a> that can run the preprocessing step every time to modify a file.
<p>You can also check out the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/js-css/preprocessor' target='_blank' rel='nofollow'>SASS preprocessor</a> tool that I wrote for this post. I wanted something that:
<ul>
<li>could be run from the command line</li>
<li>didn&#39;t require Ruby to be installed</li>
</ul>
<p>It is simple and gets the job done. I will add to it later as we start preprocessing more than just CSS.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>preprocessing</span>, <span class='post-tag'>css</span>, <span class='post-tag'>sass</span></span>
<span class='post-timestamp'>Posted on March 7, 2013 @ 5:12PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-28.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-28-thumb-100' alt='Screenshot of site after post #28'></a></span>
</div>
<div class='blog-post-guid'>5a5f7a07-b185-494f-b5cb-38dc0ec758ad</div>
</article>
<article class='blog-post' id='blog-post-27'>
<div class='blog-post-header'>
<h2>Post 27: Build-time CSS Validation</h2>
<span class='commit-link'><a href='#https://github.com/akmurray/aaronkmurray-blog/commit/1466086faba5b80ca0b61bc89fd8d8b5c27f650f' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>One of the nice things about working with <a href='http://en.wikipedia.org/wiki/Compiled_language' target='_blank' rel='nofollow'>compiled programming languages</a> like C# or C++, compared to an <a href='http://en.wikipedia.org/wiki/Interpreted_language' target='_blank' rel='nofollow'>interpreted language</a> like Javascript, is the benefit of having the compiler automatically notify the programmer when there are glaring syntactical errors in the code. Similarly, most compilers can also notify the programmer when there are potential errors or suspect code; these notifications are called <a href='http://www.cprogramming.com/tutorial/compiler_warnings.html' target='_blank' rel='nofollow'>warnings</a>.
<p>This benefit of having a compiler act as a second set of eyes on the code that you write is great. Little things like gross typos can be caught immediately, as well as more subtle warnings, can be corrected before your code ever gets out into the wild.
<h3>That is great...but I work on the web</h3>
<p>So what use are these fancy compilers when web pages are made up of markup and script? The nature of web browsers since the very beginning has been to &quot;just figure it out&quot; when it comes to parsing malformed HTML and CSS. Because HTML was largely hand-written in the old days it was often filled with a variety of errors. Browsers were vying to provide the best user experience, so they started trying to parse the &quot;intent&quot; of the HTML in addition to taking it character-for-character. Some examples of subtle typos with potentially major rendering impacts:
<ol>
<li><code>&lt;div&gt;Just some &lt;span&gt;simple&lt;/div&gt;text here&lt;/span&gt;</code></li>
<li><code>&lt;ul&gt;&lt;li&gt;item 1&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;item 2&lt;/li&gt;</code></li>
</ol>
<p>In example #1, it looks like the <code>DIV</code> and <code>SPAN</code> were accidentally swapped. The effect is that the <code>DIV</code> is closed in the middle of the the <code>SPAN</code>. What should the browser do?
<p>In example #2, it appears the programmer closed that <code>UL</code> too early, or added the second <code>LI</code> later and in the wrong place. Should the browser still show that <code>LI</code> in normal bullet formatting?
<p>These are contrived examples, but they are some of the simplest and illustrate the point that parsing can be tricky. Even the mighty Yahoo with so much focus on browser-related technology has trouble getting it right. Simply running the <a href='http://validator.w3.org/check?uri=www.yahoo.com' target='_blank' rel='nofollow'>yahoo.com homepage through the w3c markup validation service</a> exposes 200 errors. Many of these errors are considered &quot;acceptable&quot; by web developers today, but it further proves the point that our human instincts and the strict rules that computer parsers follow often disagree.
<h3>Another pair of eyes: CSSLint</h3>
<p>In previous posts I&#39;ve shown how to get some build-time validation on <a href='#post-16'>HTML</a> and <a href='#post-25'>Javascript</a>, so now I will show you how to use <a href='http://csslint.net/' target='_blank' rel='nofollow'>CSSLint</a> to add an automated validation step for CSS.
<p>By default CSSLint is a little too overzealous in my opinion. The rules it applies when parsing your CSS blur the line between coding practices that should be avoided, and political opinions for how CSS should be structured. I won&#39;t go into detail about each rule that CSSLint evaluates, but you can take a look at my build script parameters to see which rules I think are completely bogus, as well as which rules are worthy of noting, but not worthy of failing a build over (warnings).
<p>To run CSSLint from the command line or in a batch file, you need to hava <a href='http://www.java.com/en/download/index.jsp' target='_blank' rel='nofollow'>Java</a> installed, and download Rhino and css-lint for Rhino. I recommend you <a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/build' target='_blank'>download those from my GitHub repository</a> because the latest Rhino build (<a href='https://developer.mozilla.org/en-US/docs/Rhino' target='_blank' rel='nofollow'>1.7R4</a>) has a bug that will keep this example from working properly. Here is an example command line that you can run from the build directory (assuming you have Java 7 in the same location that I do):
<p><code>"C:\Program Files (x86)\Java\jre7\bin\java" -jar rhino.jar csslint-rhino.js --ignore=ids ../../aaronkmurray-blog/css/</code>
<p>What that code does is:
<ul>
<li>Tell Java to execute the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/rhino.jar' target='_blank' rel='nofollow'></a>rhino.jar file</li>
<li>Tell Rhino to execute the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/csslint-rhino.js' target='_blank' rel='nofollow'>csslint-rhino.js</a> file</li>
<li>Tell Rhino to <a href='https://github.com/stubbornella/csslint/wiki/Command-line-interface' target='_blank' rel='nofollow'>ignore the id rules</a></li>
</ul>
<figure>
<img src='img/blog/posts/post-27-csslint-output.png' alt='Example CSSLint output shown in a text file'>
<figcaption>Example CSSLint output shown in a text file</figcaption>
</figure>
<p>Take a look at my <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat' target='_blank' rel='nofollow'>build script</a> for a more detailed example.
<h3>The Takeaway</h3>
<p>You may have noticed by now that my blog posts cycle between practial web development advice, automated developer tooling, technical implementations, and performance tuning. My goal in this is to provide a well rounded look at the major components necessary in creating software.
<p>It is important for the developer:
<ul>
<li>to understand the software technology they are using (theory)</li>
<li>to understand how that software works at the machine level (practice)</li>
<li>to leverage to test and prove that their software works (test/reliability)</li>
<li>to ensure that software doesn&#39;t waste the time of humans (performance)</li>
<li>to automate repetitive tasks in order to save time and reduce errors (consistency)</li>
</ul>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css</span>, <span class='post-tag'>csslint</span>, <span class='post-tag'>build</span>, <span class='post-tag'>java</span>, <span class='post-tag'>rhino</span></span>
<span class='post-timestamp'>Posted on December 10, 2012 @ 10:30AM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-27.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-27-thumb-100' alt='Screenshot of site after post #27'></a></span>
</div>
<div class='blog-post-guid'>43c3c727-4b18-44be-b1e8-0119485bb5d7</div>
</article>
<article class='blog-post' id='blog-post-26'>
<div class='blog-post-header'>
<h2>Post 26: Reduce HTTP Requests</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/e0f24761e92c0330c42a16b75838087fa86b640d' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>The performance lesson in this post gets to the very core of creating sites that feel snappy for the user.
<h3>Background</h3>
<p>Each time a user hits a web page to view it, the server will typically send back a response in HTML. This initial HTML response almost never contains then complete &quot;page&quot; content as the user thinks of it.
<p>Instead, a subset of content is sent back, along with a lot of other information that tells the browser where to find the rest of the data needed to display the page. This linked data is for things like:
<ul>
<li>Images</li>
<li>CSS Files</li>
<li>Javascript Files</li>
</ul>
<p>There can be a lot of these file linked from the HTML. As an example, I hit the Amazon homepage and saw a whopping 220 requests accounting for 1.97MB of data, and 3.31 seconds of load time.
<figure>
<img src='img/blog/posts/post-26-amazon-requests.png' alt='Chrome developer tools view of Amazon homepage requests'>
<figcaption>Amazon homepage requests as seen in Chrome Developer Tools</figcaption>
</figure>
<p>Of those 220 requests, the breakdown is as follows:
<ul>
<li>175 Images</li>
<li>9 CSS Files</li>
<li>11 Javascript Files</li>
</ul>
<p>Despite a staggering 175 image requests, they are actually using quite a few <a href='#blog-post-20'>CSS Sprites</a>. Without these efforts, they'd probably have closer to 500 http requests on the home page.
<h3>The Test: Measuring Request Overhead as Experienced by the User</h3>
<p>I made 2 simple test pages to compare the effect of http requests. <a href='sandbox/test-http-request/test-http-request-without-sprite.html' target='_blank' rel='nofollow'>One page has 100 small images included individually</a>, and <a href='sandbox/test-http-request/test-http-request-with-sprite.html' target='_blank' rel='nofollow'>the other page has 1 CSS Sprite</a> that is used 100 times to show the same 100 images (created using my <a href='#blog-post-20'>imgsprite</a> tool).
<p>Here are the request summaries for each test page as see in Chrome:
<figure>
<img src='img/blog/posts/post-26-100-images-without-sprite.png' alt='100 separate image requests'>
<figcaption>100 separate image requests</figcaption>
</figure>
<figure>
<img src='img/blog/posts/post-26-100-images-with-sprite.png' alt='1 big CSS sprite for 100 images'>
<figcaption>1 big CSS sprite for 100 images</figcaption>
</figure>
<p>In the test you can see that using 1 big sprite for 100 images dropped the request count by 98 (1 image for the sprite, 1 image for the clear.gif vs 100 unique images).
<p>The sprite html size was 26KB compared to 4KB for the page with individual images, due to the extra css required to make the sprites work.
<p>The page with the sprite loaded in 132ms compared to 384ms on the page with individual images. That is a massive difference in time for equivalent content implemented differently.
<h3>Reduce HTTP Requests (even at the expense of bandwidth)</h3>
<p>Why such a big difference? Well, the simple answers is that each HTTP request has a lot of components that take time. Once the request is agreed upon by the browser and the server, sending the data down to the client can commence at speed.
<p>I want to illustrate this a different way. For example, take this snippet of request timing from my homepage:
<figure>
<img src='img/blog/posts/post-26-image-request-timeline.png' alt='Time spent receiving images of various sizes'>
<figcaption>Time spent receiving images of various sizes</figcaption>
</figure>
<p>There are a variety of image sizes being downloaded in this snapshot, but the interesting part is comparing the actual time spent downloading the data for images of various sizes. I drew arrows pointing to the largest and smallest image in the snapshot: 83KB vs 3KB. The time spent receiving the 83KB image was 30ms, whereas the time spent receiving the 3KB image was 20ms. You can partly see from that figure that the other images all took a relatively similar amount of time to download.
<p>This further shows the relative impact of the <a href='http://stackoverflow.com/questions/3613989/what-of-traffic-is-network-overhead-on-top-of-http-s-requests' target='_blank' rel='nofollow'>HTTP request overhead</a> and the data delivered. Unless you are serving very large data files (high resolution images, movies, eBook PDFs, etc), a sizeable percentage of request time will be in simply getting the request prepared and negotiated between the two end computers.
<p>For most sites, the takeaway here is that continuous effort should be given to reducing the number of requests that are made, especially as sites grow and get new features added.
<h3>And Finally, an Example</h3>
<p>In <a href='#post-19'>Post 19</a> I added a little flair to the site in the form of a rotating cube of various avatar images. That was originally done using 6 different images. Here is how I used my <a href='#blog-post-20'>imgsprite</a> tool to make a single sprite and shave 5 HTTP requests.
<figure>
<img src='img/blog/posts/post-26-cmd-imgsprite-logo.png' alt='Command line commands for creating and compressing the site logo sprite'>
<figcaption>Command line commands for creating and compressing the site logo sprite</figcaption>
</figure>
<p>First, from the build directory (for convenience), create the sprite out of the 6 images ending in &quot;-128.png&quot;, and set the relative path for the sprite image based on where it will end up in the web project (paths like this will be better in the future):
<p><code>imgsprite.exe<br>&nbsp;-in:..\..\aaronkmurray-blog\img\blog\logo\*-128.png<br>&nbsp;-img-out:sprite-logo.png<br>&nbsp;-css-out:sprite-logo.css<br>&nbsp;-css-class-name-prefix:img- <br>&nbsp;-image-deploy-url-base:../../blog/sprites/</code>
<p>Then simply run the image compressor. Since it is in the build directory and the only image in there is the new sprite...no command line args are necessary:
<p><code>imgsqz.exe</code>
<h3>In Closing</h3>
<p>Some of you already knew that reducing HTTP requests <a href='http://www.die.net/musings/page_load_time/' target='_blank' rel='nofollow'>was</a> <a href='https://developers.google.com/speed/docs/best-practices/request' target='_blank' rel='nofollow'>beneficial</a>, but now you know what kind of an impact these changes can have.
<p>Summary:
<ul>
<li>Favor eliminating an http request over reducing filesize (do not be afraid of sprites that have filesizes larger than the sum of each image)</li>
<li>Pack images, javascript, and css into sprites/bundles where possible</li>
<li>Stay tuned for a post that shows how to bundle files, along with the pitfalls to watch out for when doing so</li>
</ul>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>performance</span>, <span class='post-tag'>http requests</span>, <span class='post-tag'>css sprites</span>, <span class='post-tag'>amazon</span></span>
<span class='post-timestamp'>Posted on December 7, 2012 @ 4:37PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-26.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-26-thumb-100' alt='Screenshot of site after post #26'></a></span>
</div>
<div class='blog-post-guid'>d73b6264-7bbf-4baa-98c8-f227afffb444</div>
</article>
<article class='blog-post' id='blog-post-25'>
<div class='blog-post-header'>
<h2>Post 25: Automated Javascript Unit Tests</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/7670721b64acaa3c87b3d8f8e71cd6e2f44f71b0' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>First order of business - apologies for such a long time between posts. I did the code changes for this post 5 weeks ago and then got hammered by a 2-week flu, and tons of work getting <a href='http://www.buildasign.com' target='_blank'>BuildASign</a> prepared to finish out the holiday season.
<p>In modern websites, more and more of the &quot;logic and code&quot; of a site is being moved to the client. There are 2 primary benefits to doing this:
<ul>
<li>Improve responsiveness for users</li>
<li>Reduce load on servers</li>
</ul>
<p>As this code moves from the servers to the client, we run into greater risk with respect to ensuring that our sites work the way they are intended to.
<figure>
<img src='img/blog/posts/post-25-unit-testing-comic-jesuswasrasta.jpg' alt='Unit Testing can be scary and hard'>
<figcaption>Unit Testing can be scary and hard</figcaption>
</figure>
<h3>Unit Testing</h3>
<p>For the server code, <a href='http://en.wikipedia.org/wiki/Unit_testing' target='_blank' rel='nofollow'>unit testing</a> is a common way to execute code automatically to reassure humans that it is behaving properly.
<p>This is much trickier on the client side for a few reasons:
<ul>
<li><a href='http://javascript.info/tutorial/browser-environment' target='_blank' rel='nofollow'>Browser environments</a> differ from each other</li>
<li>Browser <a href='http://en.wikipedia.org/wiki/JavaScript_engine#JavaScript_engines' target='_blank' rel='nofollow'>Javascript engines</a> differ from each other</li>
<li>Instrumenting a browser to automatically &quot;do stuff&quot; is harder than it sounds</li>
</ul>
<h3>qUnit, Selenium, Test Project ... not 100% reliable</h3>
<p>In the past, I&#39;ve used various means of unit testing my javascript code to make sure that it works as I say it does. My goto combo was using a <a href='http://msdn.microsoft.com/en-us/library/ms182470(v=vs.100).aspx' target='_blank' rel='nofollow'>Visual Studio.NET test project</a> that fired up different versions of the browsers that I wanted to test using <a href='http://seleniumhq.org/' target='_blank' rel='nofollow'>Selenium</a>, and then have those instances run though a series of test webpages that used <a href='http://qunitjs.com/' target='_blank' rel='nofollow'>qUnit</a> to run the javascript code. Selenium would check to see if all of the tests ran successfully, and either pass or fail the test.
<p>While this approach worked fairly well from the test project and qUnit perspective, having Selenium reliably control all of the browsers was slightly painful. There is a helpful <a href='http://seleniumhq.org/projects/ide/' target='_blank' rel='nofollow'>browser plugin for Firefox</a> that assists in creating the tests, but that ended up being the least of the challenges. Things like Alert and Confirm promts, SSL cert warning pages, and unreliable event triggers made false test failures common enough to not trust the fail results. And the tests took quite a while to run.
<h3>PhantomJS, Jasmine, command line ... fast, but limited</h3>
<p>A <a href='http://loremipsumfoobar.com/' target='_blank' rel='nofollow'>colleague of mine</a> mentioned liking <a href='http://pivotal.github.com/jasmine/' target='_blank' rel='nofollow'>Jasmine</a> and <a href='http://phantomjs.org/' target='_blank' rel='nofollow'>PhantomJS</a> to run javascript tests from the command line. There are pros and cons to this approach, but the combination of running a headless browser (no visual component - just the engine) from the command line meant that many of the &quot;random&quot; behavior that broke my Selenium tests could potential go away.
<p>In practice, the promise of reliable tests using a headless browser seems fulfilled by PhantomJs. The major downside is that we're only testing the Javascript in 1 browser/engine combination (<a href='http://www.webkit.org/projects/javascript/index.html' target='_blank' rel='nofollow'>WebKit</a>/<a href='http://trac.webkit.org/wiki/JavaScriptCore' target='_blank' rel='nofollow'>JavaScriptCore</a>). Until we get headless browsers that reflect the mainstream browser usage, this approach won't be ideal. We'll still need to use tools (like <a href='http://www.telerik.com/automated-testing-tools/html-testing.aspx' target='_blank' rel='nofollow'>Telerik's Test Studio</a> and <a href='http://www.browserstack.com/' target='_blank' rel='nofollow'>BrowserStack</a>) for robust cross-browser automated testing, but for now on a small project, we can get near-instant feedback on broken javascript tests during our build process, which is much better than nothing.
<h3>Setting it up</h3>
<ol>
<li><a href='http://phantomjs.org/download.html' target='_blank' rel='nofollow'>Download PhantomJS</a> and <a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/build' target='_blank' rel='nofollow'>place it in the build folder</a></li>
<li><a href='https://github.com/pivotal/jasmine/downloads' target='_blank' rel='nofollow'>Download Jasmine</a> and <a href='https://github.com/akmurray/aaronkmurray-blog/tree/master/test/jasmine-standalone-1.2.0' target='_blank' rel='nofollow'>place it in the web site test folder</a></li>
<li>Edit the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/commit/e56a5f4e25b41fa531845e8f545e25956219b962' target='_blank' rel='nofollow'>build script to call PhantomJS</a>, pointing at tests we want to run</li>
<li><a href='https://github.com/akmurray/aaronkmurray-blog/tree/master/test/jasmine-standalone-1.2.0/spec' target='_blank' rel='nofollow'>Write some tests</a> (aka specs)</li>
<li>Run the build script and it will halt if there are errors</li>
</ol>
<h3>What this means</h3>
<p>Now that we have some basic code coverage, editing the javascript code for the site can be done with a little less worry about breaking something else (aka <a href='http://en.wikipedia.org/wiki/Regression_testing' target='_blank' rel='nofollow'>regression</a> errors). This will be much more important as the site starts to break up into many pieces. Most people like the time and fortitude to go back over every piece of functionality ever written after each change. Luckily we have computers that can do that for us...we simply have to tell them how to do it.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>unit test</span>, <span class='post-tag'>testing</span>, <span class='post-tag'>build</span>, <span class='post-tag'>PhantomJS</span>, <span class='post-tag'>qUnit</span>, <span class='post-tag'>Jasmine</span>, <span class='post-tag'>Telerik</span>, <span class='post-tag'>BrowserStack</span>, <span class='post-tag'>command line</span>, <span class='post-tag'>javascript</span></span>
<span class='post-timestamp'>Posted on November 26, 2012 @ 12:15PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-25.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-25-thumb-100' alt='Screenshot of site after post #25'></a></span>
</div>
<div class='blog-post-guid'>22badcaa-5d89-4976-affe-4fa8c2cd25b8</div>
</article>
<article class='blog-post' id='blog-post-24'>
<div class='blog-post-header'>
<h2>Post 24: SEO Part 4/4: Tracking SEO Results</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/07289ae7ca946a600fbded3a04d5ef1922eb230d' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p><em>This post is the last post in a 4-part series on SEO written by guest author <a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a> who runs the blog <a href='http://ppcwithoutpity.com/' target='_blank'>ppcwithoutpity.com</a>. If you haven&#39;t already, check out <a href='#blog-post-14'>Part 1: Getting Indexed</a>, <a href='#blog-post-18'>Part 2: Optimizing Code Tags For SEO</a>, and <a href='#blog-post-21' target='_blank' rel='nofollow'>Part 3: Linkbuilding</a>.</em>
<div class='guest-post-content'>
<h3>Tracking SEO Results</h3>
<p>Now that you know the basics of how to improve your organic search ranking, you&#39;ll need a way to track your site&#39;s results in the search engine results pages (SERPs). There are many tools that perform this function. Some are free, and some cost money. First, let&#39;s cover the free tools.
<h3>Google Analytics</h3>
<p>You should already be using <a href='www.google.com/analytics/' target='_blank' rel='nofollow'>Google Analytics</a> to track your site traffic. And you should already have created a <a href='https://www.google.com/webmasters/tools/' target='_blank' rel='nofollow'>Google Webmaster Tools</a> account (covered in SEO Post #1). If you have both of these enabled, you can track organic search queries and ranking to your site.
<p>To view your SEO ranking, just log in to your Google Analytics account and go to Traffic Sources &gt; Search Engine Optimization &gt; Queries:
<figure>
<img src='img/blog/posts/post-24-pic-1.jpg' alt='Google Analytics Menu: Search Engine Optimization, Queries'>
<figcaption>Google Analytics Menu: Search Engine Optimization, Queries</figcaption>
</figure>
<p>Note: if this is your first time looking at this report, you may be prompted to link your Google Analytics and Google Webmaster tools accounts. Try to do this as soon as you have both accounts so that you can start collecting historical data on your SEO performance.
<p>In this report, you can view specific queries that users typed in to reach your site, the average position on Google that your result appeared, and total clicks, impressions, and click-through rate of the traffic driven by that query in the date range of your report.
<figure>
<img src='img/blog/posts/post-24-pic-2.jpg' alt='Google Analytics SEO Query report example'>
<figcaption>Google Analytics SEO Query report example</figcaption>
</figure>
<p>This report is pretty handy, but has two major drawbacks. One, it only shows ranking for searches on Google. You could be ranking well on Bing, Ask, or another search engine and you would never know it. And two, it only shows you stats on keywords you&#39;re already ranking for. This could be a problem if you have some specific keywords that you&#39;re not currently ranking for, and you need to keep tabs on them.
<h3>SEO Book&#39;s Rank Checker</h3>
<p>This next tool is my favorite free rank checking tool. It&#39;s put out by SEO Book, who also makes the super-handy SEO Book toolbar I mentioned in the last SEO post. Rank Checker is a Firefox extension that you can download here: <a href='http://tools.seobook.com/firefox/rank-checker/' target='_blank' rel='nofollow'>http://tools.seobook.com/firefox/rank-checker/</a>.
<p>Once you install this tool, you can click on the icon in your Firefox browser to get started. You&#39;ll get a pop-up screen where you can enter your domain and the keywords you want to track:
<figure>
<img src='img/blog/posts/post-24-pic-3.jpg' alt='SEO Book Rank Checker'>
<figcaption>SEO Book Rank Checker</figcaption>
</figure>
<p>Then, hit "Start" to run the analysis. You&#39;ll get data on your keyword ranking in whatever search engines you have selected.
<figure>
<img src='img/blog/posts/post-24-pic-4.jpg' alt='SEO Book Rank Checker: Keyword Rankings'>
<figcaption>SEO Book Rank Checker: Keyword Rankings</figcaption>
</figure>
<p>Once you have a set of target keywords you want to track, you can click on the "Save" icon next to the domain field to save your keyword set for future reference. Just give it a name, and it will be saved in the application. Then, the next time you want to run that same set of keywords, you can click "Open" and choose your saved list of keywords to run again:
<figure>
<img src='img/blog/posts/post-24-pic-5.jpg' alt='SEO Book Rank Checker: Saved Keyword Groups'>
<figcaption>SEO Book Rank Checker: Saved Keyword Groups</figcaption>
</figure>
<p>If you want to keep a running tab on your keyword rankings, just set a reminder to yourself to run your saved set of keywords every week. Export the list as a CSV and enter it into a spreadsheet. This is a pretty reliable way for very small websites to keep track of their SEO ranking with no cost, and just a little bit of effort.
<p>These free tools are pretty good for basic SEO rank tracking, but if you run a larger website with many keywords (and more money at stake), it&#39;s probably in your best interest to invest in a more comprehensive paid SEO tool. Here are two great ones that get the job done at a reasonable price.
<h3>SEOMoz</h3>
<p><a href='http://www.seomoz.org/' target='_blank' rel='nofollow'>SEOMoz</a> costs $99 a month and up, but comes with a lot of resources that make it worth it. For rank tracking, they have some simple recurring reports that will deliver weekly rank changes right to your inbox. They also have a whole suite of tools that provide SEO diagnostics, and have perhaps the most active and experienced communities of SEO pros out there. An SEOMoz membership is not only worth it for the tools, but for the community and learning opportunities as well. If you&#39;re serious about SEO, and you need powerful tools to get your website ranking, taking a free 30-day SEOMoz trial would be a great next step after you finish these posts. Reading through their forums and blog posts will give you the advanced education you need, and using their diagnostic tools will help you ensure that your site is on the right track.
<h3>Raven Tools</h3>
<p><a href='http://raventools.com/seo-tools/' target='_blank' rel='nofollow'>Raven Tools</a> is another great paid option that is about $99 a month and has a free 30-day trial. Raven has an extraordinarily good rank tracking tool that allows you to view the historical rank of any keyword by week (after you&#39;ve added it in to the tool, of course). I haven&#39;t seen any other tool at this price level that does that. It&#39;s super convenient if you have a lot of keywords you need to monitor.
<p>Besides the rank tracking, Raven allows you to aggregate your link building contacts, Google Analytics data, and Google AdWords data all in one place. Their reporting is top-notch, and their user interface is fairly intuitive. You don&#39;t get the wide variety of diagnostic tools or the community of SEOMoz though, so these tools are best used in tandem if you can afford it.
<p>That about covers it for SEO tools and results tracking. There are many, many, other SEO tools out there, but these just happen to be my favorites. If you use all of these tools (or at least most of them), you should have all the tools at your disposal that 90% of SEO folks use. Now, you&#39;re armed with the strategy and the tools for SEO success. So go out there, create some great content and great links and get ranking!
</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>seo</span>, <span class='post-tag'>analytics</span>, <span class='post-tag'>SEOMoz</span>, <span class='post-tag'>tracking</span>, <span class='post-tag'>ppcwithoutpity</span></span>
<span class='post-timestamp'>Posted on October 15, 2012 @ 10:20AM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-24.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-24-thumb-100' alt='Screenshot of site after post #24'></a></span>
</div>
<div class='blog-post-guid'>534624f3-3d1a-4aac-b72c-6dad9d400f27</div>
</article>
<article class='blog-post' id='blog-post-23'>
<div class='blog-post-header'>
<h2>Post 23: CSS Resets and Organization</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/6332c7e50dc2270f2d4a1a57975b27b481d245e1' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>CSS, which stands for Cascading Style Sheets, is something that nearly everyone has heard of, most people have used, and few people understand.
<p>The first experience many people have with CSS is to do something simple, like set the background color on a page. Many folks stop learning once they are done applying colors and borders to html elements.
<p>The next big step for many folks is learning about affecting layout by &quot;floating <code>DIV</code>s&quot; or pursuing a &quot;tableless&quot; <a href='http://www.w3.org/2002/03/csslayout-howto' target='_blank' rel='nofollow'>layout</a>.
<p>While these are pratical steps in learning about CSS, I think it is important to first call out the intention for CSS. Simply put, that purpose is to help separate the page content from the page visuals.
<h3>Inline styles are valid, but bad practice</h3>
<p>In HTML, it is perfectly valid to apply inline styles to an element, along with the rest of the attributes for that element, using the <code>style</code> property. Example:
<figure>
<code>&lt;img style=&#39;border:1px solid red;height:100px;&#39; src=&#39;...&#39;&gt;</code>
</figure>
<p>As valid as inline styles are, the problem with them arises as the size and complexity of the site grows. The decision to change colors becomes tedious and error prone when that style is littered across hundreds of elements. The other major problem has to do with <a href='http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/' target='_blank' rel='nofollow'>selector specificity</a>, because inline styles are very specifc and will almost always override the styles from your css files.
<h3>CSS Resets</h3>
<p>Search for <a href='https://www.google.com/search?q=css+reset' target='_blank' rel='nofollow'>css reset</a> and you will find a ton of examples, tips, and flame wars surrounding their use. Basically, the problem that css resets are trying to solve is this: Different browsers (and version of those browsers) have different default values for various styles.
<p>These differences in default values lead to many of the headaches that you will experience when trying to get a similar look across many browsers. Shooting for an exact duplicate experience is very tough and likely futile, but using a basic CSS reset and then applying your custom styles after the reset will help save a ton of time debugging subtle differences (especially with <code>margin</code> and <code>padding</code>).
<p>Have a look at the source code for this post to see what I changed. There are comments in the CSS as well as urls to some <a href='https://github.com/csswizardry/CSS-Guidelines' target='_blank' rel='nofollow'>more</a> <a href='http://fvsch.com/code/base-stylesheet/full.css' target='_blank' rel='nofollow'>useful</a> <a href='http://html5doctor.com/html-5-reset-stylesheet/' target='_blank' rel='nofollow'>reads</a>.
<p>I also split up the styles into multiple CSS files. This is bad from the standpoint of http requests, and flies in the face of <a href='#blog-post-22' target='_blank' rel='nofollow'>previous tuning efforts</a> that I&#39;ve done, but do not fear. Soon I&#39;ll show you one way to bundle your files together for performance, and still retain the development benefits of managing separate files over giant monoliths.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css</span>, <span class='post-tag'>reset</span></span>
<span class='post-timestamp'>Posted on October 11, 2012 @ 6:20PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-23.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-23-thumb-100' alt='Screenshot of site after post #23'></a></span>
</div>
<div class='blog-post-guid'>5586da29-52bf-477b-b9b6-4db339b0b3ad</div>
</article>
<article class='blog-post' id='blog-post-22'>
<div class='blog-post-header'>
<h2>Post 22: Tuning Page Load Time</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/a5137f7da81db12f531c7f6570ea8b356aee842a' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>This post has a lot of little tweaks that radically affect the page load time. Some of these are fairly well-known, and some are a little more obscure.
<p>There are a ton of changes so I won&#39;t go into extreme detail about every line of code, but I will highlight the particularly interesting bits. Additionally, I wrote a fair bit of javascript util/library code, so I urge you to check out the source code to see what was done. It is commented so that you can follow along easily.
<p>Before diving into the details, let me first state how <a href='http://www.strangeloopnetworks.com/assets/images/visualizing_web_performance_poster.jpg' target='_blank' rel='nofollow'>important it is to have a quick loading site</a>. Each year our patience for slow web experiences dwindles. Slow sites get left in the dust. I&#39;ll bounce from a site if it doesn&#39;t load in a couple of seconds. The importance of speed cannot be emphasized enough. Amazon equates each tenth of a second (100ms) of speed improvement to a 1% increase in revenue.
<figure>
<img src='img/blog/posts/post-22-speed-affects-consumers-8.png' alt='Speed affects consumers negatively'>
<figcaption>Don&#39;t be lazy and slow. Site speed affects consumers negatively.</figcaption>
</figure>
<h3>Summary</h3>
<p>Here is a list of what I did in this post, and below I&#39;ll explain the details as well as show before and after stats.
<ul>
<li>Removed 5 external Gist js includes and 1 css include by copying them locally and putting content into <a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/js/akm-gist.js' target='_blank' rel='nofollow'>akm-gist.js</a></li>
<li>Move Quantcast and ShareThis scripts, css, and images after page load using new utility loader in <a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/js/akm-util.js' target='_blank' rel='nofollow'>akm-util.js</a></li>
<li>Split my &quot;<a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/js/akm-util.js' target='_blank' rel='nofollow'>akm.blog.init()</a>&quot; handler into two parts to move all non-essential javascript after load event</li>
<li>Added <code>defer</code> attribute to all script includes</li>
</ul>
<h3>Details</h3>
<p>Gists. The Gists are the snippets of blocks of code that are included in some of the posts. The default way of including them is to put a javascript file reference somewhere on the page and then wait for their server to send the file back down. That file simply contains two lines of code. The first code includes their standard css file for embedded scripts. The second line is a <code>document.write()</code> that just spews out the html. Because the gist js files call <code>document.write</code> they cannot be loaded after page load or the entire markup for the page will get replaced. I simply downloaded each of those js files, along with the css file, and put the contents in my own javascript file (<a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/js/akm-gist.js' target='_blank' rel='nofollow'>akm-gist.js</a>) so that I could control how the html was rendered. The lesson: just because a site provides you with a javascript include file doesn&#39;t mean that you have to use it that way to gain the functionality that it provides.
<p>Script Loader. The Quantcast script was being loaded asynchronously, but because it was inline in the HTML <code>body</code>, it was getting triggered before the page load event. It wouldn&#39;t stop the browser from continuing to process the rest of the page, but it still meant that page load happened after it finished loading. ShareThis was a little different because it was being loaded synchronously because there is a call that must be made after the script loads. The script loader function that I wrote takes a callback so that I could specify which code was to be run after the script was loaded.
<p>akm.blog.init() split. When I added the logo cube in <a href='#post-19'>Post 19</a>, I added this function to be called during the window onload event. That event gets triggered, and runs any attached functions before it finishes. Since the cube code isn&#39;t critical, there is no reason to potentially wait on that code to run. That code was moved into a new function called <a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/js/akm-blog.js' target="_blank"><code>akm.blog._initDeferred()</code></a> that will be triggered a quarter second after the init function.
<p><code>Defer</code> attribute. In the HTML5 spec, there is a new attribute for <code>script</code> tags called <code>async</code>, and it tells the browser not to hold up processing of the html while that javascript file gets downloaded and executed. So the browser will collect these script references and make requests to the various host servers while it continues processing the page. As those scripts come in, they get executed. Sadly, not all browsers support this because it is new. But do not fret! I argue that a better alternative has existed since Internet Explorer 4. The <a href='http://www.w3schools.com/tags/att_script_defer.asp' target='_blank' rel='nofollow'><code>defer</code></a> attribute has existed since IE4, FF 0.7, and Opera 7. Plus it has a cool distinguishing feature from <code>async</code> because the browser will load the deferred the scripts in the order they are included. This is perfect for pages where you server your javascript files from your own domain and are not concerned about one particular domain holding up the rest of the order.
<h3>Results</h3>
<p>Before these changes: A test load in Chrome 22 with an empty cache: DOMContent event fired at 700ms, Load event at 1600ms.
<p>After these changes: DOMContent event fired at 185ms, Load event at 208ms!
<p>1.4 seconds quicker to initial load - that is pretty darn snappy. It is worth noting that this page now loads faster than it was with only the first post and a single, scaled-down 1MB screenshot image.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>defer</span>, <span class='post-tag'>async</span>, <span class='post-tag'>js</span>, <span class='post-tag'>performance</span></span>
<span class='post-timestamp'>Posted on October 4, 2012 @ 10:50PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-22.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-22-thumb-100' alt='Screenshot of site after post #22'></a></span>
</div>
<div class='blog-post-guid'>1efc5edc-4c2d-4278-89d3-bb141b43b5c9</div>
</article>
<article class='blog-post' id='blog-post-21'>
<div class='blog-post-header'>
<h2>Post 21: SEO Part 3/4: Linkbuilding</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/a487e19f9ae33ec700c6973585656b2638742b24' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p><em>As I mentioned in <a href='#blog-post-10'>Post 10: The SEO Plan</a>, this post is the third in a 4-part series on SEO written by guest author <a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a> who runs the blog <a href='http://ppcwithoutpity.com/' target='_blank'>ppcwithoutpity.com</a>. If you haven&#39;t already, check out <a href='#blog-post-14'>Part 1: Getting Indexed</a> and <a href='#blog-post-18'>Part 2: Optimizing Code Tags For SEO</a>.</em>
<div class='guest-post-content'>
<h3>SEO Part 3: Linkbuilding</h3>
<p>Now that we&#39;ve covered most of the basics of SEO, it&#39;s time to talk about the most time consuming, yet most potentially rewarding aspect of SEO: linkbuilding. Linkbuilding is the process of obtaining links from other sites to your site. These links act as a &quot;vote&quot; for your site when search engines are evaluating your credibility. If an external site links to your site using specific anchor text in the link, that sends a signal to search engine crawlers that your site is relevant to the keywords that appear in that anchor text. Repeat the link process dozens, hundreds, or even thousands of times, and your site starts to rank higher in the search engine results for the keyword.
<p>Of course, this process is highly abused precisely because it is so effective. Unethical SEO practitioners use &quot;black hat&quot; tactics like buying links from webmasters, using bots to make thousands of spam comments on blogs with keyword-rich anchor text, or even hacking sites to sneak in a link or two. These tactics work well in the short term, but they&#39;re almost always discovered by search engines in a matter of months, leading to a complete de-indexation of the offending site.
<p>But, you don&#39;t have to resort to black hat tactics to have success. There are many legitimate ways to obtain links. Here are a few:
<ol>
<li>Requesting a link from bloggers/webmasters you know personally or professionally.</li>
<li>Adding links back to your site on your social network profiles.</li>
<li>Creating viral videos or infographics that link back to your site.</li>
<li>Offering products or services to bloggers for review purposes.</li>
<li>Creating a useful widget or template that contains a link back to your site, and sharing it with a community.</li>
<li>Posting in forums relevant to the topic of your site.</li>
<li>Submitting your link to Reddit, Digg, Stumbleupon, or similar link-sharing sites.</li>
<li>Writing a guest post for another blog, and including a link back to your site.</li>
</ol>
<p>Of course, these are just the most current linkbuilding strategies. Ask me again next year, and I&#39;ll probably give you another list. The key is to avoid tactics that seem spammy to search engines. If your gut tells you that something is spammy, it probably is. Also, if the link you obtain requires no editorial oversight from a human being, or if you pay an absurdly small amount of money for a high volume of links (I&#39;m looking at you, Fiverr), then the link is probably spammy and will hurt you in the long run. Focus on creating relevant, useful content with a relevant link back to your site and you should be good.
<p>There are a few other factors you should consider when link building:
<h3>Dofollow vs. Nofollow</h3>
<p>Before you start linkbuilding, it&#39;s important to note the difference between a dofollow and a nofollow link. These are attributes in the HTML code of a link that tell search engine spiders whether or not to follow that link and cast a &quot;vote&quot; for the site that&#39;s being linked to. Here&#39;s an example:
<p><code>&lt;a href='http://ppcwithoutpity.com' rel='nofollow'&gt;PPC Without Pity&lt;/a&gt;</code>
<p>Dofollow means that a search engine spider will go through the link and give credit to the site being linked to. All HTML links are dofollow by default. Nofollow links mean that you&#39;ll get an active link, but no real SEO benefit from the link. These days, most blog comments and social media profile links are nofollow to prevent abuse from SEO spammers. It certainly doesn&#39;t hurt to have a few nofollow links, though (see the <a href='#post-21-natural-link-profiles'>Natural Link Profiles</a> section for more on this). Even if you don&#39;t get any SEO benefit, you may obtain some valuable referral traffic.
<h3>Keywords In Anchor Text</h3>
<p>As I mentioned earlier, having keywords within a link's anchor text affect how the linked-to site ranks for those particular keywords. Basically, if you want to rank for a particular keyword, get some links that contain that keyword in the anchor text. Partial matches of the keyword have an effect as well. For example, if you wanted to rank for the keyword &quot;plaid armadillo,&quot; you would probably get some ranking benefit from links that contained the anchor text &quot;armadillo that is plaid&quot; or &quot;plaid baby armadillo&quot;.
<p>But, you can overdo this. If you have too many links with the same anchor text, it looks really spammy to the search engines and you may be penalized. As a general rule, you should have more links back to your site that contain your site's name or URL than the quantity of links that contain only keyword anchor text.
<h3 id='post-21-natural-link-profiles'>Natural Link Profiles</h3>
<p>In a perfect world, the best sites for particular topics would automatically get ranked well for the keywords relevant to the site. These sites would naturally obtain links from a variety of sites - blogs, directories, school and library resource pages, citations from other websites, etc. Unfortunately, we live in a world where the people who are most adept at SEO get the best rankings. But still, search engines favor a link profile that looks like our perfect world scenario. If you have too many links from one type of site, too many instances of a particular anchor text, or if you build a lot of links unnaturally fast, you may end up being penalized by the search engines for being a spammer. Instead, pay attention to the kinds of links you build to your site. Build a lot of links with variety. Include both dofollow and nofollow links, make sure you have more brand name/URL anchor text than any one keyword, and don&#39;t build all your links from one particular type of site.
<p>Now, let's talk about how to select which sites to approach for links. Not every site is worth your time to obtain a link from. The better a site's quality, the more SEO benefit it will confer on any site it links to. Here&#39;s how to tell if a site will provide SEO benefit:
<h3>Domain Authority/Page Authority</h3>
<p>Domain Authority and Page Authority are two proprietary SEO metrics created by SEOMoz, one of the leading SEO tool providers in the market. These metrics tell you (on a scale of 1 to 100) the &quot;authority&quot; of a domain or individual site page based on the number of links and quality of links pointing to that URL. To see a site's authority metrics, you&#39;ll need the SEOMoz toolbar. You can get it here: <a href='http://www.seomoz.org/seo-toolbar' target='_blank' rel='nofollow'>seomoz.org/seo-toolbar</a>.
<p>Before you get a link from a site, check the page that your link will appear on. If the site has a Domain Authority below 20 or 30 and the Page Authority of the page containing your potential link also falls below that threshold, the link probably won&#39;t do much for you. Generally speaking, the higher the Domain Authority and Page Authority of a link source, the more benefit it will confer upon the linked-to site.
<h3>PageRank</h3>
<p>PageRank is a similar metric to Domain Authority and Page Authority, but it takes into account on-page SEO factors as well. However, it has two drawbacks. One, it is only valid for Google ranking (PageRank is a Google proprietary metric). And two, PageRank is only updated for sites every couple of months. So if a site has been penalized for bad SEO practices recently, their PageRank might not reflect that.
<p>PageRank is kind of an outdated metric at this point, but it&#39;s still good as a general sniff test to see if a site or page will provide SEO benefit. Sites with a PageRank of 2 or higher are generally pretty good candidates for linkbuilding. As with Domain and Page Authority, the higher the PageRank, the better. There are many tools to find a site or page's PageRank. My personal favorite is the <a href='http://tools.seobook.com/seo-toolbar/' target='_blank' rel='nofollow'>SEOBook toolbar</a>. It has a lot of other neat bells and whistles for SEO pros, too.
<h3>Cache Dates</h3>
<p>If you get a link from a site, but Google never finds the site containing a link, it won&#39;t do you any good. that&#39;s why it&#39;s important to look up a site's latest Google cache date. This metric can be obtained from the SEOBook toolbar mentioned above. If the cache date is more than 30 days in the past, that should be a red flag. Try to avoid getting links from pages like that, or else you're going to be waiting a long time for some SEO benefit.
</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>linkbuilding</span>, <span class='post-tag'>seo</span>, <span class='post-tag'>ppcwithoutpity</span>, <span class='post-tag'>nofollow</span></span>
<span class='post-timestamp'>Posted on October 2, 2012 @ 9:03AM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-21.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-21-thumb-100' alt='Screenshot of site after post #21'></a></span>
</div>
<div class='blog-post-guid'>4d900633-dc8d-4827-a1fe-5e5add783b86</div>
</article>
<article class='blog-post' id='blog-post-20'>
<div class='blog-post-header'>
<h2>Post 20: CSS Sprites</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/de45671be8408f29cebe4a862229139618b3e2c3' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Alrighty, another round of performance enhancements. This time we&#39;ll go over CSS Sprites.
<p>The concept of CSS Sprites is simple. Instead of downloading 1 real image for each individual image that you see on the screen, we&#39;ll actually pack multiple images into 1 file and use CSS to only show the portion of the image that we want to show. This primary benefit is the reduction of http requests which results in faster load times. A secondary benefit is that the browser will use less RAM.
<p>Let&#39;s take the little icon images on this blog for example. There are icons in the header and footer for RSS, Twitter, and GitHub. There are 16x16 and 32x32 pixel versions as well. That is 6 icons for a total of 5.73KB after compression. Now let's put them in a simple sprite:
<figure>
<img src='img/blog/posts/post-20-blog-icons-all.png' alt='6 site icons in a sprite'>
<figcaption>6 site icons in a sprite</figcaption>
</figure>
<p>The new sprite has an 11% smaller filesize (5.11KB). Even better though, we&#39;ll save 5 http requests. I also did this for the little post thumbnails. There was 19 of them before this post weighing in at a whopping 192KB. After putting them into a single sprite, the filesize actually got a bit bigger (209KB), but 19 http requests were saved.
<p>I was also curious to see if I could reduce the image quality on the screenshot thumbnails without having them suffer too much visually. The end result is that I determined that an 8bit color depth was nearly as good as 24bit color depth in the thumbnails, and the filesize dropped From 209KB to a tiny 32KB! That is 160KB less than the originals, plus 19 fewer http requests. Win-win. But what does the HTML look like?
<p>Original: <code>&lt;img src='img/blog/icons/icon-github-32.png'></code>
<p>Sprite: <code>&lt;img src='img/blog/clear.gif' class='img-icon-github-32'></code>
<p>As you can see, the required change is very minor. First I set the image source to a clear gif, and then I set the class to one that is similar to the image filename.
<p>The CSS is fairly straightforward as well:
<pre class='code'>
.img-icon-github-32
{
width: 32px;
height: 32px;
background-image: url(../../img/blog/sprites/blog-icons-all.png);
background-position: -32px 0px;
background-repeat:no-repeat;
}</pre>
<p>Naturally, I made a <a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/img/imgsprite/imgsprite' target='_blank'>command-line tool</a> to make sprites for me because doing them by hand is tedious and error prone. Plus it will generate the css so I don&#39;t have to write that either. I also put in the option for limiting the color bit depth to 8 bits. After testing that functionality with ImageMagick, I decided to use a custom <a href='http://msdn2.microsoft.com/en-us/library/aa479306.aspx' target='_blank' rel='nofollow'>quantization</a> alogrithm which resulted in a smaller filesize and a much better looking image.
<p>The next step was to update the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat' target='_blank'>build script for this site</a>. Example:
<pre class='code'>
imgsprite.exe
-in:../../aaronkmurray-blog/img/blog/icons/*.png
-img-out:../../aaronkmurray-blog/img/blog/sprites/blog-icons-all.png
-css-out:../../aaronkmurray-blog/css/sprites/blog-icons-all.css
-css-class-name-prefix:img-
-image-deploy-url-base:../../img/blog/sprites/
-gen-test-html:true
-test-html-path:../../aaronkmurray-blog/test/sprites/
-test-html-deploy-url-base:../../img/blog/sprites/</pre>
<p>I know that is a gnarly block of command line, so I&#39;ll break it down:
<ul>
<li><code>imgsprite.exe</code>: name of the tool</li>
<li><code>-in:../../aaronkmurray-blog/img/blog/icons/*.png</code>: go grab all of the png icons</li>
<li><code>-img-out:../../aaronkmurray-blog/img/blog/sprites/blog-icons-all.png</code>: put them in a new file named blog-icons-all.png</li>
<li><code>-css-out:../../aaronkmurray-blog/css/sprites/blog-icons-all.css</code>: make a new css file called blog-icons-all.css</li>
<li><code>-css-class-name-prefix:img-</code>: prefix the css class name with &quot;img-&quot;</li>
<li><code>-image-deploy-url-base:../../img/blog/sprites/</code>: base url for the sprite</li>
<li><code>-gen-test-html:true</code>: make a test html page to view all of the sprite images at once</li>
<li><code>-test-html-path:../../aaronkmurray-blog/test/sprites/</code>: this is where the test html page goes</li>
<li><code>-test-html-deploy-url-base:../../img/blog/sprites/</code>: use a special base url for the sprite in the test page because the paths are relative (for now until CDN)</li>
</ul>
<p>There is one of these calls to imgsprite.exe in the build script for each sprite that I want to create. You can view the test page for the <a href='test/sprites/blog-icons-all.css_test.html' target='_blank'>icons</a> and <a href='test/sprites/post-screenshot-thumbs-all.css_test.html' target='_blank'>screenshots</a> if you're interested. These allow me to visually do a sanity check on the results, as well as provide me with a nice way of finding the css class name for each sprite.
<p>Before the sprites, a hit to this page had 52 http requests and a payload of 667KB. After the sprites it was 33 http requests and 506KB.
<p>And just for grins, I decided to quantize 5 of the former post images that didn&#39;t need to be lossless just to see how much they'd shrink. The result: 248KB originally down to 88KB for a savings of another 160KB. Sweet!
<p>So there you have it. Another tool to add to your collection. CSS Sprites and further image reduction options without breaking a sweat.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css</span>, <span class='post-tag'>sprite</span>, <span class='post-tag'>img</span>, <span class='post-tag'>tools</span>, <span class='post-tag'>build</span>, <span class='post-tag'>imgsprite</span>, <span class='post-tag'>quantize</span></span>
<span class='post-timestamp'>Posted on October 1, 2012 @ 7:00PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-20.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-20-thumb-100' alt='Screenshot of site after post #20'></a></span>
</div>
<div class='blog-post-guid'>8724a9a0-3ba8-4302-9e9e-8f9e70e1fe97</div>
</article>
<article class='blog-post' id='blog-post-19'>
<div class='blog-post-header'>
<h2>Post 19: Fun With A CSS3 Cube</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/f3939d0f32081bf271c82fcd8c754d922f923695' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>In this post I will show you how I did the &quot;3D&quot; CSS cube for my logo. The <a href='https://github.com/akmurray/aaronkmurray-blog/commit/721fc83fad549ba5b27174b7743496fb7e66685d' target='_blank'>code for the changes is on GitHub</a> (as usual).
<h3>Site Logo represented as a 3D Cube using CSS3 Transforms</h3>
<p>I won&#39;t do a full write-up because there is already <a href='http://desandro.github.com/3dtransforms/docs/cube.html' target='_blank'>a nice series of CSS 3D Transforms articles</a> written by <a href='http://desandro.com/' target='_blank'>desandro</a>. If you are interested, you should read the article for full details on how to do it yourself.
<p>The summary of interesting bits for how I implemented the logo cube is:
<ul>
<li>HTML: Create a wrapper DIV that will represent the &quot;cube&quot;</li>
<li>HTML: Create 6 DOM Elements inside the wrapper that will represent the 6 sides/faces of the cube</li>
<li><div id='wrapper-gist-3811888'>loading gist...</div></li>
<li>CSS: <a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/css/blog-logo.css' target='_blank'>Style the cube for size and 3D transform</a></li>
<li>JS: After the page loads, set up a timer that will rotate the cube every few seconds</li>
<li><div id='wrapper-gist-3811934'>loading gist...</div></li>
</ul>
<h3>Fallback when browser doesn&#39;t support CSS3 Transforms</h3>
<p>Because having a rotating 3D cube for my logo isn't &quot;critical&quot; for this site, I didn&#39;t concern myself with having the same experience for all browsers. In this case, browsers that don&#39;t support CSS3 Transforms will not show the 3D rotation. They will simply show the &quot;last&quot; image in the stack of &quot;sides&quot;, which will result in a single static logo being displayed.
<p>Currently there are two ways of viewing this concept: <dfn>Graceful Degradation</dfn> and <dfn>Progressive Enhancement</dfn>.
<ol>
<li><dfn>Graceful Degradation</dfn> means that if a feature isn't supported, and acceptable fallback would occur.</li>
<li><dfn>Progressive Enhancement</dfn> is the opposite way of viewing the same situation. A basic experience is defined, and when possible, enhancements to that experience will be provided based on browser support.</li>
</ol>
<p>The differences are subtle, but meaningful.
<ul>
<li><dfn>Progressive Enhancement</dfn> implies that all basic functionality will exist, and then extras will be added on to make the experience better. Example: The logo for this site will be a 2D image, unless the browser supports a 3D rendering via CSS.</li>
<li><dfn>Graceful Degradation</dfn> typically means that when failure occurs, it doesn&#39;t completely kill the experience, but that experience may not be the same. The primary example of this is the use of a text message to the user when Adobe's Flash plugin is not installed/available, instead of providing an alternative way to see that content.</li>
</ul>
<p>it&#39;s up to you to choose when features are &quot;critical&quot; and when they are simply icing on the cake.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css3</span>, <span class='post-tag'>cube</span>, <span class='post-tag'>logo</span>, <span class='post-tag'>progressive enhancement</span>, <span class='post-tag'>graceful degradation</span></span>
<span class='post-timestamp'>Posted on October 1, 2012 @ 11:05AM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-19.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-19-thumb-100' alt='Screenshot of site after post #19'></a></span>
</div>
<div class='blog-post-guid'>aea98599-7cb9-4cc4-ad4e-81d7b4c0c627</div>
</article>
<article class='blog-post' id='blog-post-18'>
<div class='blog-post-header'>
<h2>Post 18: SEO Part 2/4: Optimizing Code Tags For SEO</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/9c1566a5addefa03afe411bb3be70b45b2d17284' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p><em>As I mentioned in <a href='#blog-post-10'>Post 10: The SEO Plan</a>, this post is the second in a 4-part series on SEO written by guest author <a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a> who runs the blog <a href='http://ppcwithoutpity.com/' target='_blank'>ppcwithoutpity.com</a>. If you haven&#39;t already, check out <a href='#blog-post-14'>Part 1: Getting Indexed</a>. And after you finish reading this post, have a look at the code changes for this post in GitHub to see Shawn's suggestions at work on this site, as well as some <a href='http://www.w3schools.com/html5/html5_reference.asp' target='_blank' rel='nofollow'>html tag</a> changes to move towards cleaner, <a href='http://en.wikipedia.org/wiki/Semantic_HTML' target='_blank' rel='nofollow'>semantic markup</a>.</em>
<div class='guest-post-content'>
<h3>SEO Part 2: Optimizing Code Tags For SEO</h3>
<p>it&#39;s a common misconception that there are some magical code tweaks that you can make to your site to &quot;do&quot; SEO. Unfortunately, this is not the case. About ten or fifteen years ago, when search engines were just starting to achieve mainstream popularity, there were a lot of secret tweaks you could do to fool search engines into thinking your spam site was the most relevant page for a specific search query. Fortunately for search engine users, search engines have closed many of these loopholes, and the effect of on-site signals to determine keyword relevance have been somewhat diminished.
<p>However, they have not been eliminated entirely. There are still a few code tags that you can enter keywords into in order to influence search engine ranking. Sometimes, if you're targeting a key term with little or no competition, you can even reach a #1 rank through code optimization alone. Let&#39;s take a look at some of the code tags that still influence SEO rank.
<h3>&quot;META&quot; Tags</h3>
<p><code>&lt;meta&gt;</code> tags appear in the <code>&lt;head&gt;</code> section of each page on your website, and provide metadata to browsers and search engines about what your page is about. There are lots of different <code>&lt;meta&gt;</code> tags, but there are only two that have much bearing on SEO.
<h3>&lt;Title&gt;</h3>
<p>The <code>&lt;title&gt;</code> tag defines your page's title, and most browsers render the title as the text in your browser tab that labels the site. it&#39;s also the text that appears in the hyperlink on a search engine results page (SERP). In the code, it looks a little something like this:
<p><code>&lt;title&gt;PPC Without Pity - A PPC Marketing Blog From A Merciless Perspective&lt;/title&gt;</code>
<p>Different search engines and browsers have different character limits for the title tag (or at least, limits on what text they display). This limit varies between 65 to 72 characters. So it&#39;s best to keep your <code>&lt;title&gt;</code> tag length around 60 characters or less.
<p>You can insert keywords into your title tag. These keywords seem to have a powerful influence on ranking. In fact, optimizing your <code>&lt;title&gt;</code> tag for targeted keywords is probably the easiest thing you can do to your site that will have a distinct SEO impact. But, that doesn&#39;t mean you should just cram a mess of keywords into your title tag. Pick one or two phrases you want to target, then add your site's title after that (or if it&#39;s your home page, put your site's title first).
<h3>&lt;META&gt; Description</h3>
<p>The <code>&lt;meta&gt;</code> description tag also appears in your site's <code>&lt;head&gt;</code> section. This tag provides the words that appear below your site's hyperlinked title in the SERPs. Or at least, it does most of the time - if your <code>&lt;meta&gt;</code> description is spammy or nonexistent, the search engines may replace that block of text with a different block of text that appears within your page. A <code>&lt;meta&gt;</code> description tag looks like this in the code:
<p><code>&lt;meta name=&quot;description&quot; content=&quot;A PPC blog dedicated to pay per click advertising, Google Adwords, Yahoo Search Marketing, MSN AdCenter, and other pay per click advertising formats and accounts.&quot; /&gt;</code>
<p><code>&lt;meta&gt;</code> description doesn&#39;t have any direct bearing on your search engine ranking. That particular loophole was closed years ago. But, since the <code>&lt;meta&gt;</code> description appears on the SERPs, it will influence whether or not a user clicks on your site. If you have a really appealing description tag, you may end up getting more clicks than other sites on the results page with an irrelevant description. Treat your <code>&lt;meta&gt;</code> description as ad copy to entice a user to click on your result.
<p>Like the <code>&lt;meta&gt;</code> title, this tag has varying character limits depending on the search engine. But if you keep your <code>&lt;meta&gt;</code> description below 150 characters, you should be good.
<h3>&lt;META&gt; Keywords</h3>
<p>Another tag that appears in the <code>&lt;head&gt;</code> section, but this one has absolutely no effect on anything. But, it&#39;s worth mentioning for that fact. This meta tag was highly abused back in the day, so search engines have disregarded it entirely. If someone is trying to give you SEO advice by telling you to optimize for <code>&lt;meta&gt;</code> keywords, it&#39;s probably a good indicator that they don&#39;t know what they&#39;re talking about.
<h3>Heading Tags (H1, H2, H3, etc.)</h3>
<p>Heading tags were used more frequently in pre-CSS web development to segment content sections. But now that CSS does that trick, heading tags are somewhat obsolete. Still, there is some evidence that search engines use keywords within H1, H2, and occasionally H3 tags to determine ranking. H1 tags pass the most influence, and H2s pass a little. So if you're using H1 tags, it&#39;s a good idea to give some thought to which keywords you use in them.
<h3>Image Alt Tags</h3>
<p>When you create an image, you have an option to create an &quot;alt&quot; attribute to append a text description to the image. It looks like this:
<p><code>&lt;img src=&quot;http://ppcwithoutpity.com/wp-content/uploads/2012/09/adwords-seller-ratings-example.jpg&quot; alt=&quot;adwords seller ratings example&quot; width=&quot;224&quot; height=&quot;103&quot; class=&quot;aligncenter size-full wp-image-943&quot; /&gt;</code>
<p>Alt attributes were created to aid in screen-reading programs for blind web users. Having a picture doesn&#39;t really help describe anything if you're unable to see it. But guess who else can't see images to tell what they&#39;re about? Search engines! Search engine spiders use the text in the alt attribute to determine the topic of your image. If you put some keywords within your alt attribute, then it could help those keywords rank for the page they appear on.
<h3>A Final Note On Keyword Content</h3>
<p>Including keywords within these code tags is important, but let's not forget the most important place to put your keywords: your content. If you want to rank well for a keyword, it needs to appear within your content, preferably somewhere within the first paragraph or so. But, that doesn&#39;t give you a license to just pump your page content full of the same keyword. A good sniff test is to have someone else read your content and ask them if any keyword appears to be repeated too often. You could potentially be penalized for having a spammy site if your site content seems stuffed full of keywords, so you really need to straddle that fine line between using your targeted keywords, but not using them unnaturally.
<p>-<a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a>
</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>seo</span>, <span class='post-tag'>meta</span>, <span class='post-tag'>tags</span>, <span class='post-tag'>ppcwithoutpity</span></span>
<span class='post-timestamp'>Posted on September 24, 2012 @ 3:04PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-18.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-18-thumb-100' alt='Screenshot of site after post #18'></a></span>
</div>
<div class='blog-post-guid'>f403007e-6f72-4364-8539-18e1adbd6508</div>
</article>
<article class='blog-post' id='blog-post-17'>
<div class='blog-post-header'>
<h2>Post 17: First Month Retrospective</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/05bb0715f65389b4c173b20eea40a989fbb5e41a' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>I&#39;m a big fan of postmortems, and find myself reading lots of them from sites like <a href='http://gamasutra.com/search/index.php?search_text=postmortem' target='_blank' rel='nofollow'>Gamasutra.com</a>.
<p>The great thing about doing a postmortem is that it helps re-enforce and solidify the learning experiences from a project while they are still fresh.
<p>It has been a month since I started this blog, so I figured that a look back at the project was in order.
<h3>What Went Right</h3>
<ul>
<li>Lots of posts. I was worried that I wouldn't find enough minutes in each day to construct a decent post.</li>
<li>Variety of posts. I&#39;ve covered various topics, from entry-level HTML and CSS, to build scripts and tools.</li>
<li>RSS Feed. Not getting one up quickly was my biggest fear when doing a blog project from scratch.</li>
</ul>
<h3>What Went Wrong</h3>
<ul>
<li>RSS Feed. The intial feed had bugs that spammed all posts out as new posts each time I did an update.</li>
<li>Not enough pictures. Looking back at the posts, many of them are huge walls of text.</li>
<li>Build/Commit/Build process. I still have to do 2 GitHub Commits for each post because each post has a link to it&#39;s own commit. Still trying to figure that one out.</li>
</ul>
<h3>Frustrations</h3>
<p>As much fun as I am having with this project, there are still many frustrations and things that &quot;feel wrong&quot; every time I do them.
<ul>
<li>Not having a traditional database feels yucky/scary</li>
<li>Copying and Pasting my post template with each post feels wrong and is prone to error</li>
<li>Not using code that I&#39;ve already written to achieve things that I want to do feels wasteful</li>
<li>Writing everything from scratch feels tedious (yet liberating) at times</li>
<li>My Build/Release process still has a couple manual steps</li>
</ul>
<h3>Realizations</h3>
<ul>
<li>Different is okay. I was so used to doing sites a certain way with a wealth of frameworks that I&#39;ve built up and leveraged over the years, it was scary and foreign to go back to a single HTML page as a starting point. Now I am embracing the process. With each post I challenge myself to achieve the intended end result in a way that I have not done before.</li>
<li>Database != DBMS. Thinking about the term &quot;database&quot; without meaning mySQL, SQL Server, or Raven is really odd. Currently, the database for this site is <a href='https://github.com/akmurray/aaronkmurray-blog/blob/master/index.html' target='_blank'>index.html</a>. That is a new paradigm of thinking for me, and it has led to some radical thoughts that I plan on exploring in the future.</li>
<li>New process is hard. It actually isn't the process that is difficult as much as challenging my brain to be willing to do things that I&#39;ve done a dozen times in a new and different way.</li>
</ul>
<h3>What Is Next?</h3>
<p>This is the constant question. There are many things that I have listed out in my project notes. Here is a quick sample of things on my short-list:
<ul>
<li>Tech: use a CDN</li>
<li>Tech: js and css minification, bundling, versioning, and debugging</li>
<li>Tech: css sprites/images</li>
<li>Tech: html minification</li>
<li>Tech: url-rewriting</li>
<li>Tech: automated testing</li>
<li>Tech: reporting</li>
<li>Tech: figure out what &quot;database&quot; means</li>
<li>Tech: automatic seo analytics capture</li>
<li>Tech: server-side rendering and client-side MVC</li>
<li>Feature: tag cloud</li>
<li>Feature: permalinks</li>
<li>Feature: post paging</li>
<li>Feature: post comments</li>
<li>Feature: social integrations</li>
<li>Feature: decent UI design</li>
</ul>
<p>If there are other things that you'd like to see, <a href='https://twitter.com/aaronkmurray' target='_blank'>hit me up on Twitter</a>.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>postmortem</span>, <span class='post-tag'>retrospective</span></span>
<span class='post-timestamp'>Posted on September 21, 2012 @ 3:20PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-17.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-17-thumb-100' alt='Screenshot of site after post #17'></a></span>
</div>
<div class='blog-post-guid'>8197c362-a697-414c-bbe2-72d6247303bc</div>
</article>
<article class='blog-post' id='blog-post-16'>
<div class='blog-post-header'>
<h2>Post 16: HTML Markup Cleanup</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/4d9163e225d90e52b78cc6219efa6fd1c5ad1a8e' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>This post is a little bit of housekeeping and HTML fundamentals. It will touch on a few of the &quot;smaller&quot; questions that come up related to writing HTML, and then show how to use an automated tool at build time to get a report on the basic structure of our HTML (look for errors, etc.)
<h3>A micro-history of HTML</h3>
<p>Back in the old days, browsers were fighting to provide the best experience possible as we were discovering the possibilities of the Internet.
<p>At their core, browser are essentially fancy text parsers. They get HTML from a server, and then try to interpret that text and turn it into a nice picture for a human.
<p>It sounds simple enough, but instantly it was troublesome. As it turns out, humans aren't perfect when it comes to creating nested hierarchies of nodes and text. And back then, many sites were hand-made similarly to how this blog is currently being developed. Despite our best efforts, we humans still get it wrong.
<p>For browsers, they needed to not only be great at parsing HTML, but they had to be even better at deriving the author's intention in the midst of the author's own HTML mistakes. This was part of the reason for all of the old nasty doctype declarations (see next section). The goal was to give the browser a hint at what the author intended.
<h3>DOCTYPE</h3>
<p>Let&#39;s start from the top: <a href='http://www.w3schools.com/tags/tag_doctype.asp' target='_blank' rel='nofollow'>doctype</a>.
<p>Doctype is a special tag that basically tells the browser what type of document that it should expect to parse. As such, it has to be the first element of a page.
<p>Here is the modern example: <code>&lt;!doctype html&gt;</code>
<p>There are all sort of different doctypes out there, but the skinny is: if you are making a new site, or you are fortunate enough to no be concerned with supporting ancient browsers, then the doctype example from above is all you need to use. Done. Simple.
<p>If you live in the e-Commerce world, work on intranet apps, or have an affinity for providing support to folks who still use Netscape 4.7, then you have a decision to make.
<p>I won&#39;t go into the details here, but it&#39;s likely that you&#39;ll be using <code>HTML 4.01 Transitional</code> or <code>HTML 4.01 Frameset</code>.
<p>Well, just as authors can make mistakes in the markup, they can also make mistakes when choosing a doctype. Furthermore, most pages on large sites are actually generated on the fly by combining smaller chunks of html into one large page. This makes it especially hard to determine which doctype should be used. The code that chooses the doctype may be aggregating HTML from a source without knowing if that HTML is going to use FRAMESETS. Ugh.
<p>The old intention was noble, but ultimately flawed. So now we just go back to basics, and tell the browser that it should expect HTML.
<h3>XHTML vs HTML</h3>
<p>The first thing you learn when you start researching (old) doctypes is that in addition to HTML, there is an option for XHTML.
<p>To put it simply, XHTML is strictly-written HTML. It doesn&#39;t allow for mistakes. It removes the interpretation part from the lenient HTML structure parsing that browsers do.
<p>Again, this was originally intended to combat the wild-west, poorly written HTML that originally dominated the Internet. The moral of this story is: chances are likely that you will never have to know or care about XHTML. Be thankful for that.
<h3>Tag and Attribute Names: uppercase vs lowercase</h3>
<p>Easy: doesn&#39;t matter. UPPER CASE has a way of crying out for attention. Typically when I am reading HTML I am more interested in the tag attribute values as opposed to the tag names and attribute. Because of this, I prefer lowercase. These are functionally equivalent:
<ul>
<li><code>&lt;!doctype html&gt;</code></li>
<li><code>&lt;!DOCTYPE HTML&gt;</code></li>
</ul>
<h3>DOM Element Identification: &quot;<code>id</code>&quot; vs &quot;<code>name</code>&quot;</h3>
<p>Both <code>id</code> and <code>name</code> are attributes for DOM elements that allow you to identify certain nodes. There are differences, but this guideline will take you a long way: use <code>id</code> instead of <code>name</code> to uniquely identify elements.
<p>When should you use <code>name</code> then?
<ul>
<li>Only on <code>form</code> elements that you want to submit to a server</li>
<li>Only on the tags: <code>a, form, iframe, img, map, input, select, textarea</code></li>
<li>Example: <code>&lt;input type='text' id='txtAddress' name='txtAddress' ... /&gt;</code></li>
</ul>
<p>It is okay/advisable to also use the <code>id</code> attribute whenever using the <code>name</code> attribute. My standard mode of operating is to use the <code>id</code> attribute always, and then additionally use the <code>name</code> attribute on <code>form input</code> fields.
<h3>Attribute values: with or without quotes?</h3>
<p>Simply put: use quotes if the attribute <code>value</code> has a space in it. If the value comes from a database or other location, then use quotes and make sure to escape any quotes that may appear in that value by using <code>&amp;#39;</code>for single quotes and <code>&amp;quot;</code> for double quotes.
<p>Examples:
<ul>
<li>Right: <code>&lt;input type='text' value='Aaron<strong>&amp;#39;</strong>s House' name='txtPartyLocation' ... /&gt;</code></li>
<li>Wrong: <code>&lt;input type='text' value='Aaron<strong>'</strong>s House' name='txtPartyLocation' ... /&gt;</code></li>
<li>Right: <code>&lt;input type=&quot;text&quot; value=&quot;The <strong>&amp;quot;</strong>Good<strong>&amp;quot;</strong> Son&quot; name=&quot;txtNickname&quot; ... /&gt;</code></li>
<li>Wrong: <code>&lt;input type=&quot;text&quot; value=&quot;The <strong>&quot;</strong>Good<strong>&quot;</strong> Son&quot; name=&quot;txtNickname&quot; ... /&gt;</code></li>
</ul>
<h3>Attribute values: Single quotes vs Double quotes</h3>
<p>Short answer: either. Individual style preference. Functionally they are the same. If you are working in a big project that uses double quotes, use double quotes. And vice versa.
<p>Personally, I am conflicted. I prefer single quotes because it &quot;cuts down on the visual noise&quot; when I&#39;m looking at HTML and javascript, but the flipside is that I write a lot of C# code and <code>strings</code> in C# are wrapped in double quotes. These days I find myself using single quotes most of the time.
<h3>Tools to help</h3>
<p>Above I mentioned that web browsers work by parsing text/HTML and turning that into a visual that humans can understand more easily. There are tools that we can use to pre-parse the HTML and then warn us of the glaring structural errors. For this example, I&#39;ll show a tool called <a href='https://github.com/w3c/tidy-html5' target='_blank' rel='nofollow'>html-tidy5</a> that can be run as part of our build process.
<p>There are also <a href='http://lint.brihten.com/html/report?u=http%3A//aaronkmurray.com&amp;s=0100110#' target='_blank' rel='nofollow'>online tools</a> that you can play with to see example results.
<p>I added tidy as the first step in the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat' target='_blank'>build script for this site</a>. If it finds errors or warnings when it runs, it will cancel the build and open notepad to show a list of problems. Those can then be fixed, and the build can be run again.
<p>Here is a sample of what html tidy found on this page:
<ul>
<li>Illegal closing tag <code>&lt;/span&gt;</code> for <code>&lt;li&gt;</code></li>
<li>A quotation error in my meta name=description tag after refactoring double quotes to single quotes</li>
<li>target='_target' instead of target='_blank'</li>
<li>missing alt tags on images</li>
</ul>
<p>I was able to quickly go back and make edits to correct the bugs that I had created. I did have to make a change to the automatic timestamp HTML because tidy flags empty <code>span</code> nodes as warnings. The choice was either to ignore warnings altogether, which would leave me vulnerable to dozens of other warnings that it found, or change my process to stub out a value that was easy to detect. I chose the latter, so now my empty timestamp stubs have a question mark in them, and look like:
<ul>
<li><code>&lt;span class='post-timestamp'&gt;?&lt;/span&gt;</code></li>
</ul>
<p>This new process is a simple way to ensure that I maintain a decent quality of my code as the project gets bigger.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>html</span>, <span class='post-tag'>tidy</span>, <span class='post-tag'>doctype</span>, <span class='post-tag'>xhtml</span>, <span class='post-tag'>attributes</span></span>
<span class='post-timestamp'>Posted on September 21, 2012 @ 3:25PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-16.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-16-thumb-100' alt='Screenshot of site after post #16'></a></span>
</div>
<div class='blog-post-guid'>e19b213c-4e59-4c4d-bcc7-33973d0576f5</div>
</article>
<article class='blog-post' id='blog-post-15'>
<div class='blog-post-header'>
<h2>Post 15: CSS Includes</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/7d59ad24082cc8f8b43b873e22ec2cd031ea9063' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Back to basics. I&#39;ve blogged a couple of times already about the importance of reducing the amount of data that has to be downloaded. Some of you have noticed that up until now, the CSS styles for this blog were still imbedded in the HTML markup.
<p>First, let me explain why the seemingly odd order. There was less that 2KB of CSS in the page, as compared to hundreds of KB in images. I also wanted to have a history right in the index.html for a while so that it was easily apparent to learners looking through the GitHub commit history which CSS changes were causing the visual differences with the first few posts.
<p>In the big picture of site performance, including CSS styles in separate files provides the following benefits:
<ul>
<li>The styles can be used by different pages on the site (code reuse)</li>
<li>The CSS files can be cached by the browser so that they do not have to be re-downloaded with each page view</li>
<li>The CSS files can be served from a different server in your network, or even a different network entirely (like a global <a href='http://en.wikipedia.org/wiki/Content_delivery_network' target='_blank' rel='nofollow'>CDN</a>)</li>
<li>The CSS files can be compressed, even if your HTML content is not</li>
</ul>
<p>The downsides including CSS styles in separate files are:
<ul>
<li>Initial (empty cache) page load (slightly) takes longer with multiple requests</li>
<li>If external files are served from a different domain/subdomain, then there is also an extra (relatively slow-ish) <a href='https://developers.google.com/speed/docs/best-practices/rtt#MinimizeDNSLookups' target='_blank' rel='nofollow'>DNS lookup</a></li>
<li>Browsers need to know when the file was last changed in order to not use outdated/changed files</li>
</ul>
<p>In practice, the upsides outweigh the downsides considerably. So let's get started!
<p>First, start off by making a new text file. I&#39;ll call this <code>blog.css</code> for the sake of simplicity and place it in a folder called <code>css</code>. Then simply add some html to the <code>&lt;head&gt;</code> section let the browser know that it needs to download those styles and use them in the page:
<ul>
<li><code>&lt;link rel='stylesheet' href='<a href='css/blog.css' target='_blank' rel='nofollow'>css/blog.css</a>'&gt;</code></li>
</ul>
<p>Final note: the one truly notable downside with external file includes has to do with the browsers caching files and dealing with the scenario where a visitor has been to your site before. In that scenario, browser will nearly always try to use a cached version on the file, but may fail to recognize, for various reasons, that the file has been updated/changed and that it should use the latest version from the server instead of the one that it has saved locally. This can cause users to view your site with the old files, and is usually the reason you hear a first web-debugging step of &quot;clear your cache&quot; or &quot;restart your browser/computer.&quot;
<p>The best and most reliable way around this is to put simple version numbers in your actual filenames so that the browser always tries to fetch a file that has changed, but that can be cumbersome to maintain. Example:
<ul>
<li><code>&lt;link rel='stylesheet' href='css/blog-version-123.css'&gt;</code></li>
</ul>
<p>Other, less ideal, methods include:
<ul>
<li>Include a querystring paramter after the filename that changes with each version: <code>&lt;link rel='stylesheet' href='css/blog.css?version=123'&gt;</code>
<ol>
<li>Problem: The file won&#39;t be automatically cached for you by external/regionally distributed networks/routers/switches.</li>
<li>Problem: The browser isn't guaranteed to actually fetch the new version</li>
</ol>
</li>
<li>Specify a <a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9' target='_blank' rel='nofollow'><code>Cache-Control</code></a> Response header: <code>Cache-Control: max-age=3600, must-revalidate</code>
<ol>
<li>Problem: You need to have a good estimate of how frequently files change to set a &quot;good&quot; <code>max-age</code> value in seconds (or any of the other directive values)</li>
<li>Problem: The browser doesn&#39;t always obey these headers for various technical reasons</li>
</ol>
</li>
<li>Specify an <a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19' target='_blank' rel='nofollow'><code>ETag</code></a> Response header: <code>ETag:&quot;1edec-3e3073913b100&quot;</code>
<ol>
<li>Problem: This value needs to change when the contents of the file change</li>
<li>Problem: The browser doesn&#39;t always obey these headers for various technical reasons</li>
</ol>
</li>
<li>Specify an <a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21' target='_blank' rel='nofollow'><code>Expires</code></a> Response header: <code>Expires: Thu, 20 Sep 2012 16:00:00 GMT</code>
<ol>
<li>Problem: You need to have a good estimate of how frequently files change to set a &quot;good&quot; <code>Expires</code> value in GMT date format</li>
<li>Problem: The browser doesn&#39;t always obey these headers for various technical reasons</li>
</ol>
</li>
</ul>
<p>In the worst case scenario of my versioned filename approach, the user will refetch the newest version of the file with each page load. In the worst case scenario of the other methods, the user have the wrong version of the file. In a future post, we&#39;ll go over some automated ways of handling this situation.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css</span>, <span class='post-tag'>cdn</span>, <span class='post-tag'>bandwidth</span>, <span class='post-tag'>performance</span></span>
<span class='post-timestamp'>Posted on September 20, 2012 @ 2:00PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-15.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-15-thumb-100' alt='Screenshot of site after post #15'></a></span>
</div>
<div class='blog-post-guid'>1ee21e12-47fb-4d50-9e17-72ab21aab632</div>
</article>
<article class='blog-post' id='blog-post-14'>
<div class='blog-post-header'>
<h2>Post 14: SEO Part 1/4: Getting Indexed</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/809680a52837a2f86cac25aa714f61eb7268055c' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p><em>As I mentioned in <a href='#blog-post-10'>Post 10: The SEO Plan</a>, this post is the first in a 4-part series on SEO written by guest author <a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a> who runs the blog <a href='http://ppcwithoutpity.com/' target='_blank'>ppcwithoutpity.com</a>. </em>
<div class='guest-post-content'>
<h3>SEO Part 1: Getting Indexed</h3>
<p>Before you can start seeing spectacular SEO results on your site, first you have to let the search engines know that your site is there. There are a few ways to go about this:
<ol>
<li>Google Webmaster Tools submission</li>
<li>Bing Webmaster Tools submission</li>
<li>Creating an XML sitemap</li>
<li>Getting a link from an influential, recently-cached site</li>
</ol>
<p>Let&#39;s go through the how-to of each one.
<h3>Google Webmaster Tools</h3>
<ol>
<li>Go to <a href='http://www.google.com/webmasters/' target='_blank' rel='nofollow'>google.com/webmasters</a> to create an account.</li>
<li>Once you create an account, click on the &quot;Add A Site&quot; button to add your URL.</li>
<li>After you enter the URL you want to add, you&#39;ll be asked to verify that you own the site. You can do this via several different methods: through your domain name provider, uploading an HTML file to your web server, adding a special META tag to your homepage header, or by linking your Google Analytics account. Different sites and hosting configurations have different interactions with each of these verification methods. But, the most reliable (and easiest) method in my experience is the META tag addition.</li>
</ol>
<figure>
<img src='img/blog/posts/post-14-3-gwt-step-3.jpg' alt='Google Webmaster Tools: Verify Site'>
<figcaption>Google Webmaster Tools: Verify Site Ownership Options</figcaption>
</figure>
<p>Once your site is verified, you will have access to a set of tools that will help you diagnose SEO issues with your site, track inbound links and search queries, and create ways to help Google index your site. I won&#39;t get into all the ins and outs of Google Webmaster Tools here (that would take a whole series of posts), but I do want to cover a few settings that will help get your site indexed initially.
<p>Click on the Configuration section in the navigation, and select &quot;Settings.&quot; You have a few options on this page. You can select your geographic target here. This will help Google understand what your local language is in, and which international Google search engines should give your site priority. Also on this page, you can choose a preferred domain. You can state that you prefer your domain with or without &quot;www.&quot; This will help prevent duplicate content issues by defining one canonical version of your domain name in Google&#39;s system. The third option on this page is to select the crawl rate. If you just added your site, you probably won&#39;t have the option to change this just yet. But once you get some traffic, you can return to this page to define a suggested crawl frequency for Google&#39;s spiders to re-index your site. Of course, this is just a suggestion to Google - there&#39;s no guarantee they&#39;ll actually follow your instructions.
<p>In Google Webmaster tools, you can also upload an XML sitemap. You can perform this task in the Optimization &gt; Sitemaps section of your account. We&#39;ll go into this a little bit more in the sitemaps part of this post.
<h3>Bing Webmaster Tools</h3>
<p>Bing may not be as popular as Google, but it still gets enough user traffic where it makes sense to have your site indexed by them. Fortunately, they also have a webmaster tools account where you can show Bing how to index your content.
<ol>
<li>Go to <a href='http://www.bing.com/toolbox/webmaster' target='_blank' rel='nofollow'>bing.com/toolbox/webmaster</a></li>
<li>Enter the URL of the site you want to add at the top of the page.</li>
<li>Fill out the form on the next page with your personal information. You can also add a sitemap URL on this form, if you have one.</li>
<li>Once you save your info, your site will appear on your Bing Webmaster Tools dashboard. But, you still need to verify it. Click on the &quot;Verify Now&quot; link next to the site URL.</li>
<li>Bing offers you three verification methods: you can upload a special Bing XML file to your root folder in your hosting account, you can verify via a special META tag on your homepage <code>&lt;head&gt;</code> section, or you can add a unique CNAME record to your DNS.</li>
</ol>
<figure>
<img src='img/blog/posts/post-14-10-bing-verify-site-options.jpg' alt='Bing Webmaster Tools: Verify Site Ownership'>
<figcaption>Bing Webmaster Tools: Verify Site Ownership Options</figcaption>
</figure>
<p>Bing Webmaster Tools also has a lot of options to help your site get crawled. You can submit sitemaps, submit individual URLs, and define the crawl rate of your site. All of these options help your new site become more findable by search engine spiders.
<h3>Creating an XML Sitemap</h3>
<p>As I mentioned above, creating a sitemap is an important part of getting a website crawled by search engine spiders. First, some clarification: just adding a sitemap will not make your site more findable. What a sitemap does is provide a roadmap for crawlers that arrive on your site, helping them find all of the pages within your domain. A crawler has to reach your domain in the first place for a sitemap to help, and uploading that sitemap will not help anything find your domain. But, the sitemap does play an important role in assisting web crawlers with finding all of the obscure, deeply-buried pages within your site. And the more pages on your site that get found, the more pages that have the potential to show up on a web search.
<p>If you have a small (&lt; 500 page) site, you can create a sitemap for free using the tool at <a href='http://www.xml-sitemaps.com/' target='_blank' rel='nofollow'>xml-sitemaps.com</a>. Just follow the instructions on the page and you should be good to go. If you have a larger site, you may need to run a program on your web server to index and create all the entries on the sitemap. Google has a tool for this (in beta, of course) at this URL: <a href='http://code.google.com/p/googlesitemapgenerator/' target='_blank' rel='nofollow'>code.google.com/p/googlesitemapgenerator/</a>. There are also dozens of other tools out there to create sitemaps, so finding an easy way to make one is only a Google search away.
<p>Once you have a sitemap, you&#39;ll need to upload it to your web server. It must reside at this address: <em>www.your-site-name-here.com</em>/sitemap.xml. If you have to gzip your sitemap due to size, the URL of <em>www.your-site-name-here.com</em>/sitemap.xml.gz is also acceptable. Whichever URL you go with, make sure to enter this URL in your robots.txt file to ensure that the search engines know where it is. And just to be extra sure, submit that sitemap to both Google Webmaster Tools and Bing Webmaster Tools.
<h3>Getting An Influential Link</h3>
<p>Even after all this work, it may take a while for the search engines to find your site to speed up this process, it helps to get a strong initial link to get the ball rolling. You&#39;ll want to get a link from a site that gets cached frequently. If crawlers return to a site frequently to check for new links, the link to your site should be found quickly, meaning that the crawler will reach your site via the link and add it to the search engine&#39;s index as soon as the page with your link is cached. Also, you should make sure that the link you get is dofollow - a crawler will not pass through a nofollow link, negating the benefit of indexation.
<p>Getting links isn&#39;t exactly easy. But, maybe you have an established site that gets decent search traffic. Or maybe you know a friend who has one. You can even reach out to an influential blogger that you admire and ask them nicely to give you a link to this new project you&#39;re working on. Be creative in your linkbuilding, and you will be rewarded.
<p>To check on when a page was last cached by Google, you can use this tool: <a href='http://www.searchenginegenie.com/tools/google-bot-last-accessed-date.php' target='_blank' rel='nofollow'>searchenginegenie.com/tools/google-bot-last-accessed-date.php</a>. Or, the SEOBook toolbar has this functionality within their browser extension. You can download it here: <a href='http://tools.seobook.com/seo-toolbar/' target='_blank' rel='nofollow'>tools.seobook.com/seo-toolbar/</a>. Remember to check the cache date of the page where your link will appear. Homepages tend to get cached pretty frequently, while individual post and category pages do not.
<p>-<a href='https://twitter.com/slivengood' target='_blank'>Shawn Livengood</a>
</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>seo</span>, <span class='post-tag'>google</span>, <span class='post-tag'>bing</span>, <span class='post-tag'>sitemap</span>, <span class='post-tag'>ppcwithoutpity</span></span>
<span class='post-timestamp'>Posted on September 18, 2012 @ 11:59AM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-14.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-14-thumb-100' alt='Screenshot of site after post #14'></a></span>
</div>
<div class='blog-post-guid'>7559decd-05a3-49f5-ac1b-81248aa6789d</div>
</article>
<article class='blog-post' id='blog-post-13'>
<div class='blog-post-header'>
<h2>Post 13: Image Thumbnails</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/266bee8839e36297db1fe4256ff1d3e331712c52' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Way back in <a href='#blog-post-8'>Post 8</a> I mentioned 2 ways to reduce the impact of images on bandwidth. The method I tackled then was to automatically compress the png images in the build script. In this post, I will show you how to further reduce the impact by creating and displaying thumbnails instead of scaling down the original image using HTML (<code>&lt;img ... <strong>width=100</strong> /&gt;</code>).
<figure>
<img src='img/blog/posts/post-13-request-payload-before-thumbnails-chart.png' alt='Request payload before thumbnails'>
<figcaption>Request payload before using thumbnails (inspected using Firefox, <a href='http://getfirebug.com/' target='_blank' rel='nofollow'>FireBug</a>, and <a href='http://developer.yahoo.com/yslow/' target='_blank' rel='nofollow'>YSlow</a> plugin)</figcaption>
</figure>
<p>As you can see from the chart, fully 98% of the data that users have to download from the site is for images. Of those 24 images, 12 were fullsize blog post screenshots, which weighed in at a portly 1.17MB. Those 12 little screenshot previews accounted 77% of the size for the entire page - and that is after we compressed the images to reduce about one-third of the filesize.
<p>I made a sample thumbnail by resizing the image down to 100 pixels wide produced a new preview image that was 90% smaller than the original. The prospect of reducing 77% of the entire request payload by 90% got me excited.
<p>Given that I still despise the copy/paste portion of creating new blog posts, and knowing that I don&#39;t want to make it harder on myself to release a blog post, I wanted a solution that was 100% automated. There already exists a <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat' target='_blank'>build script for this site</a> so I knew that I wanted to tie into that step.
<div id='wrapper-gist-3739310'>loading gist...</div>
<p>Notes on the batch file:
<ul>
<li>The <code>FOR</code> loop gets a list of all of the screenshot files that don&#39;t have &quot;thumb&quot; in the name</li>
<li><code>SETLOCAL ENABLEDELAYEDEXPANSION</code> is special inside of loops so that variables can be set with each iteration</li>
<li>A new thumbnail file is only created if one does not exist already</li>
<li><code>convert.exe</code> file comes from the free image utility library <a href='http://www.imagemagick.org' target='_blank' rel='nofollow'>ImageMagick</a></li>
</ul>
<p>The result is that the sum total filesize of the first 12 post thumbnail images is 111KB (a savings of over 1 megabyte). I also removed the <code>width=100</code> attributes from the previews as they are no longer necessary. Not too shabby for a few lines of code added to the build script.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>images</span>, <span class='post-tag'>bandwidth</span>, <span class='post-tag'>batchfile</span>, <span class='post-tag'>build</span>, <span class='post-tag'>tools</span>, <span class='post-tag'>thumbnail</span></span>
<span class='post-timestamp'>Posted on September 17, 2012 @ 2:55PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-13.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-13-thumb-100' alt='Screenshot of site after post #13'></a></span>
</div>
<div class='blog-post-guid'>6bbfc7bf-2561-4cd0-a384-5574f714e51a</div>
</article>
<article class='blog-post' id='blog-post-12'>
<div class='blog-post-header'>
<h2>Post 12: Favicon</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/45555907c121025acf277bd2f7200b3b5417a166' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Alrighty. Today's post is simple - but something that is very visible to users. The Favicon.
<p>A Favicon is the little icon that appears in the browser tab/address bar.
<figure>
<img src='img/blog/posts/post-12-favico-browser-comparo.png' alt='Favicon browser comparison'>
<figcaption>Favicons as they are shown in Firefox 14, Chrome 21, and Internet Explorer 9</figcaption>
</figure>
<p>In 1999, Microsoft introduced Favicons for the purpose of having an icon to display in the Favorites (bookmarks) menu on Internet Explorer. 2 things were done that (nowadays) goes against some web principles:
<ol>
<li>Use of the Windows .ico file format
<ul><li>example: favicon.ico instead of favicon.jpg</li></ul>
</li>
<li>Default convention for the file location off the root of the site&#39;s domain URL, which meant the location didn&#39;t have to be specified in HTML
<ul>
<li>www.aaronkmurray.com/favicon.ico</li>
<li>This limits the webmaster&#39;s ability to place the file anywhere, or even on a different server, without mapping OS folders or making URL-rewrite rules (we&#39;ll cover those later)</li>
</ul>
</li>
</ol>
<p>As a result, even though you can now specify any location and filetype that you want for your favicon, I still recommend serving an actual favicon.ico from your root for 2 reasons:
<ol>
<li>Many browsers and RSS readers will still make requests to this location looking for an icon</li>
<li>You&#39;ll cut down on the 404 (File Not Found) error noise that will show up in your hit logging</li>
</ol>
<p>Adding a modern Favicon is simple: <code>&lt;link rel=&#39;icon&#39; href=&#39;/favicon.png&#39; type=&#39;image/png&#39; /&gt;</code>
<p>But you should still slap a <a href='/favicon.ico' target='_blank' rel='nofollow'>favicon.ico</a> in your root.
<p>If you don&#39;t know how to make a <a href='http://en.wikipedia.org/wiki/ICO_(file_format)' target='_blank' rel='nofollow'>.ico file</a>, you can use a free site like <a href='http://www.convertico.com/' target='_blank' rel='nofollow'>convertico.com</a> to upload an image and get an .ico file back.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>favicon</span>, <span class='post-tag'>icon</span></span>
<span class='post-timestamp'>Posted on September 14, 2012 @ 4:51PM</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-12.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-12-thumb-100' alt='Screenshot of site after post #12'></a></span>
</div>
<div class='blog-post-guid'>2ee06cd8-f5d6-46b4-ba6f-62aeb1c2ecf9</div>
</article>
<article class='blog-post' id='blog-post-11'>
<div class='blog-post-header'>
<h2>Post 11: RSS Fix to Stop Spamming Readers</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/e91b6cf36a5f32d45ffe545a0a1b38ab8d7517f3' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Bugs! Already there are bugs :)
<p>A colleague of mine mentioned to me that whenever I release a new post, his reader fills shows that <em>all</em> of the posts appear as new posts.
<p><img src='img/blog/posts/post-11-google-reader.png' alt='Google Reader showing multiple new posts with each post'>
<p>This is an interesting problem caused by the fact that I wasn&#39;t defining a <code>&lt;guid&gt;</code> element in the RSS feed, nor a corresponding <code>&lt;id&gt;</code> element in the atom feed. These elements are what feed readers (like Google Reader) use to determine if a post/entry is new or not. If the entry doesn&#39;t have an ID, it&#39;ll always be treated as new. Obviously I need to add these Ids.
<p>So, how should I choose a unique Id for each post? Some say that a <a href='http://www.taguri.org/' target='_blank' rel='nofollow'>TAG Uri</a> should be used. While that seems like a nice way to ensure the creation of a unique id, I don&#39;t really want to put a lot of effort into building these Ids by hand (since we're still not using a DB yet). Additionally, I don&#39;t care what the Ids are because they are only going to be used by machines, so they don&#39;t need to be fancy.
<p>I think this solution calls for a <a href='http://en.wikipedia.org/wiki/Globally_unique_identifier' target='_blank' rel='nofollow'>Guid</a>. In fact, RSS feeds explicitly have an element for it. Bingo.
<p>The next step was realizing that I didn&#39;t want to have another manual step in the process of releaing a new post. I don&#39;t want to <a href='http://www.guidgenerator.com/online-guid-generator.aspx' target='_blank' rel='nofollow'>generate</a> <a href='http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx' target='_blank' rel='nofollow'>a</a> <a href='http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html#randomUUID()' target='_blank' rel='nofollow'>guid</a> by hand each time. I also didn&#39;t want to store a list of guids that are mapped to blog posts in some external file.
<p>My solution for now while we&#39;re still in hand-coding mode is to add a step to rssgen that will search for a guid in each post, and if it doesn&#39;t find one, it adds it.
<p>That means that as a write a post, in the post html I have this empty stub:
<ul><li><code>&lt;div class=&#39;blog-post-guid&#39;&gt;</code></li></ul>
<p>I <a href='https://github.com/akmurray/aaronkmurray-blog-tools/commit/70f220e27e750a3f7b339b7bcb7310e0e63620d6' target='_blank'>updated rssgen</a> to add the guids inside those stubs, and then re-save the index.html file during the build process. And if I ever want to resend an update out for an old post, I can simply update the guid.
<p>This project is pretty interesting for me so far. These solutions are not the way I normally operate because I typically stand on the shoulders of giants and leverage frameworks that handle many of the details like this. My hope is that the readers learn a few things along the way, though I have a feeling that this project just may radically challenge many of my standard processes and assumptions about web development.
<p><strong>UPDATE</strong> September 14, 2012:
<p>Ironically, I had to add more changes to keep from spamming the feed readers. The changes included keeping the date timestamps from changing which would trigger a refetch/display as well.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>rss</span>, <span class='post-tag'>rssgen</span>, <span class='post-tag'>guid</span></span>
<span class='post-timestamp'>Posted on September 11, 2012 @ 12:05pm</span>
<span class='post-timestamp-updated'>Last Updated on September 14, 2012 @ 5:15pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-11.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-11-thumb-100' alt='Screenshot of site after post #11'></a></span>
</div>
<div class='blog-post-guid'>e8a8715f-24dd-44c4-9655-0aac79284aa1</div>
</article>
<article class='blog-post' id='blog-post-10'>
<div class='blog-post-header'>
<h2>Post 10: The SEO Plan</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/18d9668f9164739eb7bd40ec7d305dd82fcdb66b' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>As outlined in <a href='#blog-post-1'>The Plan</a>, a major goal for this site is to provide an inside view on creating a website from the ground up. Large parts of that inside-out view is a visual history as well as full source code with revision history. While that captures the technical aspects of the site, there are other components that go into making a site.
<p>I hinted at this in <a href='#blog-post-4'>Post 4: For the Machines</a>. Another major component for creating a site is the plan to go from simply being &quot;out there on the Internet&quot; to being easy to find from any major search engine. Much of the steps that need to be taken are lumped into the phrase <a href='http://en.wikipedia.org/wiki/Search_engine_optimization' target='_blank' rel='nofollow'>Search Engine Optimization</a>, or SEO for short.
<p>This is probably the most overlooked part of developing a site. Next week I&#39;m going to start a 4-part series on SEO, in collaboration with guest author <a href='http://ppcwithoutpity.com/' target='_blank'>Shawn Livengood who runs the blog ppcwithoutpity.com</a>.
<p>The prep for that series, it is prudent to start tracking some key SEO metrics as soon as possible. That way we&#39;ll be able to see how the changes affect those metrics over time.
<p>I won&#39;t go into too much detail know about each of these metrics, but here they are captured for historical purposes:
<ul>
<li>From Google:
<ul>
<li><a href='http://en.wikipedia.org/wiki/PageRank' target='_blank' rel='nofollow'>PageRank</a>: 0/10</li>
</ul>
</li>
<li>From <a href='http://www.seomoz.org/' target='_blank' rel='nofollow'>seoMoz</a> and <a href='http://www.opensiteexplorer.org' target='_blank' rel='nofollow'>opensiteexplorer.org</a>:
<ul>
<li><a href='http://www.seomoz.org/learn-seo/domain-authority' target='_blank' rel='nofollow'>Domain Authority</a>: <a href='http://www.opensiteexplorer.org/links?site=www.aaronkmurray.com' target='_blank' rel='nofollow'>10/100</a></li>
<li><a href='http://www.seomoz.org/learn-seo/mozrank' target='_blank' rel='nofollow'>MozRank</a>: <a href='http://moonsy.com/mozrank/' target='_blank' rel='nofollow'>2.97</a></li>
<li>Linking Root Domains: <a href='http://www.opensiteexplorer.org/domains?site=www.aaronkmurray.com' target='_blank' rel='nofollow'>2</a></li>
<li>Total Links (inbound): <a href='http://www.opensiteexplorer.org/links?site=www.aaronkmurray.com' target='_blank' rel='nofollow'>5</a></li>
</ul>
</li>
</ul>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>SEO</span>, <span class='post-tag'>PageRank</span>, <span class='post-tag'>MozRank</span></span>
<span class='post-timestamp'>Posted on September 11, 2012 @ 9:25am</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-10.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-10-thumb-100' alt='Screenshot of site after post #10'></a></span>
</div>
<div class='blog-post-guid'>9b04f8d9-f240-4ce7-9eea-44c76137e097</div>
</article>
<article class='blog-post' id='blog-post-9'>
<div class='blog-post-header'>
<h2>Post 9: IIS Static File Compression in web.config</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/70c9344d99d8d1025a7597cd8edba384d28a48c7' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Quick post here, while we're on the topic of saving a few bytes. I&#39;m making 2 changes that will save some bandwidth:
<ol>
<li>Removing the useless Response Header &quot;X-Powered-By&quot; that gets added by IIS</li>
<li>Configure text (html, css) and javascript (js, json) files to be gzip&#39;d automatically when the browser can handle it (ex: Accept-Encoding:gzip)</li>
</ol>
<figure>
<img src='img/blog/posts/post-9-request-sniff-1.png' alt='Request details before web.config changes'>
<figcaption>Request details before web.config changes (inspected using Chrome Developer Tools)</figcaption>
</figure>
<p>First of all - the Response Header &quot;X-Powered-By&quot; is a waste of 20 incompressible bytes (because they are in the header and the older HTTP protocol <a href='http://stackoverflow.com/questions/5333367/http-header-compression' target='_blank' rel='nofollow'>does not support header compression</a> like the <a href='http://en.wikipedia.org/wiki/SPDY' target='_blank' rel='nofollow'>SPDY protocol</a> does). From now on, every response sent from webserver will be 20 bytes lighter. Sweet!
<p>Secondly, we want to make sure that text files get compressed before they are sent to the client. Typically you can expect gzip&#39;d files to be fully 2/3rds smaller than their uncompressed bretheren. In the case of this home page (index.html), the payload went from a hearty 39.67KB to a relatively svelte 12.83KB - a 67.7% savings!
<figure>
<img src='img/blog/posts/post-9-request-sniff-2.png' alt='Request details after web.config changes'>
<figcaption>Request details after web.config changes: gzip&#39;d index.html payload is 67.7% smaller</figcaption>
</figure>
<p>Put this code in your web.config file and enjoy.
<div id='wrapper-gist-3694724'>loading gist...</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>web.config</span>, <span class='post-tag'>IIS</span>, <span class='post-tag'>compression</span>, <span class='post-tag'>headers</span></span>
<span class='post-timestamp'>Posted on September 10, 2012 @ 6:30pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-9.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-9-thumb-100' alt='Screenshot of site after post #9'></a></span>
</div>
<div class='blog-post-guid'>5f6842bd-df6f-402d-b451-a7447d247db5</div>
</article>
<article class='blog-post' id='blog-post-8'>
<div class='blog-post-header'>
<h2>Post 8: Automatic Image Compression</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/cc4a47493fa67f731f53abb9048cc1701cb979eb' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Alrighty, let&#39;s talk about bandwidth for a moment. Two and a half weeks ago, this site was started as a single HTML page and no external file includes aside from a screenshot. The purpose of the screenshot was to capture a visual change history of the blog so that readers could easily see how the site changed with each post without having to get the <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>code from github</a> at a certain point in time and view the site locally.
<p>These images are saved as <a href='http://en.wikipedia.org/wiki/Portable_Network_Graphics' target='_blank' rel='nofollow'>PNG</a> files, which is a lossless image format meaning that all of the original image data is still intact. Unlike <a href='http://en.wikipedia.org/wiki/JPEG' target='_blank' rel='nofollow'>JPEG</a> files, PNG files won&#39;t mess with the fine details of your image in order to make the file size smaller. This is both good and bad.
<figure>
<img src='img/blog/posts/post-8-png-vs-jpg.png' alt='PNG vs JPEG visual comparison. Source: jonmiles.co.uk'>
<figcaption>Image comparing PNG (left) vs JPEG (right) detail</figcaption>
</figure>
<p>The upside is that the screenshots look just like my screen did when I took them. The downside is that the files are bigger than a comparative jpeg file.
<p>So there are two main actions that should be taken here:
<ol>
<li>Reduce the filesize via compression utilities</li>
<li>Create separate thumbnail images and reference those for the previews</li>
</ol>
<p>For this post, I decided to tackle the compression issue first, even though creating thumbnails would have a bigger effect, simply because the utility that I wrote is more useful universally.
<p>The utility I just created, called <a href='https://github.com/akmurray/aaronkmurray-blog-tools/imgsqz' target='_blank'>imgsqz</a> (image squeeze for lack of creativity), has the following purpose:
<ul>
<li>Be executed as part of the &quot;Build&quot; process for this site</li>
<li>Batch process entire folders full of images to compress them</li>
<li>Not waste time try to recompress images that have already been compressed (because compression can take a long time)</li>
</ul>
<p>I&#39;ve checked in the tool so that you can look through the source code, but effectively just digs through a folder (and subfolders) looking for PNG files, and then trying to compress them. It keeps track of the files that it has compressed so that subsequent runs are only working on new/changed files. Using it is fairly simple:
<p><code>imgsqz.exe -s=c:\FolderWithImages</code>
<p>it&#39;s now part of the <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat' target='_blank'>build script for this site</a>, so that all PNG images from now on will be optimized before they hit the Internet for consumption.
<p>Here are the results for some of the files on this site:
<table id='table-png-compression-results'>
<tr><th>File</th><th>Original Size</th><th>New Size</th><th>% Saved</th></tr>
<tr><td><a href='img/blog/screenshots/post-1.png' target='_blank' rel='nofollow'>img/blog/screenshots/post-1.png</a></td><td>103 KB</td><td>86 KB</td><td>16.4%</td></tr>
<tr><td><a href='img/blog/screenshots/post-2.png' target='_blank' rel='nofollow'>img/blog/screenshots/post-2.png</a></td><td>90 KB</td><td>74 KB</td><td>17.7%</td></tr>
<tr><td><a href='img/blog/screenshots/post-3.png' target='_blank' rel='nofollow'>img/blog/screenshots/post-3.png</a></td><td>97 KB</td><td>68 KB</td><td>30.2%</td></tr>
<tr><td><a href='img/blog/screenshots/post-4.png' target='_blank' rel='nofollow'>img/blog/screenshots/post-4.png</a></td><td>88 KB</td><td>49 KB</td><td>44.8%</td></tr>
<tr><td><a href='img/blog/screenshots/post-5.png' target='_blank' rel='nofollow'>img/blog/screenshots/post-5.png</a></td><td>122 KB</td><td>104 KB</td><td>13.3%</td></tr>
<tr><td><a href='img/blog/icons/icon-rss-32.png' target='_blank' rel='nofollow'>img/blog/icons/icon-rss-32.png</a></td><td>1,659 bytes</td><td>1,571 bytes</td><td>5.3%</td></tr>
<tr><td><a href='img/blog/logo/logo-1.png' target='_blank' rel='nofollow'>img/blog/logo/logo-1.png</a></td><td>5,025 bytes</td><td>3,181 bytes</td><td>36.7%</td></tr>
</table>
<p>Each KB of savings is worth a tiny bit of load time and a tiny bit of bandwidth. Over time these savings will add up nicely.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>images</span>, <span class='post-tag'>compression</span>, <span class='post-tag'>bandwidth</span>, <span class='post-tag'>build</span>, <span class='post-tag'>tools</span>, <span class='post-tag'>imgsqz</span></span>
<span class='post-timestamp'>Posted on September 10, 2012 @ 5:05pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-8.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-8-thumb-100' alt='Screenshot of site after post #8'></a></span>
</div>
<div class='blog-post-guid'>9d61cdb5-c803-43cf-a5d8-644839b870a9</div>
</article>
<article class='blog-post' id='blog-post-7'>
<div class='blog-post-header'>
<h2>Post 7: Links to GitHub</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/b734038a5587fcbae1e8d3e317d7c06c48e18cd7' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Quick post here - I just added links to <a href='https://github.com/akmurray/aaronkmurray-blog/commits/master' target='_blank'>each Post&#39;s main commit on github</a> in the post header. Just click on the <a href='https://github.com/akmurray/aaronkmurray-blog/commit/b734038a5587fcbae1e8d3e317d7c06c48e18cd7' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a> icon to see what was changed.
<p>The purpose is to make it easy to see what changed with each post, but it causes an interesting flow change for &quot;releasing&quot; a post because I need to make a post, and then commit the change, but then edit the post to add the new link to the change on GitHub.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>github</span>, <span class='post-tag'>commit</span></span>
<span class='post-timestamp'>Posted on September 8, 2012 @ 2:00pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-7.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-7-thumb-100' alt='Screenshot of site after post #7'></a></span>
</div>
<div class='blog-post-guid'>6825317b-ba31-4a4c-acba-67d52dfc44ca</div>
</article>
<article class='blog-post' id='blog-post-6'>
<div class='blog-post-header'>
<h2>Post 6: Traffic Analytics</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/f61bdfc72b758ae365f73d4c108f44628fcbd34a' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Now that we&#39;ve got a way for visitors to subscribe to the site to get notified when new posts happen, let&#39;s start capturing traffic stats using <a href='https://www.quantcast.com/aaronkmurray.com' target='_blank' rel='nofollow'>Quantcast</a>.
<p>After you sign up for a free/basic Quantcast account, you can &quot;start quantifying&quot; your traffic by entering your domain name and generating a snippet of html/js that will ping their servers each time someone loads up your page. Simply slap that down at the bottom of your page for now, and we can start getting a rough idea of traffic stats.
<p>That snippet is polite because it does 2 things:
<ul>
<li>Try to load the tracking script using the <a href='http://davidwalsh.name/html5-async' target='_blank' rel='nofollow'>async attribute</a>, which <a href='http://www.stevesouders.com/blog/2012/01/13/javascript-performance/' target='_blank' rel='nofollow'>speeds</a> up the responsiveness of the site</li>
<li>Fallback to <a href='http://www.ehow.com/how_5277834_use-pixel-tracking.html' target='_blank' rel='nofollow'>pixel tracking image</a> when javascript is unavailable</li>
</ul>
<p>Simple, effective, and good enough for now.
<p>Note: it will take a few days before the stats for this site show up on Quantcast.
<div id='wrapper-gist-3678669'>loading gist...</div>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>quantcast</span>, <span class='post-tag'>tracking</span>, <span class='post-tag'>traffic</span>, <span class='post-tag'>async</span></span>
<span class='post-timestamp'>Posted on September 7, 2012 @ 5:00pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-6.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-6-thumb-100' alt='Screenshot of site after post #6'></a></span>
</div>
<div class='blog-post-guid'>1497a7a5-638d-4fb2-b51c-94d67f6cc9f2</div>
</article>
<article class='blog-post' id='blog-post-5'>
<div class='blog-post-header'>
<h2>Post 5: RSS, Atom, and Build Tools</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/5eb387dd03581340da8bfd120200f0666123c6d2' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Alrighty - creating a new blog these days pratically assumes that readers will be provided with an <a href='http://en.wikipedia.org/wiki/RSS' target='_blank' rel='nofollow'>RSS</a> or <a href='http://en.wikipedia.org/wiki/Atom_(standard)' target='_blank' rel='nofollow'>Atom</a> feed so that readers can &quot;subscribe&quot; and get notified when new posts are made. I don&#39;t even follow blogs that lack such a basic service feature.
<p>Ironically, in the interest of starting from absolute square 1, this blog lacked an <a href='http://aaronkmurray.com/feeds/feed-rss.xml' target='_blank' rel='nofollow'>RSS feed</a>. That was one of the more challenging pieces that I had to get over mentally when considering doing a blog this way. Fortunately, the thought of losing potential followers was ultimately outweighed by the principle of the project.
<p>That said, getting an RSS feed up ASAP was <em>very important</em> to me...even more important than other basics like choosing a database. This leads to an interesting chicken/egg problem however. How will I provide an RSS feed without a database? Am I going to copy/paste even more HTML into an XML file for a RSS feed? What about the Atom feed? Should that be another set of copying/pasting/formatting? Should I just buck up, pick a db, but not mention it until later?
<p>Well, given that this site is a fairly unique project, I&#39;m open to fairly unique solutions as we trod down this path. So what is the solution to the feed problem? Parsing.
<p>Considering my disdain for copying and pasting, and the lack of a database to draw from, I wrote a <a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/rss/rssgen/rssgen' target='_blank'>little parser</a> that would read the HTML from this site and produce <a href='http://aaronkmurray.com/feeds/feed-rss.xml' target='_blank'>RSS</a> and <a href='http://aaronkmurray.com/feeds/feed-atom.xml' target='_blank' rel='nofollow'>Atom</a> feeds automatically.
<p>Running that tool now becomes the first step in the &quot;build&quot; process for this site. That means that the current process for making and releasing a change to this site is now:
<ul>
<li>Edit this index.html file</li>
<li>Run my new <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/build/build-aaronkmurray-site.bat'>build script</a></li>
<li>Commit and Push the changes to <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>github</a></li>
<li>Remote into the webserver hosting this site</li>
<li>Run my new <a href='https://github.com/akmurray/aaronkmurray-blog-tools/blob/master/release/release-aaronkmurray-site.bat'>release script</a></li>
</ul>
<p>While still far from ideal, this is better than <a href='#blog-post-1'>the original</a> process, and it highlights the important phases in the make/build/release process. In upcoming posts, we&#39;ll rely more heavily on these automation points and add many steps to them that handle many of the problems that still need to be solved.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>rss</span>, <span class='post-tag'>atom</span>, <span class='post-tag'>build</span>, <span class='post-tag'>tools</span>, <span class='post-tag'>command line</span>, <span class='post-tag'>build</span>, <span class='post-tag'>release</span></span>
<span class='post-timestamp'>Posted on September 7, 2012 @ 4:40pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-5.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-5-thumb-100' alt='Screenshot of site after post #5'></a></span>
</div>
<div class='blog-post-guid'>b4932981-4707-45e9-baff-adb57e36e1d6</div>
</article>
<article class='blog-post' id='blog-post-4'>
<div class='blog-post-header'>
<h2>Post 4: For the Machines</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/978f856970e0d2bd911583a61db4883f24e63cb1' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>The purpose of this post is to assist the machines that will be &quot;reading&quot; the site.
<p>There are a couple of simple things that we need to do:
<ul>
<li>Create a <a href='http://www.robotstxt.org/robotstxt.html' target='_blank' rel='nofollow'>robots.txt</a> file for communicating instructions with web crawlers</li>
<li>Add <code>&lt;meta&gt;</code> tags to help browsers and search engines</li>
</ul>
<p>You&#39;ll notice that this site&#39;s <a href='robots.txt' target='_blank' rel='nofollow'>robots.txt file</a> is fairly empty. One interesting note is the line <code>Disallow: /BadBotHoneyPot/</code>
<p>I&#39;ll go over that in the future, but for now, I&#39;ll just say that we&#39;ll use that as a trap to identify &quot;bad&quot; crawlers so that we can automatically block them should we choose.
<p>As for the <code>&lt;meta&gt;</code> tags:
<ul>
<li><code>&lt;meta charset=&#39;utf-8&#39;&gt;</code>
<ul>
<li>This meta tag needs to be near the top of the HTML file (before any text).</li>
<li>If it is not, or it is missing, then the browser will just try to figure out the character encoding set on it&#39;s own.</li>
<li>You will typically only run across the need to include this once you start dealing with localization of your site.</li>
<li>More info <a href='http://code.google.com/p/doctype-mirror/wiki/MetaCharsetAttribute' target='_blank' rel='nofollow'>here</a></li>
</ul>
</li>
<li><code>&lt;meta http-equiv=&#39;X-UA-Compatible&#39; content=&#39;IE=edge,chrome=1&#39;&gt;</code>
<ul>
<li>This tag basically does two things.</li>
<li>#1: Tell Internet Explorer to use it&#39;s <a href='http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx' target='_blank' rel='nofollow'>most modern mode available</a> (as opposed to IE trying to determine which mode it should run in for best compatibility)</li>
<li>#2: Tells browsers with <a href='http://www.chromium.org/developers/how-tos/chrome-frame-getting-started' target='_blank' rel='nofollow'>Google Chrome Frame</a> installed to render using GCF instead of their native renderer (Uncommon, mostly to help old slow browsers)</li>
</ul>
</li>
<li><code>&lt;meta name=&#39;author&#39; content=&#39;Aaron Murray, akmurray@gmail.com&#39;&gt;</code>
<ul>
<li>Tell the crawler who authored this page</li>
<li>Tell any users who view your source how to contact you if needed</li>
<li>This is more uncommon for sites that have multiple contributors</li>
</ul>
</li>
<li><code>&lt;meta name=&#39;description&#39; content=&#39;...&#39;&gt;</code>
<ul>
<li>This is a spot where you can describe your site</li>
<li>Some search engines will use this text as preview content</li>
<li>Adds some <a href='http://en.wikipedia.org/wiki/Search_engine_optimization' target='_blank' rel='nofollow'>SEO</a> value to your site</li>
</ul>
</li>
<li><code>&lt;meta name=&#39;viewport&#39; content=&#39;width=device-width&#39;&gt;</code>
<ul>
<li><a href='https://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html' target='_blank' rel='nofollow'>This tag</a> is largely useful once you start wanting to have your site look nice on <a href='http://www.nokia.com/gb-en/products/phone/700/' target='_blank' rel='nofollow'>small handheld</a> or <a href='http://arstechnica.com/gadgets/2011/11/microsofts-table-sized-tablet-surfaces-in-pre-order/' target='_blank' rel='nofollow'>giant surface devices</a></li>
<li>We&#39;ll dive deeper into this in the future, but we&#39;ve got too many bigger fish to fry at the moment</li>
</ul>
</li>
</ul>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>robots</span>, <span class='post-tag'>meta</span>, <span class='post-tag'>crawlers</span>, <span class='post-tag'>seo</span></span>
<span class='post-timestamp'>Posted on August 23, 2012 @ 11:15am</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-4.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-4-thumb-100' alt='Screenshot of site after post #4'></a></span>
</div>
<div class='blog-post-guid'>3c8edac9-4a60-4ab0-b335-e68b55329fee</div>
</article>
<article class='blog-post' id='blog-post-3'>
<div class='blog-post-header'>
<h2>Post 3: Basic Visual Cleanup</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/480dc9d7c9073ec3e91b12c26b6c157cc11143d6' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Alrighty, so we have a plan, we&#39;ve got the code up on <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>github</a> for the world to see, and we have made a couple small changes to make publishing *slightly* less painful via some scripts to automate a couple of steps.
<p>Despite my guts screaming out for functionality, something has to be done about the visuals around here. The look is way too 1994, and not in a cool 1994 sort of way.
<p>I&#39;m going to start attaching a screenshot of the site with each post so that in the future we can easily view the visual progress that is being made. This will be easier than checking out snapshot from the <a href='https://github.com/akmurray/aaronkmurray-blog/commits/master/' target='_blank'>github commit history</a> and running the site locally. In the future this will be harder for folks to do once we get distributed and have various databases powering the content. Fun stuff!
<p>Back to reality - let&#39;s spruce this place up. For all of the newbs out there, the best way to fancy up the visuals on a web page is to sprinkle a little <a href='http://www.w3schools.com/css/' target='_blank' rel='nofollow'>CSS</a> love around. Quickly you&#39;ll learn about one of the most loved (hated) aspects of web development: browser differences. Luckily there are <a href='http://www.alistapart.com/' target='_blank' rel='nofollow'>resources</a> out there to help. For now we won&#39;t get into the weeds, but let&#39;s just say that for nearly 2 decades we&#39;ve been struggling with browser differences and there is no end in sight, but at least there is a lot of <a href='http://html5.org/' target='_blank' rel='nofollow'>hope</a> that things will get better over the next decade as <a href='http://www.ie6countdown.com/' target='_blank' rel='nofollow'>older browsers start to die off</a>.
<p>Step 1: very basic <a href='http://en.wikipedia.org/wiki/User_interface' target='_blank' rel='nofollow'>UI</a>/<a href='http://en.wikipedia.org/wiki/User_experience_design' target='_blank' rel='nofollow'>UX</a> stuff:
<ul>
<li>Visually split up the site header from the posts</li>
<li>Split up the post from each other</li>
<li>Format certain types of text (<span>like code</span>)</li>
<li>Enable a way to link directly to a specific post</li>
<li>Add some content to the footer area of the page</li>
</ul>
<p>Let&#39;s assume that we&#39;ll use <code>&lt;div&gt;</code> tags for HTML structure/grouping, and that text should be in either a <code>&lt;span&gt;</code> or a <code>&lt;p&gt;</code> tag.
<p>Using css, we can add some a style for blog posts that have a <code>&lt;span&gt;</code> tag with a css class of <code>&lt;code&gt;</code>. These matching tags will be in a different monospace font to make look them more computery. Easy.
<ul>
<li><code>&lt;style&gt; .blog-post-body span.code {font-family: monospace, Courier, Lucidatypewriter; } &lt;/style&gt;</code></li>
</ul>
<p>To enabling linking directly to a post, we&#39;re going to use the old-school method of using <code>name</code> attributes and <code>#</code> links. I know this is absurd in the days of <a href='http://www.bloggingbasics101.com/2008/11/what-is-a-permalink/' target='_blank' rel='nofollow'>permalinks</a> and SEO friendliness, but we haven&#39;t written the permalink code yet, so we suffer for now. I&#39;m doing this for your own benefit here folks - it&#39;s my <a href='http://en.wikipedia.org/wiki/PageRank' target='_blank' rel='nofollow'>PageRank</a> that will suffer. When we fix this later, it&#39;ll also be a great time to talk about the joys of <a href='http://en.wikipedia.org/wiki/Code_refactoring' target='_blank' rel='nofollow'>refactoring</a> and <a href='http://en.wikipedia.org/wiki/Brownfield_(software_development)' target='_blank' rel='nofollow'>brown-field</a> upgrades.
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>css</span>, <span class='post-tag'>html</span></span>
<span class='post-timestamp'>Posted on August 22, 2012 @ 6:10pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-3.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-3-thumb-100' alt='Screenshot of site after post #3'></a></span>
</div>
<div class='blog-post-guid'>95f8c883-3c79-4f4c-87e0-71fd7c631a62</div>
</article>
<article class='blog-post' id='blog-post-2'>
<div class='blog-post-header'>
<h2>Post 2: Deploying New Posts</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/7d1cbce99a47e5b5e37f46c98293d5ab5821715d' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>Already there is pain. Currently, my brand new process when I want to write a new post is:
<ul>
<li>Open up my <a href='http://www.editplus.com/' target='_blank' rel='nofollow'>text editor</a> of choice</li>
<li>Copy and paste the HTML for a post from my previous post</li>
<li>Edit the old HTML</li>
<li>Save and preview the file (testing testing testing)</li>
<li>Fix my bugs (remember to edit the timestamp, post tags, etc)</li>
<li>Commit the changes to <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>github</a> using <a href='http://code.google.com/p/tortoisegit/' target='_blank' rel='nofollow'>TortoiseGit</a></li>
<li>Push the changes to <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>github</a> using <a href='http://code.google.com/p/tortoisegit/' target='_blank' rel='nofollow'>TortoiseGit</a> (Manually enter username and password each time in the prompt boxes)</li>
<li>Remote into the webserver hosting this site</li>
<li>Pull the changes from github to a local folder</li>
<li>Copy the files to the IIS folder hosting the site</li>
</ul>
<p>Ugh. No fun already. I know we can do better than that. First up, let&#39;s automate a couple of those steps.
<ul>
<li>Install <a href='http://msysgit.github.com/' target='_blank' rel='nofollow'>Git for Windows</a> (<a href='http://www.thegeekstuff.com/2012/02/git-for-windows/' target='_blank' rel='nofollow'>how-to</a>)</li>
<li>Select the option for &quot;Run Git from the Windows Command Prompt&quot; so that we can write scripts to do our work</li>
<li>Make sure that worked (open a Command Prompt, type in &quot;git&quot; and hit Enter</li>
<li>Clone the github repo to a local directory. <code>c:\code\git>git clone https://github.com/akmurray/aaronkmurray-blog c:\code\git\aaronkmurray-blog</code></li>
<li>Make a new Windows .bat file that will download latest code and copy to local website folder:
<ul>
<li><code>cd c:\code\git\aaronkmurray-blog</code></li>
<li><code>git pull https://github.com/akmurray/aaronkmurray-blog</code></li>
<li><code>xcopy /Y /E /R /V /I &quot;c:\code\git\aaronkmurray-blog&quot; &quot;C:\inetpub\wwwroot\aaronkmurray&quot;</code></li>
<li><code>REM pause</code></li>
</ul>
</li>
</ul>
<p>Now we can just run that file on the webserver and it&#39;ll fetch the latest source from github and push it to the website&#39;s folder.
<p>Next up, let&#39;s take out the step of entering a username/password each time when doing the <code>git push</code>. <a href='http://www.programmoria.com/2012/02/saving-tortoisegit-password.html' target='_blank' rel='nofollow'>Here is an article</a> that describes the simple step of creating a batch file, and then running it, enter your username and password, and it creates the file that TortoiseGit needs so that you don&#39;t have to enter those manually anymore.
<p>Far from perfect, but we&#39;re taking baby steps here ;)
<p>Article on <a href='http://longair.net/blog/2009/04/16/git-fetch-and-merge/' target='_blank' rel='nofollow'>git fetch vs pull</a>
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>git</span>, <span class='post-tag'>command-line</span></span>
<span class='post-timestamp'>Posted on August 22, 2012 @ 4:00pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-2.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-2-thumb-100' alt='Screenshot of site after post #2'></a></span>
</div>
<div class='blog-post-guid'>1a761ec2-aecf-43c2-a76f-4eebdabf6b51</div>
</article>
<article class='blog-post' id='blog-post-1'>
<div class='blog-post-header'>
<h2>Post 1: The Plan</h2>
<span class='commit-link'><a href='https://github.com/akmurray/aaronkmurray-blog/commit/be3aa221316ebdab153ab31f43d9c03b9df65fc3' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='View the code changes related to this post on github'></a></span>
</div>
<div class='blog-post-body'>
<p>This has been a long time coming.
<p>I&#39;ve been wanting to start blogging for about a year now, but have been struggling with figuring out where to start.
<p>There have been tons of questions swirling around in my head, like:
<ul>
<li>Blog: Roll my <a href='http://www.tandemgames.com/' target='_blank'>own</a> <a href='http://www.domainofheroes.com/' target='_blank'>site</a> <a href='http://www.aliensandrobots.com/' target='_blank'>again</a>? or use seasoned blog <a href='http://dasblog.codeplex.com/' target='_blank'>software</a> with <a href='http://wordpress.org/' target='_blank' rel='nofollow'>heavy community support</a>?</li>
<li>Host: Use a <a href='https://appharbor.com' target='_blank' rel='nofollow'>cloud</a> <a href='http://www.heroku.com/' target='_blank' rel='nofollow'>application</a> <a href='http://www.rackspace.com/cloud/public/sites/' target='_blank' rel='nofollow'>host</a>? Use a cheap host that <a href='http://bluehost.com/' target='_blank' rel='nofollow'>supports simple scripts</a> for common apps? Host out of the <a href='img/blog/posts/post-1-aarons_server_rack.jpg' target='_blank' rel='nofollow'>server rack in my house</a>?</li>
<li>Platform: Java? .NET? &quot;pure&quot; HTML/JS? <a href='http://expect.sourceforge.net/cgi.tcl/'>TCL/CGI</a>? Something more <a href='http://rubyonrails.org/' target='_blank' rel='nofollow'>hip</a>?</li>
<li>Audience: Should I be connecting with <a href='http://lostechies.com/' target='_blank' rel='nofollow'>other developers</a>? Other small-business owners? Friends? Family? </li>
<li>Content: Is this going to be a personal activity log? Professional journal? Or just another tech experiement?</li>
</ul>
<p>As I poured through ideas and wrote down reams of notes, one thing was apparent: <span class='callout'>I was spending a lot of time and effort on the blog but not actually blogging.</span>
<p>Last night I couldn&#39;t sleep. The kid&#39;s toy keyboard was &quot;cleaned up&quot; in a way that a key was being pressed repeatedly whenever the air conditioning changed the pressure in the play room. I finally got up to address the situation, and then found myself unable to fall back to sleep.
<p>After laying in bed for a couple of hours thinking about the blog, I finally got up to write down my ideas on paper so that I could actually fall asleep. This is common for me: the fear of forgetting an idea keeping me from drifting off into sleepytown.
<p>This morning I get into work and checked on my RSS feed folder for .NET development. it&#39;s been a few days since I checked it, but <a href='http://www.hanselman.com/blog/YourWordsAreWasted.aspx' target='_blank'>this call-to-action from Scott Hanselman</a> was the final straw. The answer is simply to start blogging now and sort out the details later.
<p>So what&#39;s the plan? Well, the plan is:
<ul>
<li>Roll my own site/blog from the ground up</li>
<li>Hosted at my house in my server rack</li>
<li>Post about all of the changes and more importantly, show the intention behind them</li>
<li>Make this site <a href='https://github.com/akmurray/aaronkmurray-blog' target='_blank'>publicly available on github</a> so that everyone can see how it works and see it progress</li>
<li>Start with a single index.html file and advance the site it all the way through to a scalable, distributed system, from the ground up</li>
</ul>
<p>Ultimately, I&#39;d like to think that someone new to the web development craft will be able to use this site, the posts, and the source code history as a guide to seeing what goes on behind the scenes for how to create modern web software. I&#39;m going to start at absolute step 1, and advance steadily through the growth of a real application.
<p>I&#39;d love it if you followed me on this journey. It&#39;d be great if you could sign up for an RSS feed to get auto-notifications when I make new posts, but since this is just an index.html file at the moment, you can&#39;t. Looks like we&#39;ve got a lot of work to do. Get ready for a fun ride.
<p>For now, you can reach me on <a href='https://twitter.com/aaronkmurray' target='_blank'>Twitter @aaronkmurray</a>. Let me know what you think about this project and what features you&#39;d like to see implemented. Here&#39;s a sample of what I have planned already:
<ul>
<li>Basics: CSS reset, JS framework, Cloud/CDN hosting</li>
<li>Javascript: organizing your JS files (custom and 3rd-party), creating your own framework patterns, debugging</li>
<li>CSS: responsive design, image bundling/sprites</li>
<li>Build/Deploy: tools for building, bundling, and deploying the site and assets</li>
<li>Performance: optimizing response time, payload, client-side caching, server-side caching, web-server and load balancer config</li>
<li>Debugging: client-side debugging, server-side debugging, error logging, pro-active notifications, self-healing services, system health dashboards and reports</li>
<li>Testing: js unit testing, server-side testing, integration testing</li>
<li>Database: choosing a DB, using an ORM (like Entity Framework), writing your own ORM</li>
<li>Marketing: strategy, considerations, tracking and mining your own site data</li>
<li>Social: integration with the Majors (Facebook, Twitter, Instagram, Pinterest, etc.), API usage, tracking</li>
<li>Advanced: client-side MVC, new JS paradigms and protocols for server communication, custom DBMS!</li>
</ul>
<p>As you can see, that is a reasonably ambitious sampling of goals since we&#39;re starting with a single HTML page and no code. Let&#39;s get cracking!
</div>
<div class='blog-post-footer'>
<span class='post-tags'>Tags: <span class='post-tag'>site-story</span>, <span class='post-tag'>insomnia</span>, <span class='post-tag'>plan</span>, <span class='post-tag'>twitter</span>, <span class='post-tag'>git</span></span>
<span class='post-timestamp'>Posted on August 22, 2012 @ 3:00pm</span>
<span class='post-screenshot'><a href='img/blog/screenshots/post-1.png' target='_blank' rel='nofollow'><img src='img/blog/clear.gif' class='img-post-1-thumb-100' alt='Screenshot of site after first post'></a></span>
</div>
<div class='blog-post-guid'>a882e042-86e5-4d3e-b1c7-f970cf2e0769</div>
</article>
</div>
<div id='wrapper-sidebar'>
<div id='wrapper-blog-post-menu'>
<div class='menu-header'>Posts</div>
<ul>
<li><a href='#blog-post-1'>Post 1: The Plan</a></li>
<li><a href='#blog-post-2'>Post 2: Deploying New Posts</a></li>
<li><a href='#blog-post-3'>Post 3: Basic Visual Cleanup</a></li>
<li><a href='#blog-post-4'>Post 4: For the Machines</a></li>
<li><a href='#blog-post-5'>Post 5: RSS, Atom, and Build Tools</a></li>
<li><a href='#blog-post-6'>Post 6: Traffic Analytics</a></li>
<li><a href='#blog-post-7'>Post 7: Links to GitHub</a></li>
<li><a href='#blog-post-8'>Post 8: Automatic Image Compression</a></li>
<li><a href='#blog-post-9'>Post 9: IIS Static File Compression in web.config</a></li>
<li><a href='#blog-post-10'>Post 10: The SEO Plan</a></li>
<li><a href='#blog-post-11'>Post 11: RSS Fix to Stop Spamming Readers</a></li>
<li><a href='#blog-post-12'>Post 12: Favicon</a></li>
<li><a href='#blog-post-13'>Post 13: Image Thumbnails</a></li>
<li><a href='#blog-post-14'>Post 14: SEO Part 1/4: Getting Indexed</a></li>
<li><a href='#blog-post-15'>Post 15: CSS Includes</a></li>
<li><a href='#blog-post-16'>Post 16: HTML Markup Cleanup</a></li>
<li><a href='#blog-post-17'>Post 17: First Month Retrospective</a></li>
<li><a href='#blog-post-18'>Post 18: SEO Part 2/4: Optimizing Code Tags For SEO</a></li>
<li><a href='#blog-post-19'>Post 19: Fun With A CSS3 Cube</a></li>
<li><a href='#blog-post-20'>Post 20: CSS Sprites</a></li>
<li><a href='#blog-post-21'>Post 21: SEO Part 3/4: Linkbuilding</a></li>
<li><a href='#blog-post-22'>Post 22: Tuning Page Load Time</a></li>
<li><a href='#blog-post-23'>Post 23: CSS Resets and Organization</a></li>
<li><a href='#blog-post-24'>Post 24: SEO Part 4/4: Tracking SEO Results</a></li>
<li><a href='#blog-post-25'>Post 25: Automated Javascript Unit Tests</a></li>
<li><a href='#blog-post-26'>Post 26: Reduce HTTP Requests</a></li>
<li><a href='#blog-post-27'>Post 27: Build-time CSS Validation</a></li>
<li><a href='#blog-post-28'>Post 28: CSS Preprocessing using SASS</a></li>
<li><a href='#blog-post-28'>Post 29: Understanding Javascript Numbers</a></li>
</ul>
</div>
</div>
<div id='wrapper-site-footer'>
<div id='content-site-footer'>
<section class='contact'>
<h3>Stay in Touch</h3>
<ul>
<li><a href='https://twitter.com/aaronkmurray' target='_blank' title='Follow me on Twitter @aaronkmurray'><img src='img/blog/clear.gif' class='img-icon-twitter-16' alt='Twitter icon'> @aaronkmurray</a></li>
<li><a href='http://www.aaronkmurray.com' target='_blank' title='My Blog'><img src='img/blog/clear.gif' class='img-icon-aaronkmurray-16' alt='Blog icon'> Blog</a></li>
<li><a href='https://github.com/akmurray' target='_blank' title='View the code for this site on GitHub'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='GitHub icon'> GitHub</a></li>
<li><a href='http://aaronkmurray.com/feeds/feed-rss.xml' target='_blank' title='Subscribe via RSS'><img src='img/blog/clear.gif' class='img-icon-rss-16' alt='RSS icon'> RSS Feed</a></li>
<!--
<li><a href='https://plus.google.com/110489899179528047715' target='_blank' title='Find me on Google+'><img src='img/blog/clear.gif' class='img-icon-googleplus-16' alt='Google+ icon'> Google+</a></li>
-->
</ul>
</section>
<section class='tools'>
<h3>Code &amp; Tools</h3>
<ul>
<li><a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/js-css/preprocessor' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='GitHub icon'> sass preprocessor</a></li>
<li><a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/img/imgsprite/imgsprite' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='GitHub icon'> imgsprite</a></li>
<li><a href='https://github.com/akmurray/aaronkmurray-blog-tools/tree/master/img/imgsqz/imgsqz' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='GitHub icon'> imgsqz</a></li>
<li><a href='https://gist.github.com/akmurray' target='_blank'><img src='img/blog/clear.gif' class='img-icon-github-16' alt='GitHub icon'> Aaron&#39;s Gists</a></li>
</ul>
</section>
<section class='share'>
<h3>Share...</h3>
<ul>
<li><span class='st_twitter' displaytext='Tweet'>&nbsp;</span></li>
<li><span class='st_digg' displaytext='Digg'>&nbsp;</span></li>
<li><span class='st_stumbleupon' displaytext='StumbleUpon'>&nbsp;</span></li>
<li><span class='st_reddit' displaytext='Reddit'>&nbsp;</span></li>
<!--
//['digg','stumbleupon','slashdot','reddit','google_reader','googleplus','dotnetshoutout','facebook','pinterest','twitter','linkedin','sharethis','email']
<li><span class='st_dotnetshoutout' displayText='DotNetShoutOut'>&nbsp;</span></li>
-->
</ul>
</section>
<section class='share'>
<h3>...more</h3>
<ul>
<li><span class='st_facebook' displaytext='Facebook'>&nbsp;</span></li>
<li><span class='st_linkedin' displaytext='LinkedIn'>&nbsp;</span></li>
<li><span class='st_googleplus' displaytext='Google+'>&nbsp;</span></li>
<li><span class='st_slashdot' displaytext='Slashdot'>&nbsp;</span></li>
<!--
//['digg','stumbleupon','slashdot','reddit','google_reader','googleplus','dotnetshoutout','facebook','pinterest','twitter','linkedin','sharethis','email']
<li><span class='st_dotnetshoutout' displayText='DotNetShoutOut'>&nbsp;</span></li>
-->
</ul>
</section>
<div class='copyright'><span>&copy; Copyright 2012 - 2013, <a href='https://twitter.com/aaronkmurray' target='_blank'>Aaron K. Murray</a></span></div>
</div>
</div>
<!-- Quantcast Fallback -->
<noscript><div style='display:none;'><img src='//pixel.quantserve.com/pixel/p-M_hV8wgLbE9k_.gif' border='0' height='1' width='1' alt='Quantcast'></div></noscript>
</div>
</body>
</html>