Three Ways to Speed Up WordPress in Azure – Part 1

When I initially set up my blog, I had very little idea what I was doing. I’d heard of WordPress and Project Nami, and decided that it would be cool to run a fully PaaS website in Azure. I knew I wanted a performant website – if it’s slow, there’s penalization in SEO. Plus, everyone reads stuff on their phones now, so it needs to be fast on the phone. I found the Google PageSpeed tool, which told me I had some work to do. I don’t have a screenshot of that, but this is an approximation of what it looks like. The actual score was closer to 25/100!

As you can see, it’s not doing so well. However, with a little work, it made it up to 90%! I don’t think it’s actually possible to do better without eliminating the tracking (I use Google Analytics and Microsoft Application Insights to hopefully get to know my audience a little bit better) and, probably, moving to a static web page.

One caveat I should point out is that I’m using Project Nami, which is slightly unique because it runs on IIS and MS SQL Server. However, if your website uses IIS, I believe you’ll see some benefit from all of these tweaks.

Here’s what I did (the links won’t work until I publish the followups):

 

Caching Plugin

There are lots of WordPress caching plugins available. These improve speed by removing the need to process PHP to load up every version of a page. Most WordPress sites don’t need dynamically-generated content for each visitor, and caching plugins allow the server to take advantage of unchanging content where possible. Be aware, like any caching solution, these can make troubleshooting efforts a bit squirrely if you don’t remember to clear the cache or disable the functionality while troubleshooting!

Web.config Changes

I made some changes to the web.config of my website. Some of these are for HSTS, to ostensibly to improve ranking in Google, which I’ve heard prioritizes websites with good TLS configuration. Other pieces inform the client (your browser) to cache pieces of the page so that next time you visit, it loads faster. The final piece that I added configures compression, so that the web server compresses some of the content that is served, such as CSS or JavaScript files.

There are a number of ways to edit your web.config. The way that I most commonly make changes is via the Kudu console. This is found at your-website-name.scm.azurewebsites.net. For example, if your website is mywebsite.azurewebsites.net, go to mywebsite.scm.azurewebsites.net. The website name persists regardless of whether you have configured a custom domain (like I have, using blog.romyn.ca). You can also follow a link from the Azure Portal:

A screenshot of the Azure portal, showing a portion of the screen, highlighting the Advanced Tools link in an Azure App Service instance

You should be aware that any changes you make here can, and probably will, result in your website serving up HTTP 500 errors due to misconfiguration. Before starting, make a backup. XML is sensitive to things like cases and whitespace; you have been warned.

The web.config for my Azure Web App is found at D:\home\site\wwwroot. To get there, navigate to the Diagnostic Console, and then type cd “D:\home\site\wwwroot”  and press enter. You can now see the web.config file and click the edit button.

The web.config XML file viewed in the browser.

To enable HSTS, I followed Scott Hanselman’s blog post. HSTS assumes you already have a good SSL configuration! If you can’t browse all of your website using HTTPS:// in the URL, this is not for you! There’s more to configuring HSTS than simply creating some server headers, but this is a start.

To set up HSTS, you need to create two rewrite rules. You probably already have the system.webServer, and possibly the rewrite and rules sections already created. Don’t duplicate any sections; it will break IIS. Just insert what’s needed. You should back up the file before editing it – preferably, download the file and save a copy. It’s extremely easy to add a space or > in the file, which will break the web server (you’ll get a HTTP 500 response).

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
                        redirectType="Permanent" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
                    <match serverVariable="RESPONSE_Strict_Transport_Security"
                        pattern=".*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="on" ignoreCase="true" />
                    </conditions>
                    <action type="Rewrite" value="max-age=31536000" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

To enable caching, it’s a one-liner. Note, though, that this won’t impact anything that’s not on your web server – for example, images or analytics tools like Google Analytics. It’s also going to be overridden by the configuration of your CDN, eventually. For more information about this configuration, you can read about the clientcache setting here: https://docs.microsoft.com/en-us/iis/configuration/system.webserver/staticcontent/clientcache

<staticContent>
         <clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00"/>
</staticContent>

Finally, enabling compression for some types of file. I encourage you to investigate what types are supported and what the pay-off is. You can, of course, read more more about urlCompression and httpCompression of course.

   <urlCompression doStaticCompression="true" doDynamicCompression="true" />
   <httpCompression>
      <dynamicTypes>
        <clear />
        <add enabled="true" mimeType="text/*"/>
        <add enabled="true" mimeType="message/*"/>
        <add enabled="true" mimeType="application/x-javascript"/>
        <add enabled="true" mimeType="application/javascript"/>
        <add enabled="true" mimeType="application/json"/>
        <add enabled="false" mimeType="*/*"/>
        <add enabled="true" mimeType="application/atom+xml"/>
        <add enabled="true" mimeType="application/atom+xml;charset=utf-8"/>
      </dynamicTypes>
      <staticTypes>
        <clear />
        <add enabled="true" mimeType="text/*"/>
        <add enabled="true" mimeType="message/*"/>
        <add enabled="true" mimeType="application/javascript"/>
        <add enabled="true" mimeType="application/atom+xml"/>
        <add enabled="true" mimeType="application/xaml+xml"/>
        <add enabled="true" mimeType="application/json"/>
        <add enabled="false" mimeType="*/*"/>
      </staticTypes>
    </httpCompression>

That’s all there is to it – if you can accomplish this, you should start to see improved scores on website speed test assessments. However, it’s not the end of the story! There’s more you can do to improve speed, coming up in future posts.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *