Currently the main focus of my work has been on developing a web portal that allows users to control hosting based services, and automates the provisioning, so there is mininal work to be done manually. We recently deployed a new version of the front-end, which incorporated extensive use of jQuery as well as AJAX to give the site a more modern look, as well as improving it’s usability. The main issue that we found once we had deployed the software is that it resulted in some very slow load times, so I spent a few days working doing what I could to increase the performance of the site. After all, a site might be fantastic, but if it’s not quick, people aren’t going to use it.
Luckily my boss has given me permission to share some of the benefits of my research both here and on the companies blog. The versions I write here will contain a slightly slimmed down version of the original posts.
The first step was to fire up Yahoo!s YSlow addon and Google’s Page Speed addon for Firefox, and see what we could do to speed things up. We found one of the main issues was that we were loading so many different css and js files that it was slowing everything right down to a crawl. It was decided that the first step was for us combine there into one file. On top of this, we also needed to minify our CSS and JS, to make sure the files we were sending were as small as possible. This can make development very difficult though, if not impossible. This meant that for us to do this correctly, we needed to have the standard CSS and JS files during development, and have them combine automatically when deploying. We discovered the Yahoo! Yui Compressor. All we needed was a way to use this compressor automatically while deploying. In comes Powershell.
Powershell is very handy when working with Windows servers. As we run theCloud on IIS7 we were able to modify it with our Powershell script. Combine this with some code to export the code from SVN, modify the code as required, and then updating IIS to point to the new code base, we now have an all-in-one deployment script that leaves us with a restore point in case anything goes wrong, minifies and combines all of our CSS and JS files, and cleans up anything that doesnt need to be on the server.
First of all, we create a tag of the release in SVN based on the deployment time/date. We will also be using this tag as a version number later on.
#This will get the SVN username and password from whoever is doing the release $credentials = Get-Credential $SVNCredentials = $credentials.GetNetworkCredential() $basePath = "" #this is where you put the base url of your SVN repository $project = "" #this is the name of your project in SVN $tag = Get-Date -Format yyyyMMddhhmm $tagURL = "$basePath/$project/tags/$tag" $trunkURL = "$basePath/$project/trunk" #create the tag in SVN svn copy $trunkURL $tagURL --username $SVNCredentials.username --password $SVNCredentials.password --message "tagging release" #export a copy of the codebase to the local server $baseFolder = "C:inetpubwwwroot" svn export $tagURL $newPath --username $SVNCredentials.username --password $SVNCredentials.password $newPath = $baseFolder + $project + "_v" + $tag
Once this has completed you should have a copy of the new code base sitting in a folder in your web root. Now, we adjust the code by minifying and combining the JS and CSS files, as well as removing any test code or other files that are included in SVN, that we dont want on the live site. The YUI Compressor is available as a JAR file, which can be run directly from within the Powershell script. We keep a copy of the JAR file in the root folder of our site in SVN, so that it is pulled down with our code export.
Get-Content $newPath/js/*.js | java -jar $newPath/yuicompressor-2.4.2.jar --type js -o $newPath/js/thecloud-$tag.min.js Get-Content $newPath/css/*.css | java -jar $newPath/yuicompressor-2.4.2.jar --type css -o $newPath/css/thecloud-$tag.min.css
Notice that we are using the version number to tag the resultant file’s name, so that no two deployments have the same name. This is important, as it will force a clients browser to download the latest version of the file each time you deploy, and can avoid caching issues. The issue now is that the references in our HTML code need to be updated so that they point at the correct filename. Again, we can do this inside our Powershell script automatically. Our initial code in our index page will look like this:
<link href="/css/thecloud.min.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="/js/thecloud.min.js"></script>
We open the file in Powershell, and use a string replacement on the content and modify it before saving the file.
$indexPage = Get-Content "$newPath/index.cfm" $indexPage -replace "thecloud.min", "thecloud-$tag.min" | Set-Content -Path $newPath/index.cfm
Next, we delete the unwanted files from the site. This includes our test files (we use MX Unit Tests), our YUI Compressor, and anything else that we dont want live.
Remove-Item "$newPathmxunit" -Recurse -Force #removes the folder and its contents Remove-Item "$newPathyuicompressor-2.4.2.jar" -Force #remove the file
You can also use this to remove your un-modified JS and CSS files. We achieve this by having them in a sub-directory of the main folder, and then saving them to the main folder after modifying them. Then, you simply remove the folder from your code and it’s done.
Now, you have a clean, minified version of your code sitting on your server, waiting to be deployed. The last step is to use Powershell to update IIS to point the root folder of your site at the new site.
$siteName = "theCloud" #this is the name of your site in IIS
[Void][Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration") #this loads the library needed to interact with IIS in Powershell
$serverManager = New-Object Microsoft.Web.Administration.ServerManager
$site = $serverManager.Sites | where { $_.Name -eq $siteName }
$rootApp = $site.Applications | where { $_.Path -eq "/" }
$rootVdir = $rootApp.VirtualDirectories | where { $_.Path -eq "/" }
$rootVdir.PhysicalPath = $newPath
$serverManager.CommitChanges()
And that’s it. The site is now deployed.


