<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blogrescue.com</title>
	<atom:link href="http://blogrescue.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogrescue.com</link>
	<description>Technical Know-How in Human Terms</description>
	<lastBuildDate>Wed, 01 Feb 2012 20:24:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Back Button Mystery &#8211; IE Only</title>
		<link>http://blogrescue.com/2012/02/back-button-mystery/</link>
		<comments>http://blogrescue.com/2012/02/back-button-mystery/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 20:22:57 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[AdSense]]></category>
		<category><![CDATA[Back Button]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=431</guid>
		<description><![CDATA[I recently had a complaint from users of a site I support that the browser&#8217;s back button did not work when they visited the site. Further research showed that this is only happening on IE8 and IE9 (and possibly earlier versions that I&#8217;m too lazy test) and it is indeed a problem. It appears that [...]]]></description>
			<content:encoded><![CDATA[<div style='float:right;'><a href="http://blogrescue.com/wp-content/uploads/2012/02/ie.jpg"><img src="http://blogrescue.com/wp-content/uploads/2012/02/ie.jpg" alt="" title="ie" width="140" height="140" class="alignright size-full wp-image-432" /></a></div>
<p>I recently had a complaint from users of a site I support that the browser&#8217;s back button did not work when they visited the site.  Further research showed that this is only happening on IE8 and IE9 (and possibly earlier versions that I&#8217;m too lazy test) and it is indeed a problem. It appears that the issue is an incompatibility between Internet Explorer and Google Adsense and is pretty much a problem across a significant portion of the web as Adsense is used on so many sites (like this one).</p>
<p>The issue isn&#8217;t that the back button doesn&#8217;t work&#8230;it actually is working.  The real problem is that IE is adding every loaded advertisement as a new page loaded and updates the history accordingly.  This means that every time you press the Back button, you are moving back through IE&#8217;s history of the ads loaded on the page.  Once you&#8217;ve cycled back through every ad that has been served, pressing Back one more time will finally take you back to the previous page.  On the site in question, it takes 11 clicks of the back button to go to the previous page.  I&#8217;m planning on poking around a bit more but it really appears that there is not a known solution to this problem yet.</p>
<p>As serious as this is, I did find it amusing that the AdSense terms of service <a href='http://support.google.com/adsense/bin/answer.py?hl=en&#038;answer=1346295#Placing_ads_in_pop-up_windows'>expressly forbid</a> serving ads on a page where the navigation buttons are not provided, yet it is their code that is rendering these buttons inoperable on Internet Explorer:</p>
<blockquote><p>
Ads are not permitted in any window that is not initiated by a user&#8217;s click. Additionally, we do not permit ads to be placed in any window which lacks navigational controls, including back and forward browse buttons, and an editable URL field. AdSense ad code may also not be implemented on webpages where navigational elements have been removed.
</p></blockquote>
<p>In their defense, it does just state that the navigation buttons have to exist&#8230;and not that they have to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2012/02/back-button-mystery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 is Great, except on [lte IE 9]</title>
		<link>http://blogrescue.com/2012/01/html5-is-great-except-on-lte-ie-9/</link>
		<comments>http://blogrescue.com/2012/01/html5-is-great-except-on-lte-ie-9/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 22:47:59 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[IE]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=426</guid>
		<description><![CDATA[If you use HTML5 elements, they work great in all major browsers. However, the styles on the new elements will be ignored by IE7 and IE8. (IE6 is dead to me.) This is a pretty big deal since IE7 and IE8 have 3.2% and 10.7% of the browser marketshare (according to w3schools). Your site not [...]]]></description>
			<content:encoded><![CDATA[<p>If you use HTML5 elements, they work great in all major browsers.  However, the styles on the new elements will be ignored by IE7 and IE8.  (IE6 is dead to me.)</p>
<p>This is a pretty big deal since IE7 and IE8 have 3.2% and 10.7% of the browser marketshare (according to <a href='http://www.w3schools.com/browsers/browsers_explorer.asp'>w3schools</a>).  Your site not rendering properly for 14% of your traffic is a significant problem.</p>
<p>However, this doesn&#8217;t mean that using HTML5 is not possible.  Thanks to the <a href='http://remysharp.com/2009/01/07/html5-enabling-script/'>HTML5 Shiv</a>, very basic HTML5 now works in IE7 and IE8.  </p>
<p>Now if only tables, transparent backgrounds and z-indexes worked on IE7 and IE8.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2012/01/html5-is-great-except-on-lte-ie-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stepping Away from the Desk</title>
		<link>http://blogrescue.com/2012/01/stepping-away-from-the-desk/</link>
		<comments>http://blogrescue.com/2012/01/stepping-away-from-the-desk/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 21:19:38 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=422</guid>
		<description><![CDATA[How Your Brain May Get a Boost from Time Spent Outdoors: Deep in wilderness settings, detached from persistent electronic information input, I am a quieter, humbler, more alert, more appreciative, more empathetic, more reflective being. Beautiful day today &#8211; time to step away from technology and take a walk.]]></description>
			<content:encoded><![CDATA[<p><a href='http://findout.rei.com/blog_detail/?contentid=8370209246235413673'>How Your Brain May Get a Boost from Time Spent Outdoors</a>:</p>
<blockquote><p>
Deep in wilderness settings, detached from persistent electronic information input, I am a quieter, humbler, more alert, more appreciative, more empathetic, more reflective being.
</p></blockquote>
<p>Beautiful day today &#8211; time to step away from technology and take a walk.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2012/01/stepping-away-from-the-desk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vestigal Keys</title>
		<link>http://blogrescue.com/2012/01/vestigal-keys/</link>
		<comments>http://blogrescue.com/2012/01/vestigal-keys/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 23:41:53 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CapsLock]]></category>
		<category><![CDATA[Keyboard]]></category>
		<category><![CDATA[Shift]]></category>
		<category><![CDATA[Vestigal]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=418</guid>
		<description><![CDATA[The caps lock key has been a worthless key since it started appearing on computer keyboards. I&#8217;ve used (and learned to type on) an IBM Selectric where the key almost had a purpose. The IBM PC Keyboard as well as the VIC-20 / C64 both had them, and they continue to appear on keyboards where [...]]]></description>
			<content:encoded><![CDATA[<p>The caps lock key has been a worthless key since it started appearing on computer keyboards.  I&#8217;ve used (and learned to type on) an IBM Selectric where the key almost had a purpose.  The IBM PC Keyboard as well as the VIC-20 / C64 both had them, and they continue to appear on keyboards where they are not used, except by accident.</p>
<p>Why on earth haven&#8217;t I thought of disabling or changing their function before today, I have no idea.  But it is easy:</p>
<p><a href='http://www.howtogeek.com/howto/windows-vista/disable-caps-lock-key-in-windows-vista/'>Disable Caps Lock in Windows</a><br />
<a href='http://www.howtogeek.com/howto/38828/how-to-disable-caps-lock-on-mac-os-x/'>Disable Caps lock in Mac OS X</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2012/01/vestigal-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The 95 Queries</title>
		<link>http://blogrescue.com/2012/01/the-95-queries/</link>
		<comments>http://blogrescue.com/2012/01/the-95-queries/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 15:31:33 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[themes]]></category>
		<category><![CDATA[widgets]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=394</guid>
		<description><![CDATA[No, these are not something nailed to the door of the Wittenberg church. This is the number of queries generated on every page load on a lagging WordPress site I’ve been trying to speed up. The hosting is adequate and they are using a caching plugin and a CDN. They’ve done everything right but something [...]]]></description>
			<content:encoded><![CDATA[<p>No, these are not something nailed to the door of the Wittenberg church.  This is the number of queries generated on every page load on a lagging WordPress site I’ve been trying to speed up.  The hosting is adequate and they are using a caching plugin and a CDN.  They’ve done everything right but something is still very wrong.</p>
<p>A complicated theme will use extra queries and this is acceptable if you need extra loops or recent comments or other special items.  However, the key issue in this case is a theme framework with its significant overhead coupled with a sidebar employing 10 widget sections and over 30 different widgets.</p>
<p>I don’t want to sound like a broken record, but themes that allow the user to change settings within the WordPress interface generate overhead.  Widgets generate additional overhead.  For a high traffic site or even a significant burst of traffic, this can bring a site to its knees. </p>
<div style='width:300px; float:right;margin:5px 0 5px 5px;padding:4px;border:1px solid #ccc;'>
Curious how many queries your theme is generating?  Just add this code to the footer, just above the <code>&lt;/body&gt;</code> tag, load a page from your site and view the source to see how many queries were required to generate the page:</p>
<p><code style='margin:2px 5px;padding:0;color:#555;'>&lt;?php echo $wpdb-&gt;num_queries; ?&gt;<br />
&nbsp;&lt;?php _e('queries'); ?&gt;.<br />
&nbsp;&lt;?php timer_stop(1); ?&gt;<br />
&nbsp;&lt;?php _e('seconds'); ?&gt;</code></p>
<p>Keep in mind that a bare bones vanilla template with no overhead and no widgets and nothing in it at all still yields a baseline of 12 queries.
</p></div>
<p>How can you fix this problem?  Well, optimally, you recode the entire template so it doesn’t use any widgets or settings stored in the database.  Is this painful, expensive and unreasonable?  Yes, yes and no.  What if you are not currently in a place where recoding the template is reasonable?  Well, then you try to optimize what you can and get the query count as low as possible.</p>
<p>Most themes store settings in the WordPress options table and access them using the <a href='http://codex.wordpress.org/Function_Reference/get_option'><code>get_option()</code></a> function.  The theme set I’m trying to salvage uses <code>get_option()</code> 162 times.  Finding a way to reduce the impact of these calls is probably a good place to start.  Simply getting all the theme options in a single query and using cached values instead of reading them when needed should help reduce the number of total queries on each page.</p>
<p>To do this, first we need to figure out how to identify the theme specific options.  Usually there will be a prefix on each option name, so I’ve created a new function in functions.php that reads all the options with that prefix and then I call it:</p>
<pre>
function theme_cache_options($prefix) {
  global $wpdb;
  global $theme_cached_options;

  $sql = "SELECT option_name, option_value FROM ".$wpdb->prefix."options ".
        "WHERE option_name LIKE '%s' AND blog_id = %d";
  $prepared_sql = $wpdb->prepare($sql, $prefix.'%', get_current_blog_id() );
  $theme_cached_options = $wpdb->get_results($prepared_sql, OBJECT_K);
}
theme_cache_options(‘cow_’);
</pre>
<p>Second, we need a function that lets us read the cached option value:</p>
<pre>
function get_cached_option($key) {
  global $theme_cached_options;
  $result = isset($theme_cached_options[$key]) ?
        $result = $theme_cached_options[$key]->option_value : '';
  return $result;
}
</pre>
<p>Finally, we need to go through the theme itself, and change every <code>get_option()</code> call that references a theme setting to <code>get_cached_option()</code>.  Be sure <strong>not</strong> to change any option requests that do not start with the prefix specified in the <code>theme_cache_option()</code> call.</p>
<p>Does this help?  Well, it helps a little.  With the site I’m working on, I’m seeing roughly a 10% reduction in the number of queries.  Worth it?  I think so.</p>
<p><strong>Final note for theme developers:</strong>  If you are going to store theme options in the options table, there is a fourth parameter for the <a href=’ http://codex.wordpress.org/Function_Reference/add_option’><code>add_option()</code></a> function that you should really be aware of.  If you set </code>$autoload</code> to ‘yes’, then WordPress will automatically load and cache that option when it fires up.  This means that <code>get_option()</code> calls for any option that was created with <code>$autoload</code> set to ‘yes’ will not generate any additional queries.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2012/01/the-95-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Development: Send Tweet Action</title>
		<link>http://blogrescue.com/2011/12/android-development-send-tweet-action/</link>
		<comments>http://blogrescue.com/2011/12/android-development-send-tweet-action/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 15:57:21 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[tweet]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=381</guid>
		<description><![CDATA[I recently had a need within an Android application to provide a tweet button. It is really easy to launch a Share action in Android: Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + content); this.startActivity(Intent.createChooser(intent, "Share...")); This brings up a selection dialogue which presents the users with every app they have installed [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had a need within an Android application to provide a tweet button.  It is really easy to launch a Share action in Android:</p>
<pre>
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + content);
this.startActivity(Intent.createChooser(intent, "Share..."));
</pre>
<p>This brings up a selection dialogue which presents the users with every app they have installed on their device which handles a &#8220;text/plain&#8221; type request.  For most scenarios, this is the best way to go, although sometimes the list of applications can be a bit overwhelming.</p>
<p>However, I needed a &#8220;Tweet This&#8221; button related to the content that was being displayed.  Searching the net yielded a significant number of people asking exactly how to do this.  Some responses just chided the question, and advised strongly that the standard intent and letting the user choose from what they have installed is the right way to do it.  This isn&#8217;t bad advice, but I already have a social share button in this project that does exactly that.  The project requirements also include a dedicated &#8220;Tweet&#8221; button and it makes no sense for a button labeled &#8220;Tweet&#8221; to pull up a list that buries my Twitter client (or clients!) among Gmail, Facebook, Google+, Dropbox, Evernote, LinkedIn, GoogleVoice, and others.</p>
<p>This post details how I managed to pull it off.  I&#8217;m very aware that the solution is far from perfect and there is much room for improvement.  It doesn&#8217;t support every known Twitter client out there but it can be extended as needed.  The bottom line is it works, and the &#8220;Tweet&#8221; button actually tries to send a tweet.  After spending the better part of a day putting this together, I thought I would share it here and hope it helps someone else out also.</p>
<p><strong>Step 1</strong> involves building a list of supported Twitter clients.  This list can be easily expanded once you know the intent activity of any client.  I did this by installing the 7 clients in the list, looking at the list of intents and then adding them to the list and testing each one.  I hate hardcoding anything and I will probably move this list to arrays.xml down the line, but there really is not a better way to do this.  All of these save one (UberSocial) support the generic &#8220;text/plain&#8221; intent type, which yields no way to identify a twitter client other than knowing the activity name in advance.  (By the way, UberSocial supports the &#8220;application/twitter&#8221; intent type, which is a cool idea, however they are (as far as I know) the only client that supports this intent type which makes it pretty worthless at this point.)</p>
<p>Here is the code, which stores our supported Twitter Client list in a <em>Map&lt;String,String&gt;</em> named <em>knownTwitterClients</em>:</p>
<pre>
// Build list of Known Twitter Clients
private void buildKnownTwitterClientsList() {
	knownTwitterClients = new HashMap&lt;String, String&gt;();

	knownTwitterClients.put(&quot;Twitter&quot;, &quot;com.twitter.android.PostActivity&quot;);
	knownTwitterClients.put(&quot;UberSocial&quot;, &quot;com.twidroid.activity.SendTweet&quot;);
	knownTwitterClients.put(&quot;TweetDeck&quot;, &quot;com.tweetdeck.compose.ComposeActivity&quot;);
	knownTwitterClients.put(&quot;Seesmic&quot;, &quot;com.seesmic.ui.Composer&quot;);
	knownTwitterClients.put(&quot;TweetCaster&quot;, &quot;com.handmark.tweetcaster.ShareSelectorActivity&quot;);
	knownTwitterClients.put(&quot;Plume&quot;, &quot;com.levelup.touiteur.appwidgets.TouiteurWidgetNewTweet&quot;);
	knownTwitterClients.put(&quot;Twicca&quot;, &quot;jp.r246.twicca.statuses.Send&quot;);
}
</pre>
<p><strong>Step 2</strong> is comparing our list of known clients with apps actually installed on the device.  This is done by reading through the Intent Activities on the device and storing any that match our list of known Twitter Client.  This list is stored in a <em>Map&lt;String, ActivityInfo&gt;</em> named <em>foundTwitterClients</em>.</p>
<pre>
// Detect Twitter Clients
public boolean detectTwitterClients() {
	buildKnownTwitterClientsList();
	foundTwitterClients = new HashMap&lt;String, ActivityInfo&gt;();

	Intent intent = new Intent(Intent.ACTION_SEND);
	intent.setType(&quot;text/plain&quot;);
	PackageManager pm = getPackageManager();
	List&lt;ResolveInfo&gt; activityList = pm.queryIntentActivities(intent, 0);
 	int len = activityList.size();
	for (int i = 0; i &lt; len; i++) {
		ResolveInfo app = (ResolveInfo) activityList.get(i);
		ActivityInfo activity = app.activityInfo;
		if (knownTwitterClients.containsValue(activity.name)) {
			foundTwitterClients.put(activity.name, activity);
		}
	}
	return false;
}
</pre>
<p><strong>Step 3</strong> is a method that resolves the ComponentName object that will be used to launch a tweet request.  Notice  that I&#8217;ve added an extra string named <em>preferredTwitterClient</em>.  This code grabs the first found Twitter client from our list and sets that as the client that will be used.  Then it checks to see if a preferredTwitterClient is specified, and if that app is installed on the device, then that client is used instead.  The thought behind this feature is to eventually have a settings option that lists the available Twitter Clients on the device and allow the users to pick the one they prefer.</p>
<pre>
// Resolve the twitter client component name
public ComponentName getTwitterClientComponentName() {
	ComponentName result = null;

	if (foundTwitterClients.size() &gt; 0) {
		ActivityInfo tweetActivity = null;
		for(Map.Entry&lt;String, ActivityInfo&gt; entry : foundTwitterClients.entrySet()) {
			tweetActivity = entry.getValue();
			break;
		}

		if (preferredTwitterClient != null) {
			String activityName = knownTwitterClients.get(preferredTwitterClient);
			if(foundTwitterClients.containsKey(activityName)) {
				tweetActivity = foundTwitterClients.get(activityName);
			}
		}

		result = new ComponentName(tweetActivity.applicationInfo.packageName, tweetActivity.name);
	}

	return result;
}
</pre>
<p><strong>Step 4</strong> is simply coding the &#8220;Tweet&#8221; button handler method.  Notice that if none of our known Twitter clients are found on the device, this method simply fires off the standard &#8220;text/plain&#8221; application chooser.  The variables <em>title</em> and <em>permalink</em> are globals in the activity; you can set the Intent.EXTRA_TEXT to whatever suits your application. </p>
<pre>
// Tweet button handler
public void onTweetClick(View v) {
	ComponentName targetComponent = getTwitterClientComponentName();

	if(targetComponent != null) {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setComponent(targetComponent);
		String intentType = (targetComponent.getClassName().contains("com.twidroid")) ?
			"application/twitter" : "text/plain";
		intent.setType(intentType);
		intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + permalink);
		this.startActivity(intent);
	} else {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_TEXT, title + "\n" + permalink);
		this.startActivity(Intent.createChooser(intent, "Share..."));
	}
}
</pre>
<p>I hope that helps.  The solution would be much cleaner if there was an intent type that identified <em>Tweet</em> actions.  Ideally, every client should support both &#8220;text/plain&#8221; and &#8220;application/twitter&#8221; intent types &#8211; which would eliminate the need to manually build a list of known twitter clients &#8211; a significant improvement to what I&#8217;ve done here.  </p>
<p>Future: I&#8217;m planning on adding a preference selector where the user could select the installed client they prefer, but another really nice idea would be to instead display a selector list just like the createChooser does but that only lists Twitter Clients.</p>
<p>If your favorite Twitter Client isn&#8217;t in the list and you want to do the research and find their intent activity, post it in the comments and I will add it to my knownTwitterClients map.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2011/12/android-development-send-tweet-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Take on WordPress Optimization</title>
		<link>http://blogrescue.com/2011/12/my-take-on-wordpress-optimization/</link>
		<comments>http://blogrescue.com/2011/12/my-take-on-wordpress-optimization/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 17:40:56 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[wordpress optimization]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=340</guid>
		<description><![CDATA[Lately, I&#8217;ve seen a huge number of articles on WordPress Optimization being linked to or broadcast on Twitter, and each made one or two good points, but optimization is not simply tweak this or use this plugin. It is a whole course of actions that you should be taking in order to make your WordPress [...]]]></description>
			<content:encoded><![CDATA[<p>Lately, I&#8217;ve seen a huge number of articles on WordPress Optimization being linked to or broadcast on Twitter, and each made one or two good points, but optimization is not simply <em>tweak this</em> or <em>use this plugin</em>.  It is a whole course of actions that you should be taking in order to make your WordPress site deliver content as quickly as possible.</p>
<p>I&#8217;ve worked with WordPress since it first came out, and I&#8217;ve supported a number of very high traffic sites.  The items below are what I&#8217;ve learned about making WordPress work better and faster:</p>
<h2>Actions that are Free (or Mostly Free)</h2>
<div style='padding-left:20px;'>
<h3>Use a Caching Plugin</h3>
<p>The two that come to mind are <a href='http://wordpress.org/extend/plugins/wp-super-cache/'>wp-super-cache</a> and <a href='http://wordpress.org/extend/plugins/w3-total-cache/'>w3-total–cache</a> (w3tc).  W3tc does quite a bit more than simply caching content so that gives it the edge, at least in my opinion.  Most WordPress optimization guides start&#8230;and end with implementing a caching plugin, but this is just the first step.</p>
<h3>Homepage Caching</h3>
<p>The most resource intensive page to generate on a wordpress install is usually the homepage and it is also the most viewed page.  By hard caching the homepage every minute via cron and using .htaccess to direct visitors to this static copy, server load can be reduced pretty significantly.  Caching plugins do provide <em>some</em> remedy as far as front page generation and delivery but this is a better solution because it does not even involve starting up php or processing any logic, aside from evaluating a redirect rule.</p>
<h3>Header/Footer/Sidebar Caching</h3>
<p>Some content on a site rarely changes (header, footer, sidebar) so the same strategy described above for the index page can also be employed for other content.  Using cron to regularly grab and store this content and then changing the other templates to include <em>sidebar.inc</em> instead of <em>sidebar.php</em> means generating every page on your side instantly becomes more efficient.  The same works for header.php and footer.php, although keep in mind that the page title should remain dynamic and key actions like wp_head and wp_footer have to be accommodated.</p>
<h3>Minimize Plugins</h3>
<p>Plugins provide many necessary functions and add on features to WordPress.  They also introduce overhead.  The key is to decide what plugins you absolutely need and what features you can either live without or handle with direct code in the templates.   Plugins aren&#8217;t bad and should be used as required.  Just don’t use too many.  Always keep them up to date and remove unused templates from your server.</p>
<h3>Avoid Widgets</h3>
<p>Widgets are fun.  You drag items around and they appear on your blog.  You can download new ones and re-position them at will.  They make things easy but also introduce overhead.  Widget compatible themes add function calls and widget positions and content are stored in the database which equals extra database reads.  For this reason, I never use widgets and always strongly recommend against them.  The problem isn&#8217;t the features provided by the widgets but the overhead that comes with them &#8211; all of which could easily be avoided by simply coding the feature directly in your templates.</p>
<h3>Avoid Frameworks</h3>
<p>There are some incredible theme frameworks out there.  Developers have spent a tremendous amount of time developing a codebase that runs on top of WordPress and provides a huge amount of additional functionality.  Then they can easily put together a theme that runs on top of the framework.  </p>
<p>Many of the themes are gorgeous and coding a theme on a framework, once past the learning curve, can be faster and easier because the framework already has so many features built right in.  They also usually provide a very slick administration panel which provides easy ways for a user to change the header image and set a myriad of options that control how the site works.  </p>
<p>These are very useful features but it comes at a high cost.  Frameworks add an entire layer of codebase, action hooks and database reads between your theme and WordPress.  For lower traffic sites, this overhead might not be noticeable, but high traffic sites are going to pay for the convenience the framework provides.  I always advise against using framework based themes.</p>
<h3>Use Clean Templates</h3>
<p>There are a myriad of ways to reduce function calls and database usage when coding a template.  The biggest one is to figure out when a WordPress call like bloginfo() is giving you a static result and either store the result in a variable or even hard code it into the template.  Granted, this does makes a theme less portable but this post is concerned with optimization, not portability.  </p>
<p>Eliminate widget code if you are not using widgets (which you shouldn’t be), and avoid unnecessary include statements.  Special loops that find recent or related items can bring in plenty of overhead.  If possible, eliminate them.  If not, find a way to make them faster or cache the results periodically.  I realize this section is very broad and is requires advanced php and WordPress experience.  Yet it had to be included because a clean set of templates is critical in order to serve content efficiently and quickly.</p>
<h3>Implement a Hybrid Webserver Solution</h3>
<p>Apache is a full featured webserver and does a good job processing php.  Nginx is a svelte minimalist webserver that does a really good job delivering static content.  Picture Apache as a 4WD vehicle with big tires and a V8 engine, and Nginx as a Toyota Prius.  You want to use the 4WD to drive up into the mountains, but it would be wasteful to drive it for a local shopping trip &#8211; take the Prius instead.  Using Apache to deliver simple static content like stylesheets, javascript and images is the same kind of waste because Apache&#8217;s overhead is always there, whether you are rendering a complicated page via php or delivering a plaintext stylesheet.</p>
<p>I&#8217;ve effectively employed both servers in a hybrid solution which leverages the strength of Apache as needed but utilizes Nginx for the easy stuff.  It works like this:  Nginx listens on port 80 (the standard http port) and then a set of rules helps it decide if it should deliver the request itself (js, html, css, images) or pass it on to Apache.  Apache listens on port 8080 and can quickly respond to requests for dynamic WordPress content.  </p>
<p>It is pretty normal for a single page to have between 10 and 30 static items which must also be read.  Think how happy Apache would be if the number of requests was reduced by 90%?  Granted, this only removes the easy requests, but it still dramatically reduces the overall load.  And using low footprint Nginx to deliver a stylesheet instead of Apache with all its overhead is going to improve speed and reduce server load.</p></div>
<h2>Actions that cost money</h2>
<div style='padding-left:20px;'>
<h3>Use a CDN</h3>
<p>CDN stands for content delivery network.  It is a service that can store and deliver your static content (images, stylesheets, javascript) on demand.  A good CDN delivers those items very quickly which speeds up pageloads for your site and simultaneously reduces the number of requests your server has to deal with.  There are plugins (like w3tc) which make using a CDN pretty seamless to you and to your visitors.  <em>This is a huge bang for the buck option &#8211; highly recommended.</em></p>
<h3>Dedicated server</h3>
<p>Shared hosting is great when you are starting out because it is a cheap option and usually does a good job with a low traffic WordPress site.  However, as your design becomes more complicated and your hit count rises, you may notice really slow loadtimes and the admin interface may become almost unusable.  You are also potentially at the mercy of the other sites on the same server.  If one of them is behaving badly or gets a boatload of traffic, your performance can suffer through no fault of your own.  A dedicated server is an expensive option (comparatively) but makes you less dependent on the actions of other users on a shared service.  However, It is <strong>not a magic bullet</strong> – having a dedicated server does not mean you can ignore all other optimization options described here.</p>
<h3>Dedicated database server</h3>
<p>A dedicated server is great, but it still has to act as a webserver and also as a database server.  By adding a second dedicated server to handle the database side of things, your webserver is now single purpose and can focus on generating and delivering pages as quickly as possible.  For high traffic sites using WordPress, this is a great (but even more expensive) way to go.</p>
<h3>Multiple Load-Balanced Servers</h3>
<p>Supersites have to use this simply to handle all the requests.  I have worked with WordPress sites which handle huge amounts of traffic but are still extremely fast.  They employ almost every option above and also employ multiple load-balanced servers.  If you ever get that big, you will have to spend the big bucks and go this route also.</p></div>
<p>I hope at least some of that is new information and helps you make sure your site delivers your content as fast as possible.  I know some people will disagree with some of this and I fully expect hate mail from some who either develop or employ Frameworks, which is fine.  The point of this post was not to please everyone, but simply to take a critical look at anything that adds overhead to WordPress and ways to reduce it.  </p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2011/12/my-take-on-wordpress-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The value of Coffee confirmed yet again&#8230;</title>
		<link>http://blogrescue.com/2011/12/the-value-of-coffee-confirmed-yet-again/</link>
		<comments>http://blogrescue.com/2011/12/the-value-of-coffee-confirmed-yet-again/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 16:10:09 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[coffee]]></category>
		<category><![CDATA[reason]]></category>
		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=337</guid>
		<description><![CDATA[Hat-tip to Grek Mankiw]]></description>
			<content:encoded><![CDATA[<p><iframe width="560" height="315" src="http://www.youtube.com/embed/tsFxH2zdi_Y" frameborder="0" allowfullscreen></iframe></p>
<p>Hat-tip to <a href='http://gregmankiw.blogspot.com/2011/12/coffee-and-age-of-reason.html'>Grek Mankiw</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2011/12/the-value-of-coffee-confirmed-yet-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tech News &#8211; November 14th</title>
		<link>http://blogrescue.com/2011/12/tech-news-november-14th/</link>
		<comments>http://blogrescue.com/2011/12/tech-news-november-14th/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 01:01:47 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[The Web]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[Cats]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Kindle Fire Firefox]]></category>
		<category><![CDATA[Pigs]]></category>
		<category><![CDATA[Siri]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=328</guid>
		<description><![CDATA[Use of cats stopped in Survival Flight training Instead of cats, they are using Robots and pigs. PETA says pigs shouldn&#8217;t be used either. PETR had no comment, mostly because it doesn&#8217;t exist&#8230;yet. #RobotsHaveRightsToo Can a Software Update Quench Kindle Firestorm? The Kindle Fire is selling big, but some buyers are not satisfied. This update [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://www.chicagotribune.com/news/chi-ap-mi-medicalflighttrai,0,7470226.story'>Use of cats stopped in Survival Flight training</a><br />
Instead of cats, they are using Robots and pigs.  PETA says pigs shouldn&#8217;t be used either.  PETR had no comment, mostly because it doesn&#8217;t exist&#8230;yet. <strong>#RobotsHaveRightsToo</strong></p>
<p><a href='http://www.technewsworld.com/story/Can-a-Software-Update-Quench-Kindle-Firestorm-73951.html'>Can a Software Update Quench Kindle Firestorm?</a><br />
The Kindle Fire is selling big, but some buyers are not satisfied.  This update is supposed to help. <strong>#SlowBurn</strong></p>
<p><a href='http://androidandme.com/2011/12/news/googles-response-to-siri-is-codenamed-majel-could-be-released-by-end-of-year/'>Google&#8217;s Response to Siri is Codenamed Majel, Could be released by End of Year</a><br />
I predict this will result in another lawsuit by Apple.<br />I also predict that the <a href='http://www.bestapples.com/index.aspx'>Washington Apple Commission</a> will someday be the target of a lawsuit by Apple.  <strong>#DontCopyUs!</strong></p>
<p><a href='http://developers.slashdot.org/story/11/12/14/1725205/firefox-too-big-to-link-on-32-bit-windows'>Firefox is too big to link on 32-bit Windows</a><br />
This is why I, a huge Firefox proponent from the beginning, abandoned Firefox entirely a little over two years ago. <strong>#Bloat</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2011/12/tech-news-november-14th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stealth Hacking</title>
		<link>http://blogrescue.com/2011/12/stealth-hacking/</link>
		<comments>http://blogrescue.com/2011/12/stealth-hacking/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 04:49:46 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://blogrescue.com/?p=321</guid>
		<description><![CDATA[Could your WordPress install be Hacked without you knowing about it? Similar to the Pharma-Hack, there is a new stealth hack which affects compromised WordPress sites and most people have no idea their site is infected. The reason for the ignorance is that the hack doesn&#8217;t affect any content on the infected site &#8211; except [...]]]></description>
			<content:encoded><![CDATA[<p>Could your WordPress install be Hacked without you knowing about it?</p>
<p>Similar to the <a href='http://www.pearsonified.com/2010/04/wordpress-pharma-hack.php'>Pharma-Hack</a>, there is a new stealth hack which affects compromised WordPress sites and most people have no idea their site is infected.  The reason for the ignorance is that the hack doesn&#8217;t affect any content on the infected site &#8211; except for pages delivered to googlebot.  For those pages, it injects &#8220;Free live streaming porn &#8211; &#8221; in front of page titles which gives nasty search results for innocuous content.</p>
<p>Take a look at these search results: <a href='http://www.google.com/search?q=%22free+live+streaming+porn%22' target='_blank'>google search for: &#8220;Free live streaming porn&#8221;</a>. (Link is SFW).  </p>
<p>About 11 million hits and if you read the summary content, most are blogs or pages from a WordPress installs that have search results that are injected with a bogus title and keywords. (Either the hack does not target Bing and Yahoo, or hacked pages end up futher down in the result set for those search engines, at least that is what I saw on those sites with the same search.)</p>
<p>So how do you know if your blog is one of these hacked sites?  Do the same google search with the site tag:</p>
<blockquote><p>
&#8220;Free live streaming porn&#8221; site:blogrescue.com
</p></blockquote>
<p>Mine comes up clean, but it is probably a good idea to check yours.  If you are infected, then you need to deal with the issue right away, and then comes the agonizing wait for googlebot to recrawl these pages and replace the damaged pages with the real version.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogrescue.com/2011/12/stealth-hacking/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

