Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • Embedding CBS Video

    Embedding CBS Video

    Video!This spun out of someone who was _doing_it_wrong(). His plugin embed code reinvented all four wheels. First he was doing a reg4exp to implement shortcodes, then he was replicating oEmbeds that WordPress already has. I told him to first remove the ones that existed (so as not to cause conflicts) and then look up shortcodes.

    But since the shortcodes he wanted to make were a little weird, I thought “Well, I know I would like to see the CBS Videos one, since I embed a lot of them…” So I took ten minutes to eat a cracker and re-write his code.

    Here’s my code first.

    // CBS Video Shortcode
    function cbsvideo_func( $atts ) {
            extract( shortcode_atts( array(
                    'id' => '00',
                    'width' => '480',
                    'height' => '270',
            ), $attr ) );
    
            return '<object width="'.$width.'" height="'.$height.'"><param name="movie" value="http://www.cbs.com/e/'.$id.'/cbs/1/" /></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed width="'.$width.'" height="'.$height.'" src="http://www.cbs.com/e/'.$id.'/cbs/1/" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"></embed></object>';
            }
    add_shortcode( 'cbsvideo', 'cbsvideo_func' );
    

    Then you use [cbsvideo id="9wFRf8KYoAXipnXgA8GKIm1VNaMgKjpE"] to embed it and have a beer. I put it in a file called sitewide-functions.php in my mu-plugins folder and walked away.

    Here’s his code, as a reference.

    define("CBS_WIDTH", 480); // default width
    define("CBS_HEIGHT", 270); // default height
    define("CBS_REGEXP", "/\[cbs ([[:print:]]+)\]/");
    define("CBS_TARGET", "<object width=\"###WIDTH###\" height=\"###HEIGHT###\"><param name=\"movie\" value=\"http://www.cbs.com/e/###URL###/cbs/1/\" /></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowScriptAccess\" value=\"always\"></param><embed width=\"###WIDTH###\" height=\"###HEIGHT###\" src=\"http://www.cbs.com/e/###URL###/cbs/1/\" allowFullScreen=\"true\" allowScriptAccess=\"always\" type=\"application/x-shockwave-flash\"></embed></object>");
    
    function cbs_plugin_callback($match)
    {
    	$tag_parts = explode(" ", rtrim($match[0], "]"));
    	$output = CBS_TARGET;
    	$output = str_replace("###URL###", $tag_parts[1], $output);
    	if (count($tag_parts) > 2) {
    		if ($tag_parts[2] == 0) {
    			$output = str_replace("###WIDTH###", CBS_WIDTH, $output);
    		} else {
    			$output = str_replace("###WIDTH###", $tag_parts[2], $output);
    		}
    		if ($tag_parts[3] == 0) {
    			$output = str_replace("###HEIGHT###", CBS_HEIGHT, $output);
    		} else {
    			$output = str_replace("###HEIGHT###", $tag_parts[3], $output);
    		}
    	} else {
    		$output = str_replace("###WIDTH###", CBS_WIDTH, $output);
    		$output = str_replace("###HEIGHT###", CBS_HEIGHT, $output);	
    	}
    	return ($output);
    }
    function cbs_plugin($content)
    {
    	return (preg_replace_callback(CBS_REGEXP, 'cbs_plugin_callback', $content));
    }
    
    add_filter('the_content', 'cbs_plugin',1);
    add_filter('the_content_rss', 'cbs_plugin');
    add_filter('comment_text', 'cbs_plugin');
    

    35 lines of code vs 11, and my 11 will run faster.

  • Permalink Elephants

    Permalink Elephants

    Broken Link The best permalink format for your site is so simple, you’re going to wonder why you never thought of it before. It’s obvious, intuitive, and perfect. In fact, I dare say it’s genius. Want to know what it is?

    The best permalink is the one your visitors can remember.

    I told you it was obvious.

    Look, you can waste immesurable hours and days trying to determine if /postname/ is better than /2012/postname, or you can sit down and remember you’re not making a site for search engines, but for your visitors.

    SEO does have a point, don’t get me wrong. If it’s easy for people to find your site, you get more traffic. One of my sites, following the recent Panda and Penguin updates on Google, jumped from 5th place to 3rd on a search for the major keyword. Another went from 12th to 9th (we’re working on that). None of that has to do with me changing anything, or even picking the best SEO plugin. It was done the traditional way.

    1. I wrote good copy
    2. I networked with related sites for links
    3. I advertised
    4. I was memorable

    Those three things, when done correctly, are how you get your site to rank high. And it’s that last item, being memorable, that should drive your URL choices.

    A URL like http://example.com/12897342134/jkahsdu.aspx isn’t memorable. It tells me nothing of what your site’s about, what the topics are, what the subject is.

    Elephants being adorableOn the other hand, a URL like http://example.com/2011/how-to-save-elephants tells me quite a bit. I know when the post was written, so if there was a big to-do about elephants in 2011, it probably is related. But it’s not always easy to tell someone that URL, nor is it a given I’ll remember it tomorrow. I may remember that example.com had a cool posts about saving elephants,  however. It’s certainly more likely I’ll remember it than the other link!

    This is where WordPress does something cool, though. See, I can tell someone to go to http://example.com/how-to-save-elephants/ and that will redirect them to the right URL! You can do this on Drupal as well with a module called Global Redirect (Drupal folks, correct me if I’m wrong/there’s a better one).

    To me, that says the issue isn’t what permalink pattern you pick, but what permalink slug you use! On that train of thought, what if I made my URL http://example.com/2011/save-elephants instead? Naturally then http://example.com/save-elephants  would also work.

    Now we can clearly see that ultimate issue is not the permalink structure. The only thing I don’t like about how WordPress defaults URLs is that I have to tell people ‘it’s example dot com slash save dash elephants’ and that’s not as easy as ‘example dot com slash elephants.’ Or even ‘saveelephants, all one word’ (I don’t know why that’s easier, but people tell me it is).

    The whole reason people like short URLs is that they’re short and easier to remember. If I told you to get to a site you used http://bit.ly/elephant, you’d have a much higher likelihood of remembering. Invariably, however, we look at branding and think “I don’t want bit.ly to have my name.” That’s a case for Yourls, and now, as long as you customize all your Yourls, you’re in it to win it. I know most people use short URLs for Twitter and such, but I find that making a handy short URL to tell someone ‘go to foo dot in slash facebook’ works astonishingly well. Of course Facebook knows that too, and lets you use http://fb.com/username to find people.(I don’t have a yourls setup here because I’m incapable of finding a short URL I like.)

    Sadly, there is one problem with this, and it’s that you can only use each ‘slug’ once, so once you’ve use ‘elephant’ you’re never able to use it again.

    Name your slugs wisely and plan, as best you can, for the future.

  • WordPress 3.4 – No Problem

    WordPress 3.4 – No Problem

    It’s in beta, don’t nobody panic.

    The last 3 releases of WP, I’ve made troubleshooting posts about what to do, what plugins are going to barf, and so on. This time, there really doesn’t seem as much to worry about. Of course, having said that, everything will die in a fire. Actually, though, I haven’t made a list of things yet, because there’s nothing to list. I’ve not run into any stand out ‘Oh shits!’ and the forums are remarkably quiet. So. If you’ve got stupid problems, or found you have to edit themes/plugins, please reply and let me know! I’ll get on it.

    So here’s some of the cool new stuff:

    Akismet 2.5.6

    Custom Headers and Backgrounds — See also Flexible Headers in 3.4 Themes and Backwards Compatibility for WP 3.4 Headers and Backgrounds

    Twitter was added to oEmbeds — This should just work out of the box, but if you have a plugin (like Blackbird Pie), you may want to disable it before upgrading.

    RPC-XML support for Custom Post-Types.

    Admin Toolbar To The Top! Click on any blank space in the admin bar and you go to the top of the page. (It’s the toolbar, damn it, I know this!)

    Sexier Theme Options. Have you ever wanted to see what the changes did to your theme on the fly? Go to WP Admin > Themes and click on Customize Theme to get a quick way to see what you’re tweaking. Not every option is there, nor will every option be added, but this is pretty nice!
    Theme Options

    You also get that view when you preview a theme.

    Of note, Twenty Twelve and Favicons got punted to 3.5.

    Edited to add…

    Jane Wells has a nice write up of some of the new stuff. It’s on .com, but a lot of this (all) is on 3.4 too. What? You didn’t know .com used the same (mostly) WordPress we do?

  • Storify oEmbed

    Storify oEmbed

    Of note, this no longer appears to work. It’s been almost 2 years. Not shocked. Embedly has a plugin though. http://wordpress.org/plugins/embedly/

    I was reviewing a plugin that went the long way around for this (similar to how things work on my Rickroll plugin, with a search/replace).

    You would think this is easier:

    // Add Storify oEmbed
    function add_oembed_storify(){
        wp_oembed_add_provider( 'http://storify.com/*', 'http://api.storify.com/v1/stories/');
    }
    add_action('init','add_oembed_storify');
    

    But even though there’s a nice API, it won’t work. Why not? Because Storify doesn’t have it’s own oembed provider. Boo. Instead you have to use something like embed.ly

    wp_oembed_add_provider( 'http://storify.com/*', 'http://api.embed.ly/1/oembed?url=http://storify.com/');
    

    Then you put http://storify.com/dailydot/betty-white-joins-twitter in your post and it shows a story.

    Example:

    http://storify.com/dailydot/betty-white-joins-twitter

  • jQuery – Why U No Enqueued?

    jQuery – Why U No Enqueued?

    DevoThis is a followup to my how to get your plugin in the WordPress repository post.

    While code isn’t outright rejected for being ‘bad’ code (only security holes and guideline violations), a lot of plugins are doing the easy things wrong. These plugins will get approved, but they won’t work with all setups, they’re more likely to have issues with Multisite, and they’re just not thinking forward. They aim to solve a, singular, problem, without looking beyond. Primarily I see this when people are trying to bring in some js code into their plugin. Heavens knows I do it, and I’ve done it wrong too. But as I see more and more plugins, I’m starting to get better and better at knowing what’s wrong when I see it.(“I know it when I see it” thanks to United States Supreme Court Justice Potter Stewart)

    The easiest way to show you is to give you some really bad examples and go through some of the steps to fix it. The best part is that I’m actually going to use real plugins I’ve seen. Only the name has been changed to protect the innocent.

    Ready? Here’s what we’re doing wrong.

    Not using functions to define locations

    The very bad code:

    echo '<script src="/wp-content/plugins/myplugin/myscript.js"></script>';

    I wish this was something I made up. Worse, I’ve see it more than once. Recently.

    This install is assuming WordPress is installed in the root of your HTML folder (i.e. domain.com). This is not always the case, as many people install WordPress in subfolders. We’ll need to fix that first with home_url().

    echo '<script src="'.home_url('wp-content/plugins/myplugin/myscript.js').'"></script>';

    Now it’s a little better, as by using home_url() we’re letting WordPress define where ‘home’ is. Great! This has two pretty obvious problems, however. First, if I have WordPress installed in a folder, like /public_html/wordpress/, but I’m running it out of the main domain by giving it its own directory, this won’t work. Your code would point to http://example.com/wp-content… when mine is in http://example.com/wordpress/wp-content.. instead! The ‘easy’ fix is to change home_url() for site_url(), but what if I’m not using wp-content? You didn’t know we could Move wp-content? We can. So let’s address that.

    echo '<script src="'.content_url('plugins/myplugin/myscript.js').'"></script>';

    By using functions to determine plugin and content directories, we can make this much more flexible. That works, but it could be better. What if we didn’t have to define the plugins or myplugin folders? We could just do something simple like this.

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    Now we have a simple, flexible, functional script embed of js. Except there’s one, minor problem. We’re not including the script correctly.

    Not enqueuing files

    This isn’t ‘wrong’ really. I mean, if I put this in my plugin, it would echo out the script, and that’s what I want, right?

    echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';

    But let’s say I want to put it in my header:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    add_action('wp_head', 'my_scripts_method');

    And now I want to include my CSS so it looks pretty:

    function my_scripts_method() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method');

    Oh, wait, no, I wanted my JS in the footer:

    function my_scripts_method_foot() {
        echo '<script src="'.plugins_url('myscript.js',__FILE__).'"></script>';
    }
    function my_scripts_method_head() {
        echo '<link rel="stylesheet" type="text/css" href="'.plugins_url('myscript.js',__FILE__).'" media="all" />';
    }
    add_action('wp_head', 'my_scripts_method_head');
    add_action('wp_footer', 'my_scripts_method_foot');

    And really, this will work. But it’s not efficient, I’ve got extra actions, and I’m not considering any jquery dependencies anymore. By using wp_enqueue_script is better. Weblog Tools Collection did a series on how to properly add scripts (note that it’s a bit out of date with the use of WP-CONTENT constants). From that we can extrapolate to use just this to include our js and css:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__) );
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    What enqueue does is put your code in the best possible location and can be extended to load dependencies. wp_enque_scripts has a lot of power, and because it’s a WordPress function, it’s got options that make it more flexible. Like when I look at my above code, I remember, oops! I wanted to run my js out of the footer! Not a problem. Look at my options.

    wp_enqueue_script('handle', 'source', 'dependencies', 'version', 'in_footer');

    jQuery Logo looks like a Devo HatThe ‘handle’ is what I want to name my script, it should be unique. If I register my script, I can call the handle over and over again. We’re using my_script right now. The ‘source’ is where my file is located. We’re lifting that from our other code, the bad code, because it works. Your ‘dependencies’ are the other js files yours needs to function. If I put in array('jquery', 'scriptaculous') then both jQuery and Scriptaculous would get loaded before my script. Curiously, you don’t actually need the ‘version’ option, as you can leave it blank and WordPress will automatically add a version number equal to the current version of WordPress you are running. So every time you upgrade WP, it will get updated and force a re-download. This is good, since if you have dependencies to scripts included in WordPress, and they change with a new version (which is the only way they can change), then you get updated too. Finally we have the value I was looking for, ‘in_footer.’ Leave it blank and it’s in the header, put in true and it’s not.

    This makes my code:

    function my_scripts_method() {
        wp_enqueue_script('my_script', plugins_url('myscript.js',__FILE__), '','', true ););
        wp_enqueue_style('my_script', plugins_url('myscript.css',__FILE__) );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Yeah, isn’t that a lot easier?

    Using a different jQuery

    This last one I’m going to touch on today is the exact code I saw, in the wild, and it’s got two of my three buggaboos in it.

    wp_enqueue_script('jquery-1.4.3.min.js', '/wp-content/plugins/myplugin/js/jquery-1.4.3.min.js');

    Okay. You already know the right way to call the script, so we’ll edit that into something more flexible.

    wp_enqueue_script('jquery-1.4.3.min.js', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );

    That should be okay, but it’s totally not.

    Most importantly here, we’re calling jquery, which is actually built in to WordPress. Now, we’re calling it by a different handle, but that’s no guarantee that it won’t cause conflicts. In fact, I’m pretty sure this will cause no end of problems with some plugins. The right thing to do would be this:

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', plugins_url('js/jquery-1.4.3.min.js',__FILE__) );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');

    Now we’re making sure we won’t have conflicts by re-registering jquery, replacing it, and moving on.

    A lot of people would actually recommend using Google instead, as it takes the responsibility off you for including a file you don’t ‘control.’ Also it makes your plugin smaller and load faster.

    function my_scripts_method() {
        wp_deregister_script( 'jquery' );
        wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' );
        wp_enqueue_script( 'jquery' );
    }
    add_action('wp_enqueue_scripts', 'my_scripts_method');
    

    Devo Hat looks like Devo HatGreat! Now we’re done, right? Wrong. As of this writing, WordPress is using jQuery 1.7.2. Now I couldn’t come up with a reason to include an old version of jQuery in WordPress (newer, yes, older, no), so I asked around and none of my friends could either. Using an older version is more likely to cause issues with newer code included in WordPress, as well as plugins which are upgraded to take advantage of the new features. You’re shooting yourself in the foot. The only thing you might be using this for is to include deprecated fictions, and really you need to update your code to fix that instead.

    If the whole point is to load the scripts from Google, though, there’s an awesome plugin for that.

  • Speed Up Your Site

    Speed Up Your Site

    FasterThe majority of what I do to speed up my website is on the server level. In 2009 I moved to a VPS, and just last year I switched to a Smart Server. I have access to install APC, to tune MaxClients, and to upgrade my PHP whenever I darn well want to. And I regularly use these tools to fine tune my server so it’s lean, fast, and efficient. 75% of why my domains run this fast under this much stress (I have two fan sites, they get hammered), is that I’ve done all this work, including some of the stuff I did on DDOS prevention.(My CT_LIMIT is set to 75 right now, and that seems to be the perfect balance. The only people hurt are some silly people in Brazil who like to open 100 pictures all at once. I’ve explained why this is bad.)

    However, not all of you have access to the server to make all those cool tweaks and changes to speed up your website. If you’re on shared hosting (and there’s nothing wrong with that), you can’t edit httpd.conf, you can’t always edit php.ini, and you sure can’t upgrade PHP on your own. Don’t worry, there are still things that you can do!

    The first thing you should do is understand that the more complicated your site is, the slower it’s going to be. So if you want a site with all those bells and whistles, you have a lot more work to do than a simple, plain, site. These are the tradeoffs we must accept in all things.(The exception being, perhaps, cookware. I have some awesome Lodge cast-iron pots and pans, and they’re pretty expensive for their simplicity. Then again, they’re made with such amazing skill and precision, they’re not ‘simple’ to make. So YMMV.) Reduce the complications and things run faster. You have to have a balance between ‘everything’ and usability. If your site is sexy as all get out, but slower than a truculent five year-old on a family walk, then you’re doing it wrong. That doesn’t mean you need to have the world’s most boring site, it just means you have to start learning what it is that makes your site slow. When you look at themes and plugins for a site, remember the more you have, the slower things may become, so use them wisely.

    My favorite tools to show why a site is slow are YSlow and PageSpeed. YSlow is a browser add-on you can use with Chrome, Firefox, and every other commonly used browser. Except for IE. Once installed, you simply go to the webpage and run the tool to get a scan of your site. You get ‘graded’ on an A through F scale, with F being the worst, and the grades are computed based on a fairly understandable methodology.(See FAQ: Grading) Page Speed is Google’s version, and I prefer it, but only because I don’t have to install anything to do it, and it gives really good explanations of what’s wrong. There’s also Web Page Test, which is great to find out if your site flails on different browsers, as well as giving you accurate speed breakdowns.

    Here are three of my sites, all installed on this server, scanned by YSlow:

    And here are the same three as SiteSpeed:

    I’m not going to go through every option, most of them are self explanatory (put the CSS at the top and JS at the bottom). Instead, I’ll explain the weirder ones that you can tweak yourself, and some that you can ignore. If you’re using a tool like W3 Total Cache, you actually can configure most of this directly in the tool instead. For what it’s worth, I did ‘fix’ my scores with both sites and I’m now in the 90s from Page Speed and .. Well not so much with YSlow. The two disagree on how much ‘weight’ to give various errors. Page Speed thinks minification is low priority, and doesn’t judge you about a CDN. It also understands that you can’t gzip what you don’t own. If you use YSlow, make note of what you score poorly in, and fix those as best you can.

    Things I Ignore

    When I get complaints of too many HTTP requests, that just means I’m calling ‘too many’ JS scripts and stylesheets. YSlow doesn’t say which ones those are, which isn’t actually helpful to the novice. If you click on ‘Read More’ it just explains why this is bad. The idea here is that you should have one CSS file, but realistically, any dynamically generated site is going to have more that one. Especially when you consider I’m calling some from Google, Facebook and Twitter for my sharing buttons. While this does slow your site down, unless you have 20 stylesheets on your own site (again, I’m not counting the ones on other domains), it’s not that big of an issue. If you minimize what you have, and combine as much as you can, you’re going to be okay.

    I also totally ignore any scores related to my CDN, or rather the fact that I’m not using one. Yes, a CDN will make your site much faster, but I don’t think this is applicable for everyone, and I generally ignore that value.

    Finally I ignore suggestions to use cookie-free domains, but that’s because I’m running WordPress, and it needs cookies.

    Things I Fix in .htaccess

    You can fix most expires headers errors, but only the ones that relate to your site. When I look at a scan for one of my domains, I see that the items my site loads that don’t have Expires headers are a flash module from PayPal, Google’s +1 javascript, a banner, and two gravatars. Those are all items that, yes, can slow my site down, but they’re outside my ability to fix! And in the case of gravatars, I don’t want them to Expire too soon, since they may change. I’m going to, again, ignore this.
    YSlow - Add Expires headers (F)

    Why wasn’t my server listed? It’s because I added Expires headers to my site. Obviously. The easiest way to do this for your site is to put the following in your .htaccess file(If you’re using WordPress, Drupal, or any web app that has it’s own .htaccess rules, remember to put these above the section for them! It’s important.):

    <ifmodule mod_expires.c>
      <filesmatch "\.(jpe?g|gif|png|css|js)$">
           ExpiresActive on
           ExpiresDefault "access plus 1 year"
       </filesmatch>
    </ifmodule>
    

    What this will do is turn on Expires and set to to today plus one year. Now this isn’t actually the best way to do it, as it leaves out a lot of variables, but for most people, it’s good. Keep in mind, the further you set out this expires, the harder it is to change any files! For example, if I upload a PNG with a 1 year expiration, and then upload a new version, no one will see it (unless they flush their browser cache). Don’t set this further than a year, and only set it for things you know aren’t changing often.(You’ll notice WordPress sourcecode has your JS and CSS files saved with ?ver=x.x at the end. This lets you work around the expires, as when you change your CSS, it changes the version, and thus, pushes the changes down to your users.)

    Cache-Control is the half-sibling of Expires, and lets you specify what files should be cached and for how long. The Ask Apache site has some great examples, as this is what I generally use:

    # 480 weeks
    <filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
    Header set Cache-Control "max-age=290304000, public"
    </filesMatch>
     
    # 2 DAYS
    <filesMatch "\.(xml|txt)$">
    Header set Cache-Control "max-age=172800, public, must-revalidate"
    </filesMatch>
     
    # 2 HOURS
    <filesMatch "\.(html|htm)$">
    Header set Cache-Control "max-age=7200, must-revalidate"
    </filesMatch>
    

    The ‘must-revalidate’ tag is what makes sure your webpages changes actually get picked up quickly. Nothing’s worse than editing a typo, and not having it fixed for your readers!

    Related to that is ETags, which is a bit weird, but this too is something you can tweak. If you disable ETags, everyone has to trust your cache and that gives you a lot of control. It sounds easy, but there’s a reason we should be using ETags for some situations. My sites are using a pretty complex rule that was set by W3TC for me. It sets my Cache Control and ETag, generating the rules I need. If you just want the basics, though, AskApache’s Speed Tips: Turn Off ETags will get you there. For what it’s worth, a small site doesn’t need to worry about this too much.

    If you want to grab my default .htaccess starter, here you go!

    download TXT file

    Things I Fix via CPanel

    You can also speed up your site by enabling gzip. I’d say I left it off on purpose to show you the error, but the fact is I forgot to turn it on when I moved to a new server. If you have cPanel, this is stupid easy. Log in, go to ‘Optomize Website’ and turn it on.

    gzip

    Doing improved a lot of results on my site, though it didn’t want to consider three of my .js files gzipped for some reason, though it did on other domains on the same server when I changed it. I’m not terribly concerned at this point, since I used the HTTP Compression Test (from What’s My IP?) and it says I’m compressed.

    Things I Fix with Elbow Grease (or Plugins)

    Minification. If you view the source of this site, it’s ugly. Everything’s all crammed up without line breaks, and finding anything is a hassle. That’s because I minified my content. If you don’t have a plugin or add-on for your site that can do that for you, you’ll need to do this manually, via Minify CSS and Minify JS. It’s more of a hassle to do that manually, since it’s hard for you to edit later. After-the-fact compression can slow your site a little, but it’s easier to maintain and still faster than non-minified code. Now I use W3TC, which has a minification tool built in, but there are other WordPress plugins that do the same thing.

    The Rest

    There are a lot more tips and tricks to getting your site running faster. I mention W3 Total Cache (W3TC) multiple times because it works great. There’s also WP Super Cache, which I prefer for smaller hosts and shared servers. W3TC is very, very, very complicated, so be warned. WP Super Cache isn’t a ‘lesser’ tool, it’s just different, and I advocate using either one if your site is moderate to large.

    If your site is small, you really can get by with just minifying. There are a lot of minification plugins out there. Images can be reduced in size by compressing them more via Smush.it (there’s a plugin called WP Smushit for WordPress). Many people have also suggested using a Lazy Load plugin, like jQuery Image Lazy Loading, which loads images on demand. I like it, but it slows my site down, and doesn’t work well at all on ones with a lot of dynamic images. I may be using it wrong.

    Anyone can take advantage of a free CDN, Cloudflare has a free plan.(Caveat: I don’t use CDN, nor have I looked at Cloudflare in depth.) They claim to protect you as well as speed things up, and I’ve heard interesting (good) reports on it.

    Many people advocate using plugins to tune your database, but I really don’t like using a plugin for that. You can optimize your database with a cron job instead, or even just do it manually now and again, if you think your site is sluggish. For WordPress I limit my revisions and empty my trash more often with two lines in my wp-config.php:

    define('WP_POST_REVISIONS', 5);
    define('EMPTY_TRASH_DAYS', 5 );
    

    When all else fails and nothing you can do speeds up your site, take a look at your server. If the server itself is really slow, all the time, and I mean you can hardly get your email, ask your host if you can be put on another cluster. A lot of shared hosts are oversold, since not everyone needs all the space and power. It makes sense, but some hosts monitor the status of these servers and move people around if they become bad neighbors, while others wait for you to notice. Opening up a line of communication with your host is always a good thing. Remember, you’re paying these guys! They should be willing to help you out, or you should leave and get a new host.

    At a certain point, you’ll notice that the only ‘fixes’ are to throw more money at it, buying a better host, better themes, better tools, and so on. And that’s simply a fact of life. You can’t live forever on ramen and hot dogs.