<?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>Devon Hillard&#039;s Digital Sanctuary &#187; performance</title>
	<atom:link href="http://www.digitalsanctuary.com/tech-blog/tag/performance/feed" rel="self" type="application/rss+xml" />
	<link>http://www.digitalsanctuary.com/tech-blog</link>
	<description>Java, ATG, Seam, and related Technologies</description>
	<lastBuildDate>Mon, 30 Jan 2012 23:04:32 +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>JBoss Performance Tuning and MasterTheBoss</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/jboss-performance-and-mastertheboss.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/jboss-performance-and-mastertheboss.html#comments</comments>
		<pubDate>Tue, 02 Nov 2010 15:36:59 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[JBoss]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=716</guid>
		<description><![CDATA[I review technical book manuscripts for a few different publishers, and recently had the pleasure of working on an upcoming book called JBoss Performance Tuning by Francesco Marchioni.  It&#8217;s coming out in December 2010 and will be a must have &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/jboss/jboss-performance-and-mastertheboss.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I review technical book manuscripts for a few different publishers, and recently had the pleasure of working on an upcoming book called <a title="JBoss Performance Tuning Book" href="http://www.mastertheboss.com/jboss-server/255-announcing-jboss-performance-tuning-book.html" target="_blank">JBoss Performance Tuning by Francesco Marchioni</a>.  It&#8217;s coming out in December 2010 and will be a must have addition to your bookshelf if you deploy applications on JBoss.</p>
<p>The book contains extensive performance/load test results giving you hard data to work with when deciding which changes to make in your environment.  Some of the results were very surprising and the book has a lot of valuable data.</p>
<p>The author, Francesco Marchioni, also runs a popular <a title="MasterTheBoss Blog" href="http://www.mastertheboss.com" target="_blank">JBoss related blog called MasterTheBoss.com</a>.  There are a ton of great articles and posts there, so check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/jboss-performance-and-mastertheboss.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Speed!</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/google-speed.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/google-speed.html#comments</comments>
		<pubDate>Sun, 02 Aug 2009 04:40:25 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=471</guid>
		<description><![CDATA[Google has a nice collection of tutorials, tech talks, etc&#8230; related to making websites run faster. You can find it here: Let&#8217;s make the web faster. I strongly disagree with the first tutorial however. CSS: Using every declaration just once. &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/general/google-speed.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Google has a nice collection of tutorials, tech talks, etc&#8230; related to making websites run faster.  You can find it here: <a href="http://code.google.com/speed/articles/">Let&#8217;s make the web faster</a>.</p>
<p>I strongly disagree with the first tutorial however.  <a href="http://code.google.com/speed/articles/optimizing-css.html">CSS: Using every declaration just once</a>.  </p>
<p>The premise of the tutorial is that in order to make your website faster, you should make the code you send to the browser smaller (TRUE) and that one of the best ways to optimize CSS files is to use every declaration just once.  This second part is the part I disagree with so strongly.</p>
<p>Basically the author recommends reversing the standard organization of the CSS declarations.  Here are the before and after examples from the tutorial:</p>
<p>Before:</p>
<pre class="brush: css; title: ; notranslate">
h1, h2, h3 { font-weight: normal; }
a strong { font-weight: normal !important; }
strong { font-style: italic; font-weight: normal; }
#nav { font-style: italic; }
.note { font-style: italic; }
</pre>
<p>After:</p>
<pre class="brush: css; title: ; notranslate">
h1, h2, h3, strong { font-weight: normal; }
a strong { font-weight: normal !important; }
strong, #nav, .note { font-style: italic; }
</pre>
<p>So instead of having your selector/class/id contain all of the relevant styling declarations, you group the relevant selectors for each declaration.  It&#8217;s changing the traditional one-to-many relationship of selectors and style declarations to a many-to-one relationship.</p>
<p>The upside, and the premise of the article, is that this reduces the size of the CSS by reducing duplicate lines of declarations.  This is true, but is a very small upside compared with the downside.</p>
<p>The downside of this is that it makes writing, maintaining, and debugging your CSS MUCH harder.  The styles applied to a given selector/element/class/id are now spread out over the entire CSS file.  </p>
<p>If you&#8217;re a Java developer, this is akin to re-factoring every property in every bean you have into their own interface (since Java doesn&#8217;t do multiple inheritance) and having each bean implement a huge number of these interfaces.  It&#8217;s backwards, and makes maintaining your application amazingly difficult.</p>
<p>The other thing is that the CSS file size savings are only 20-40%.  If you&#8217;re gzipping your CSS files on your web server and setting a far futures expiration header (and you are doing both of those things, right?), then the savings are closer to 2-4%.  Totally not worth it considering the downsides above.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/google-speed.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSSQL, jTDS, NVARCHAR and Slow Indexes</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html#comments</comments>
		<pubDate>Sun, 24 May 2009 04:02:50 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=423</guid>
		<description><![CDATA[An application I&#8217;ve built is going into production soon. It&#8217;s the first application I&#8217;ve been involved with which will be using MSSQL server in production, I have some learning about MSSQL to do. After some research, I ended up using &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_424" class="wp-caption alignright" style="width: 250px"><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/05/1276854575_6aa8a88b40_mjpg.jpeg"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/05/1276854575_6aa8a88b40_mjpg.jpeg" alt="Mr. Slow" title="Mr. Slow" width="240" height="238" class="size-full wp-image-424" /></a><p class="wp-caption-text">Mr. Slow by <a href='http://www.flickr.com/photos/vox/'>Vox</a></p></div>
<p>An application I&#8217;ve built is going into production soon.  It&#8217;s the first application I&#8217;ve been involved with which will be using MSSQL server in production, I have some learning about MSSQL to do.  After some research, I ended up using the <a href="http://jtds.sourceforge.net/"> jDTS JDBC driver</a> instead of the Microsoft JDBC driver (which is feature incomplete and has some serious open issues).  </p>
<p>We recently began performance testing and saw some odd behavior.  Initially the application was performing well.  However after few runs of the stress test the performance went from good to awful.  The main web service call went from 600 ms to 23,000 ms.  The database server&#8217;s CPU was pinned, and the app servers were barely loading, spending all their time waiting for the database server to return queries.  Stranger still, my local instance (running against PostgreSQL) performed well with the same code and same stress tests.  Luckily a smart MSSQL DBA was able to figure out why the database was burning so much CPU and responding so slowly.</p>
<p>One of the primary queries is against a table which has been growing.  The select query is simple and had an indexed column in the WHERE clause.  Even as the table grew to over a million rows, it should have been a very quick query.  Unfortunately it was taking several seconds to complete.  My local instance had over 30 million rows in the same table in PostgreSQL and the query was lightening fast.  The DBA discovered that the query execution was converting the indexed varchar column into nvarchar values for comparison with the query parameter used in the WHERE clause which was inexplicably coming over as an nvarchar.  This datatype mismatch between the column definition and the query parameter meant that MSSQL was doing a scan of the million+ record index instead of the almost instant seek it should have been doing.  </p>
<p>It turns out that jTDS sends String parameters over as Unicode (nvarchar) by default.  It&#8217;s easily fixed by adding this property to your connection-url:</p>
<pre class="brush: plain; title: ; notranslate">
sendStringParametersAsUnicode=false
</pre>
<p>That immediately fixed the performance issues.  </p>
<p>So, if you&#8217;re using jTDS and are using indexed varchar columns in your queries, you should add the property above to avoid your indexes being wasted and your queries running slowly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/mssql-jtds-nvarchar-and-slow-indexes.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Smush.it Shrinks Your Images</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/smushit-shrinks-your-images.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/smushit-shrinks-your-images.html#comments</comments>
		<pubDate>Wed, 11 Mar 2009 01:12:59 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=298</guid>
		<description><![CDATA[In my post on Improving Secondary Asset Loading Time in order to increase the performance of your web application I briefly touched on shrinking your media files to the smallest size that will give you acceptable quality. Rather than waste &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/general/smushit-shrinks-your-images.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my post on <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/improving-secondary-asset-loading-time-for-an-atg-application.html">Improving Secondary Asset Loading Time</a> in order to increase the performance of your web application I briefly touched on shrinking your media files to the smallest size that will give you acceptable quality.</p>
<p>Rather than waste your time playing with Photoshop export settings for each image, you can now use <a href="http://smush.it/" target="_new">Smush.i</a>t, a web applicaiton built to shrink your image files for you:</p>
<blockquote><p>Performance just got a little bit easier. Optimizing images by hand is time consuming and painful. Smush it does it for you.</p></blockquote>
<p>I&#8217;ve used it on a few images, and so far I&#8217;m impressed with the results. </p>
<p>Do you have any handy tricks for optimizing the size of your media files?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/smushit-shrinks-your-images.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Additional CDN Information</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/additional-cdn-information.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/additional-cdn-information.html#comments</comments>
		<pubDate>Sat, 24 Jan 2009 06:42:18 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[akamai]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=236</guid>
		<description><![CDATA[A few popular commercial CDN services are: Akamai Mirror Image Multicast Media Limelight End user performance is typically increased roughly 20-25% by the addition of a good CDN solution. This does not count the reduced capacity requirements of your server &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/additional-cdn-information.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/01/908946494_c37f4e8970.jpg"><img src="http://www.digitalsanctuary.com/tech-blog/wp-content/uploads/2009/01/908946494_c37f4e8970.jpg" alt="Speed" title="Speed" width="400" height="300" class="alignright size-full wp-image-254" /></a><br />
A few popular commercial CDN services are:</p>
<ul>
<li><a href="http://www.akamai.com/">Akamai</a></li>
<li><a href="http://www.mirror-image.com/">Mirror Image</a></li>
<li><a href="http://www.multicastmedia.com/">Multicast Media</a></li>
<li><a href="http://www.limelightnetworks.com/">Limelight</a></li>
</ul>
<p>End user performance is typically increased roughly 20-25% by the addition of a good CDN solution.  This does not count the reduced capacity requirements of your server farm, which is an added bonus.</p>
<div style="clear:both"></div>
<div class="alignright"><font size="-4">Photo by <a href="http://www.flickr.com/photos/laserstars/">jpctalbot</a></font></div>
<div style="clear:both"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/additional-cdn-information.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving ATG Performance With a CDN</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-atg-performance-with-a-cdn.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-atg-performance-with-a-cdn.html#comments</comments>
		<pubDate>Mon, 19 Jan 2009 23:13:57 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=231</guid>
		<description><![CDATA[Why use a CDN? A Content Delivery Network, or CDN, is essentially a system of geographically distributed web servers which serve static content, typically images, video, and other bandwidth intensive files. This serves two purposes: it keeps your servers from &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/improving-atg-performance-with-a-cdn.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>Why use a CDN?</h3>
<p>A Content Delivery Network, or CDN, is essentially a system of geographically distributed web servers which serve static content, typically images, video, and other bandwidth intensive files.  This serves two purposes: it keeps your servers from having to handle those requests and it serves those files to the end user from a low latency server closer to the user (network-wise).  Both of these aspects improve the user&#8217;s perception of page and site performance.  CDNs can also be extremely useful for things like streaming video or other very high bandwidth uses.  </p>
<h3>How do CDNs work?</h3>
<p>CDNs typically work in one of two ways: for some you have to deploy the files to the CDN manually via FTP or some similar mechanism while others work as a transparent proxy automatically loading the files from the source or origin (your servers) into the CDN as users request them.  The latter is preferable as you don&#8217;t need to take the CDN into consideration when building your application&#8217;s page and referencing media, this also makes handling non-production environments more complex.  Also it allows the media to be reloaded from the origin based on cache expiration headers, so you don&#8217;t need to do anything special during deployments of new media.  However those CDN solutions also seem to be more expensive, so it&#8217;s a balance you have to weigh yourself.</p>
<h3>Roll Your Own Apache Pseudo CDN</h3>
<p>You can also roll a pseudo-CDN yourself using Apache.  I call it a pseudo-CDN because unlike Akamai and other large providers you don&#8217;t get the advantages of hundreds or thousands of geographically distributed servers.  You also don&#8217;t get lots of fancy math routing user&#8217;s requests to the quickest servers based on location, network congestion, and more.  What you do get is transparent proxying and off-loading the request handling from your application servers.  </p>
<p>This means you don&#8217;t have to do anything special or complex when coding your web application and your JSPs to facilitate the CDN, and it means that your application servers are freed up from having to handle the requests for static media, large and small, which means they have more CPU time available for handling the real dynamic processing of your web application.</p>
<p>Apache makes this simple by way of the mod_disk_cache module.  I&#8217;d recommend avoiding the mod_mem_cache.  Even though it sounds like it would be the preferred caching mechanism, I have had significant problems with mem_cache, and have abandoned it.  If you&#8217;re using Linux (and you should be) the kernel&#8217;s ability to aggressively cache recently accessed files means that when you&#8217;re using mod_disk_cache, Apache will cache the files you specify on the local hard drive and will use all available RAM to cache those files in memory for rapid serving.  If you plan on using <a href="http://www.digitalsanctuary.com/tech-blog/general/apache-mod_deflate-and-mod_cache-issues.html">mod_gzip and mod_disk_cache together, please read my post on the issues encountered using them together</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-atg-performance-with-a-cdn.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Improving Secondary Asset Loading Time for an ATG Application</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-secondary-asset-loading-time-for-an-atg-application.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-secondary-asset-loading-time-for-an-atg-application.html#comments</comments>
		<pubDate>Sun, 18 Jan 2009 00:47:42 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=219</guid>
		<description><![CDATA[Now that we covered improving the performance of serving the HTML from the JSP, we need to tackle the bigger problem of all of the secondary assets and media that the page loads to display correctly. This includes images, Javascript, &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/improving-secondary-asset-loading-time-for-an-atg-application.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now that we covered improving the performance of serving the HTML from the JSP, we need to tackle the bigger problem of all of the secondary assets and media that the page loads to display correctly.  This includes images, Javascript, CSS, Flash, videos, etc&#8230;</p>
<p>The reason that these secondary page assets are so critical for page performance is two-fold.  First, there are many more of them for each page than the single HTML file.  This means more HTTP connections have to opened and closed, more files have to be transfered from the server to the user&#8217;s computer.  This takes a lot of time.  Second, most of these assets tend to be static, they don&#8217;t change very often.  This means we can cache them.</p>
<h3>Reduce the number of assets</h3>
<p>The first thing we need to do is to try to reduce the number of secondary assets which need to be loaded.  You can try to simplify the page design to require less assets, reduce the number of images used, replace images with text (which is more accessible and search engine friendly anyhow), etc&#8230;  Also reducing large files like videos and Flash files can make a significant improvement on page load times.  Personally, for things other than video players and similar things, I strongly dislike the use of Flash.  There is an impressive amount of rich interface and interaction that can be created using DHTML and AJAX.  It generally performs better, loads faster, and is easier to make search engine friendly.</p>
<p><span id="more-219"></span></p>
<p>Another approach is to try to combine multiple CSS or JavaScript files into a single CSS file and a single JavaScript file.  However, this makes managing the CSS and JavaScript during development much more difficult, especially if you&#8217;re using 3rd party CSS or JavaScript files or libraries.  So I don&#8217;t do that.  There is a great taglib which solves this problem for you.  <a href="http://www.galan.de/projects/packtag">pack:tag</a>.  This tag library allows you to reference multiple JavaScript or CSS files from your JSPs.  It then merges the files together and optionally minify and gzip compresses them.  This allows you to develop and maintain CSS and JavaScript files which are organized logically by functionality, and yet only serve a single, minified, gzip compressed, JavaScript or CSS file to the end user.  This can be a huge benefit.  For instance the BestBuy Televisions page we used as an example before references 23 external JavaScript files.  Reducing that down to 1 minified file would dramatically increase the performance of the page.</p>
<p>While we&#8217;re talking about JavaScript, try to put the JavaScript references at the bottom of the page, this reduces the time the browser waits before rendering the DOM tree.  And you should also put the CSS scripts inside the head of the HTML document.</p>
<p>We can also reduce the number of images we request by using <a href="http://www.alistapart.com/articles/sprites">CSS Sprites</a>.  This is method of putting a number of small images into a single large image and referencing the images based on the coordinates.  The downside is that you have to manage/edit the images within the single large image file.  The upside is you can dramatically reduce the number of HTTP requests for images to build the page.</p>
<h3>Reduce file sizes</h3>
<p>We need to also reduce file sizes, if we can.  Images, Flash files, video files, etc&#8230; should all be examined to ensure they are encoded for the minimal size possible and to still maintain the quality needed.</p>
<h3>Caching files</h3>
<p>Now that we&#8217;ve reduced the number of files that need to be loaded, and ideally their size, the next step is to reduce the number of times they need to be loaded.  Your basic website will use the same general CSS file(s) and maybe a few commonly used JavaScript files, the same widgets and design images on almost every page.  The default behavior is for the browser on the end user&#8217;s computer to request those files each time a new page is loaded.  This is obviously wasteful. By setting the appropriate HTTP headers in the response with a file, you can tell the browser to cache the file for some period of time, and not request it again.  This lets the subsequent pages use an image or CSS file that is loaded from the end user&#8217;s computer (memory cache or hard disk cache), which is much faster.  Many times those files can be safely cached for days or weeks, which means every time the end user returns to your site, the pages load rapidly.</p>
<p>If you&#8217;re using ATG on DAS, you can use this <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/atg-cache-header-control-module.html">ATG pipeline Servlet I create to set the cache related headers</a> easily.  If you are using JBoss as your application server then you&#8217;ll want to look at this <a href="http://www.digitalsanctuary.com/tech-blog/java/jboss/setting-cache-headers-from-jboss.html">cache header managing Servlet filter</a> that I wrote.</p>
<h3>Summary</h3>
<p>At this point the user&#8217;s browser should be requesting fewer, smaller secondary assets to display the webpage, and should only be requesting them once (per expiration time period-week or day).  Not only does this make pages load much more quickly, but with the use of caching the static content on the browser, you&#8217;ve dramatically reduced the number of HTTP requests that hit the server, thus freeing up your web application cluster to handle more users and page requests on the same hardware.  Plus it reduces your bandwidth used, which can save money.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-secondary-asset-loading-time-for-an-atg-application.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Setting Cache Headers from JBoss</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/jboss/setting-cache-headers-from-jboss.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/jboss/setting-cache-headers-from-jboss.html#comments</comments>
		<pubDate>Thu, 15 Jan 2009 19:15:20 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[JBoss]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=214</guid>
		<description><![CDATA[Having control over the HTTP response headers allows you to set cache related headers in responses for various content you&#8217;d like cached on the browser (or an intermediary proxy). I created the ATG Cache Control DAS pipeline Servlet a year &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/jboss/setting-cache-headers-from-jboss.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Having control over the HTTP response headers allows you to set cache related headers in responses for various content you&#8217;d like cached on the browser (or an intermediary proxy).  I created the <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/atg-cache-header-control-module.html">ATG Cache Control DAS pipeline Servlet</a> a year ago, but when you&#8217;re using JBoss you need another solution.</p>
<p>Since the DAF pipeline is only executed for JSPs the pipeline Servlet it doesn&#8217;t allow you to set headers for the static media items you&#8217;re more likely to want to cache.  I created a Servlet Filter which allows you to set cache headers in JBoss based on URI patterns.  It doesn&#8217;t allow the same fine grained control that the old pipeline Servlet does, but it should work for most situations.</p>
<p>Servlet Filters are very similar to ATG pipeline Servlets in that they are executed within the lifecycle of a request and can read the request and modify the response.  The filter I created gets configured from the web.xml and sets the response headers relating to caching.  You can configure different instances of the filter for each cache time you need, an hour, a day, or a week, and map different URL patterns to the appropriate instances.</p>
<p>I&#8217;ve added the filter into <a href="https://developer.sparkred.com/confluence/display/ATGDC/Foundation">Foundation</a>, the open source ATG e-commerce framework project, which is hosted at the <a href="http://sparkred.com/">Spark::red</a> <a href="https://developer.sparkred.com">Development Community</a>.</p>
<p>The Servlet filter code looks like this:</p>
<pre class="brush: java; title: ; notranslate">
package org.foundation.servlet.filter;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * The Class CacheHeaderFilter.
 *
 * @author Devon Hillard
 */
public class CacheHeaderFilter implements Filter {

    /**
     * The Constant MILLISECONDS_IN_SECOND.
     */
    private static final int MILLISECONDS_IN_SECOND = 1000;

    /** The Constant POST_CHECK_VALUE. */
    private static final String POST_CHECK_VALUE = &quot;post-check=&quot;;

    /** The Constant PRE_CHECK_VALUE. */
    private static final String PRE_CHECK_VALUE = &quot;pre-check=&quot;;

    /** The Constant MAX_AGE_VALUE. */
    private static final String MAX_AGE_VALUE = &quot;max-age=&quot;;

    /** The Constant ZERO_STRING_VALUE. */
    private static final String ZERO_STRING_VALUE = &quot;0&quot;;

    /** The Constant NO_STORE_VALUE. */
    private static final String NO_STORE_VALUE = &quot;no-store&quot;;

    /** The Constant NO_CACHE_VALUE. */
    private static final String NO_CACHE_VALUE = &quot;no-cache&quot;;

    /** The Constant PRAGMA_HEADER. */
    private static final String PRAGMA_HEADER = &quot;Pragma&quot;;

    /** The Constant CACHE_CONTROL_HEADER. */
    private static final String CACHE_CONTROL_HEADER = &quot;Cache-Control&quot;;

    /** The Constant EXPIRES_HEADER. */
    private static final String EXPIRES_HEADER = &quot;Expires&quot;;

    /** The Constant LAST_MODIFIED_HEADER. */
    private static final String LAST_MODIFIED_HEADER = &quot;Last-Modified&quot;;

    /** The Constant CACHE_TIME_PARAM_NAME. */
    private static final String CACHE_TIME_PARAM_NAME = &quot;CacheTime&quot;;

    /** The Static HTTP_DATE_FORMAT object. */
    private static final DateFormat HTTP_DATE_FORMAT = new SimpleDateFormat(&quot;EEE, dd MMM yyyy HH:mm:ss z&quot;, Locale.US);

static {
HTTP_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone(&quot;GMT&quot;));
}

    /** The reply headers. */
    private String[][] mReplyHeaders = { {} };

    /** The cache time in seconds. */
    private Long mCacheTime = 0L;

    /**
     * Initializes the Servlet filter with the cache time and sets up the unchanging headers.
     *
     * @param pConfig the config
     *
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    public void init(final FilterConfig pConfig) {
        final ArrayList&lt;String[]&gt; newReplyHeaders = new ArrayList&lt;String[]&gt;();
        this.mCacheTime = Long.parseLong(pConfig.getInitParameter(CACHE_TIME_PARAM_NAME));
        if (this.mCacheTime &gt; 0L) {
            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, MAX_AGE_VALUE + this.mCacheTime.longValue() });
            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, PRE_CHECK_VALUE + this.mCacheTime.longValue() });
            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, POST_CHECK_VALUE + this.mCacheTime.longValue() });
        } else {
            newReplyHeaders.add(new String[] { PRAGMA_HEADER, NO_CACHE_VALUE });
            newReplyHeaders.add(new String[] { EXPIRES_HEADER, ZERO_STRING_VALUE });
            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, NO_CACHE_VALUE });
            newReplyHeaders.add(new String[] { CACHE_CONTROL_HEADER, NO_STORE_VALUE });
        }
        this.mReplyHeaders = new String[newReplyHeaders.size()][2];
        newReplyHeaders.toArray(this.mReplyHeaders);
    }

    /**
     * Do filter.
     *
     * @param pRequest the request
     * @param pResponse the response
     * @param pChain the chain
     *
     * @throws IOException Signals that an I/O exception has occurred.
     * @throws ServletException the servlet exception
     *
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
     *      javax.servlet.FilterChain)
     */
    public void doFilter(final ServletRequest pRequest, final ServletResponse pResponse, final FilterChain pChain)
            throws IOException, ServletException {
        // Apply the headers
        final HttpServletResponse httpResponse = (HttpServletResponse) pResponse;
        for (final String[] replyHeader : this.mReplyHeaders) {
            final String name = replyHeader[0];
            final String value = replyHeader[1];
            httpResponse.addHeader(name, value);
        }
        if (this.mCacheTime &gt; 0L) {
            final long now = System.currentTimeMillis();
             final DateFormat httpDateFormat = (DateFormat) HTTP_DATE_FORMAT.clone();
            httpResponse.addHeader(LAST_MODIFIED_HEADER, httpDateFormat.format(new Date(now)));
            httpResponse.addHeader(EXPIRES_HEADER, httpDateFormat.format(new Date(now
                    + (this.mCacheTime.longValue() * MILLISECONDS_IN_SECOND))));
        }
        pChain.doFilter(pRequest, pResponse);
    }

    /**
     * Destroy all humans!
     *
     * @see javax.servlet.Filter#destroy()
     */
    public void destroy() {
    }

}
</pre>
<p>And the web.xml configuration looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
	&lt;filter&gt;
		&lt;filter-name&gt;CacheFilterOneWeek&lt;/filter-name&gt;
		&lt;filter-class&gt;org.foundation.servlet.filter.CacheHeaderFilter&lt;/filter-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;CacheTime&lt;/param-name&gt;
			&lt;param-value&gt;604800&lt;/param-value&gt;
		&lt;/init-param&gt;
	&lt;/filter&gt;

	&lt;filter&gt;
		&lt;filter-name&gt;CacheFilterOneDay&lt;/filter-name&gt;
		&lt;filter-class&gt;org.foundation.servlet.filter.CacheHeaderFilter&lt;/filter-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;CacheTime&lt;/param-name&gt;
			&lt;param-value&gt;86400&lt;/param-value&gt;
		&lt;/init-param&gt;
	&lt;/filter&gt;

	&lt;filter&gt;
		&lt;filter-name&gt;CacheFilterOneHour&lt;/filter-name&gt;
		&lt;filter-class&gt;org.foundation.servlet.filter.CacheHeaderFilter&lt;/filter-class&gt;
		&lt;init-param&gt;
			&lt;param-name&gt;CacheTime&lt;/param-name&gt;
			&lt;param-value&gt;3600&lt;/param-value&gt;
		&lt;/init-param&gt;
	&lt;/filter&gt;

.......

&lt;filter-mapping&gt;
		&lt;filter-name&gt;CacheFilterOneDay&lt;/filter-name&gt;
		&lt;url-pattern&gt;*.js&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;
	&lt;filter-mapping&gt;
		&lt;filter-name&gt;CacheFilterOneDay&lt;/filter-name&gt;
		&lt;url-pattern&gt;*.css&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;
	&lt;filter-mapping&gt;
		&lt;filter-name&gt;CacheFilterOneWeek&lt;/filter-name&gt;
		&lt;url-pattern&gt;*.jpg&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;
	&lt;filter-mapping&gt;
		&lt;filter-name&gt;CacheFilterOneWeek&lt;/filter-name&gt;
		&lt;url-pattern&gt;*.gif&lt;/url-pattern&gt;
	&lt;/filter-mapping&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/jboss/setting-cache-headers-from-jboss.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Improving JSP Serving Time for an ATG Application</title>
		<link>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-jsp-serving-time-for-an-atg-application.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-jsp-serving-time-for-an-atg-application.html#comments</comments>
		<pubDate>Mon, 12 Jan 2009 23:15:54 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=200</guid>
		<description><![CDATA[Improving the performance of the JSPs that serve your HTML pages is the first step in improving the overall site performance. The user&#8217;s browser can not start rendering the page or requesting the secondary media. Also the faster the page &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/improving-jsp-serving-time-for-an-atg-application.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Improving the performance of the JSPs that serve your HTML pages is the first step in improving the overall site performance.  The user&#8217;s browser can not start rendering the page or requesting the secondary media.  Also the faster the page request is completed, the sooner you have a thread free to handle the next request.</p>
<p>There are two parts to this:  first, the time it takes the JSP servlet to generate the HTML response, and secondly the time it takes to transmit that HTML response back to the user&#8217;s browser.</p>
<h3>Caching content sections</h3>
<p>The easiest way to reduce the time it takes for the JSP servlet to generate the response is by reducing the amount of dynamic content on the page.  Or more precisely by reducing the amount of real-time or unique individual content on the page.  </p>
<p>The Cache droplet is THE most under-utilized ATG droplet.</p>
<p>The Cache droplet caches the rendered output of the contents of the oparam based on a content key (such as category, user gender, logged in/logged out state, etc..) for a configured period of time.  This can be very useful for things like navigation menus dynamically built based on the catalog.  The catalog won&#8217;t change too often, so this dynamically generated menu can be safely cached for hours.  Or for some or all of a category or product page, when you set the key to the category id or product id.</p>
<p>Look at your pages and evaluate what parts of the page don&#8217;t change that frequently.  Even if you can only cache the page or block for five minutes, that can be a huge performance win.</p>
<p>Read on for more&#8230;.<br />
<span id="more-200"></span></p>
<p>I&#8217;ll talk about things like repository caching and other related topics when I dive into the server side of performance tuning your ATG application in a future post.</p>
<h3>Reduce CPU utilization in page rendering</h3>
<p>You&#8217;re also going to want to look at potential CPU draining elements of your pages.  Think about what has to happen to render the page.  Don&#8217;t use RQLQueryForEach if you have the Repository Id you want, just use the RepositoryLookup droplet.  Don&#8217;t loop through collections if you don&#8217;t have to.  Think through it.  If you have to do something computationally expensive, don&#8217;t do it twice.  If you need the same data later just store the first result in a param or JSP variable.</p>
<h3>Reduce the size of the HTML</h3>
<p>Now that we&#8217;ve reduced the CPU time need to render the JSP, we need to reduce the amount of time it takes to transmit to the end user.  First, we want to shrink the generated HTML.  The smaller the output HTML is, the less time it will take to transfer across the wire to the end user.  Also, you want to keep the HTML output under 100k, as Google does not index page content over the first 100k (that&#8217;s 100k ungzipped).  Also, the smaller the HTML is, the quicker the browser can parse it out into the DOM tree.  </p>
<p>Don&#8217;t use inline JavaScript or CSS styles in your JSP.  Extract them out into separate JavaScript and CSS files.  This reduces the size of the output HTML, and increases the amount of content that the browser can cache locally (more on this in my future post on secondary media).  </p>
<p>Simplify the html structure as much as you can.  Don&#8217;t use more tags than you need.  I&#8217;ve seen an amazing amount of useless nested divs on pages.  </p>
<p>Move comments from HTML comments to JSP comments (if you can).  Most comments shouldn&#8217;t be seen by end users anyhow.</p>
<p>Reduce spaces.  This is huge.  JSPs (especially ones heavy in ATG droplets) tend to generate a huge amount of extraneous spaces.  Part of it is that you generally want to format the JSP files using spaces and tabs to make it easy to see the tag hierarchy structure.  It makes development and maintenance much easier.  Unfortunately these linefeeds, tabs, and spaces get multiplied by iterative or recursive droplets, and other outputs.  </p>
<p>For instance the ATG home page source has 431 lines.  103 are blank.  The BestBuy televisions page has 2519 lines and 902 are blank.  If you take that BestBuy page, and remove the extra blank lines, comments, and inline JavaScript and CSS, it goes from 98k to 80k.  That&#8217;s a 20% size reduction, or a 20% transfer speed improvement.  </p>
<p>If you&#8217;re using JBoss the Tomcat engine has an option to strip out extraneous whitespace.  It doesn&#8217;t remove all of it, but it helps with multiple blank lines very well.  In the tomcat55.sar/conf/web.xml file add the following init param to the &lt;servlet-name>jsp&lt;/servlet-name> section:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;init-param&gt;
     &lt;param-name&gt;trimSpaces&lt;/param-name&gt;
     &lt;param-value&gt;true&lt;/param-value&gt;
&lt;/init-param&gt;
</pre>
<p>This, and other helpful performance configurations are listed in the Tuning Site Performance section of the Installation and Configuration Guide for JBoss Application Server ATG documentation.  You should really read through the whole thing, and generally follow it.</p>
<h3>Compressing the HTML response using gzip</h3>
<p>Now we&#8217;ve reduced the size of the HTML the JSP is outputting.  We can further shrink the data we need to send from our server cluster to the end user&#8217;s browser, hence making the HTML transfer faster, by compressing the HTML using gzip.  Most modern browsers understand gzipped content and decompress it on the fly.  Some don&#8217;t, and we&#8217;ll work around those in a moment.</p>
<p>Assuming you&#8217;re using JBoss for your application server and Apache for your web server, you actually have two options for gzipping the content: You can compress it from within JBoss Tomcat, or you can compress it as it passes through the Apache web server.</p>
<p>If you want to compress it within JBoss you can configure Tomcat to do that by editing the tomcat55.sar/conf/server.xml file.  Find the connector you are using (the one with port=&#8221;8080&#8243; for HTTP, or port=&#8221;8009&#8243; if you&#8217;re using AJP) and add the following properties to that section:</p>
<pre class="brush: xml; title: ; notranslate">
compression=&quot;on&quot;
compressionMinSize=&quot;2048&quot;
noCompressionUserAgents=&quot;gozilla, traviata&quot;
compressableMimeType=&quot;text/html,text/xml&quot;
</pre>
<p>That should use gzip compression for output that is html or xml, and is greater than 2k in size.</p>
<p>I prefer to perform the gzip compression in Apache instead of JBoss/Tomcat.  Firstly the Apache deflate module is more flexible than the Tomcat option, allowing greater control of compression based on path, mimetype, extension, browser, and more.  Second in a three-tier infrastructure, the web servers are typically acting as pass-through proxies, plus handling some caching perhaps (more on this later), but are generally light on CPU utilization, but higher on thread and bandwidth usage.  App servers on the other hand are using this CPUs a great deal to actually handle the dynamic application.  Gzipping the outgoing content does use some CPU power, so I prefer to have that load be on the web servers who can handle it easily, versus having it impact the application performance.</p>
<p>To make Apache gzip compress the output, you need to enable <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html" target="_new">mod_deflate</a>.</p>
<p>You then need to configure the module using settings similar to this:</p>
<pre class="brush: xml; title: ; notranslate">
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSIE no-gzip 

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSIE\s7  !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|swf|flv)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</pre>
<p>You can read more about this configuration, plus some <a href="http://www.digitalsanctuary.com/tech-blog/general/apache-mod_deflate-and-mod_cache-issues.html">issues that arise when using mod_disk_cache and mod_deflate together here</a>.  You can get around this by only gzipping html output from your JSPs, which you won&#8217;t be caching anyhow, however doing that in a clean fashion appears to be tricky.  The <strong>AddOutputFilterByType</strong> directive <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=31226" target="_new">doesn&#8217;t work with proxied content, and the mod_filter based approach</a> for that is only built into Apache 2.1 and 2.2, so if you&#8217;re on 2.0 it&#8217;s no good.  When I have a good solution for Apache 2.0 + ATG, I&#8217;ll post about it.</p>
<p>By gzipping the HTML we can reduce the BestBuy page further, from 80k to 14k, an additional 80% reduction.  We&#8217;ve shrunk the data that has to transfer to the end user&#8217;s computer by a total of 85% at this point.  This means the end user&#8217;s browser can parse the HTML dom tree, display the page, and start loading the secondary media (images, css, js, etc&#8230;) 85% faster.  It also means your request handling thread is now free that much faster (after doing the actual processing of the JSP servlet) and is available to handle a new request.</p>
<h3>Summary</h3>
<p>So at this point we&#8217;ve made the JSP as efficient as possible, used the Cache droplet wherever we could, reduced the size of the output HTML, and gzipped the HTML for faster transmission to the end user.  We&#8217;ve taken a 98k page and ended up only having to move 14k across the wire.</p>
<p>Next we&#8217;ll look at all those secondary media files that your page needs: JavaScript, CSS, images, video, Flash, etc&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/java/atg/improving-jsp-serving-time-for-an-atg-application.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Why Is User Experience Performance So Important?</title>
		<link>http://www.digitalsanctuary.com/tech-blog/general/why-is-user-experience-performance-so-important.html</link>
		<comments>http://www.digitalsanctuary.com/tech-blog/general/why-is-user-experience-performance-so-important.html#comments</comments>
		<pubDate>Wed, 31 Dec 2008 22:32:25 +0000</pubDate>
		<dc:creator>Devon</dc:creator>
				<category><![CDATA[ATG]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.digitalsanctuary.com/tech-blog/?p=195</guid>
		<description><![CDATA[In my ATG Performance Tuning post I mentioned that how a user perceives the site performance impacts their behavior on the site, and that a fast site leads to more purchases/traffic/etc&#8230; Here are some numbers to back that up: Amazon &#8230; <a href="http://www.digitalsanctuary.com/tech-blog/general/why-is-user-experience-performance-so-important.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.digitalsanctuary.com/tech-blog/java/atg/atg-performance-tuning.html">ATG Performance Tuning</a> post I mentioned that how a user perceives the site performance impacts their behavior on the site, and that a fast site leads to more purchases/traffic/etc&#8230;</p>
<p>Here are some numbers to back that up:</p>
<ul>
<li>Amazon found that a 100ms increase in page response time led to a 1% DROP in sales, or conversely improving a page response time by 100ms will increase sales 1%.  I suspect that this effect continues beyond the 100ms mark, but probably tapers off at some point.</li>
<li>Google found that an 500ms increase in page response time led to a 20% drop in traffic and revenue.  This is despite the 3X increase in search results delivered (30 results instead of the default 10) to the test group.</li>
<li>Google also found that a 30% reduction in page size resulted in 30% more traffic/usage due to faster loading and rendering.</li>
</ul>
<p>Given the relatively low cost/time in performance tuning your application, the resultant gain of 1%-20%+ in revenue makes it a smart move.</p>
<blockquote><p>&#8220;As Google gets faster, people search more, and as it gets slower, people search less&#8221;<br />
&#8211; Marissa Mayer, Google vice president of search products and user experience</p></blockquote>
<p>This is also true for your website, just replace search with &#8220;buy&#8221;, &#8220;read&#8221;, etc&#8230;</p>
<p>In fact, I&#8217;ll lay down a wager:  If you improve the page rendering time of the most visited pages of your ATG site by over 10% or 100ms (which ever is greater), and you don&#8217;t see any improvement in your goal conversion (purchases, sign-ups, whatever your measured goal is) I will give you an iPhone.</p>
<p>My up-coming posts on ATG Performance Tuning will make it easy to improve the page performance much more than that.  I&#8217;d expect most ATG sites can cut the user experience of page loading and rendering time by 50%, or more, based on the advice I will be posting here.</p>
<p>So check back often!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.digitalsanctuary.com/tech-blog/general/why-is-user-experience-performance-so-important.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/50 queries in 0.010 seconds using disk: basic
Object Caching 778/887 objects using disk: basic

Served from: www.digitalsanctuary.com @ 2012-02-07 00:18:31 -->
