I recently released an update to BlogCFC. One of the fixes includes a performance update that I'd like to detail. It isn't that big of a deal. In fact, I assume most folks will consider it quite obvious when they see it. But I missed it for years and figured it would be good to share. To give you a clue - the issue only came about when I updated to the latest ColdFish and also involved the large number of subscribers I have at the blog here. I had noticed for a while now that whenever I published a blog entry, it took a good 10-15 seconds to go through. Let me show you the code and tell me if you can see the issue:

<cffunction name="mailEntry" access="public" returnType="void" output="false" hint="Handles email for the blog."> <cfargument name="entryid" type="uuid" required="true"> <cfset var entry = getEntry(arguments.entryid,true)> <cfset var subscribers = getSubscribers(true)> <cfset var theMessage = ""> <cfset var mailBody = "">

<cfloop query="subscribers">

<cfsavecontent variable="theMessage"> <cfoutput> <h2>#entry.title#</h2> <b>URL:</b> <a href="#makeLink(entry.id)#">#makeLink(entry.id)#</a><br /> <b>Author:</b> #entry.name#<br />

#renderEntry(entry.body,false,entry.enclosure)#<cfif len(entry.morebody)> <a href="#makeLink(entry.id)#">[Continued at Blog]</a></cfif>

<p> You are receiving this email because you have subscribed to this blog.<br /> To unsubscribe, please go to this URL: <a href="#getRootURL()#unsubscribe.cfm?email=#email#&token=#token#">#getRootURL()#unsubscribe.cfm?email=#email#&token=#token#</a> </p> </cfoutput> </cfsavecontent>

<cfif instance.mailserver is ""> <cfmail to="#email#" from="#instance.owneremail#" subject="#variables.utils.htmlToPlainText(htmlEditFormat(instance.blogtitle))# / #variables.utils.htmlToPlainText(entry.title)#" type="html">#theMessage#</cfmail> <cfelse> <cfmail to="#email#" from="#instance.owneremail#" subject="#variables.utils.htmlToPlainText(htmlEditFormat(instance.blogtitle))# / #variables.utils.htmlToPlainText(entry.title)#" server="#instance.mailserver#" username="#instance.mailusername#" password="#instance.mailpassword#" type="html">#theMessage#</cfmail> </cfif> </cfloop>

</cffunction>

(Note, I removed a few lines that weren't relevant.) See the issue? Notice that I loop over the subscribers query. Remember that for my blog here, that query was 300+ users. I loop over every single user and for each, I'm generating a rendered blog entry. Imagine a blog entry with 4 code blocks in it. I ended up running ColdFish's rendering code 1200 times. Ouch.

I rewrote the code to simply pull out the function calls, like so:

<cfset var renderedText = renderEntry(entry.body,false,entry.enclosure)> <cfset var theLink = makeLink(entry.id)> <cfset var rootURL = getRootURL()>

<cfloop query="subscribers">

<cfsavecontent variable="theMessage"> <cfoutput> <h2>#entry.title#</h2> <b>URL:</b> <a href="#theLink#">#theLink#</a><br /> <b>Author:</b> #entry.name#<br />

#renderedText#<cfif len(entry.morebody)> <a href="#theLink#">[Continued at Blog]</a></cfif>

<p> You are receiving this email because you have subscribed to this blog.<br /> To unsubscribe, please go to this URL: <a href="#rooturl#unsubscribe.cfm?email=#email#&token=#token#">#rooturl#unsubscribe.cfm?email=#email#&token=#token#</a> </p> </cfoutput> </cfsavecontent>

There are probably other ways to do this too - but I guess the important take from this is - remember to pay special attention to loops. If you see yourself running some type of function within the loop, consider pulling that out (if possible) so you don't repeat the calls.