In some cases, your ColdFusion page might contain a combination of dynamic information that ColdFusion must generate each time it displays the page, and information that it generates dynamically, but that change less frequently. In this case, you cannot use the cfcache
tag to cache the entire page. Instead, use the cfsavecontent
tag to cache the infrequently changed content.
The cfsavecontent
tag saves the results of processing the tag body in a variable. For example, if the body of the cfsavecontent
tag contains a cfexecute
tag that runs an executable program that displays data, the variable saves the output.
You can use the cfsavecontent
tag to cache infrequently changing output in a shared scope variable. If the information is used throughout the application, save the output in the Application scope. If the information is client-specific, use the Session scope. Because of the overhead of locking shared scope variables, use this technique only if the processing overhead of generating the output is substantial.
Before you use this technique, also consider whether other techniques are more appropriate. For example, query caching eliminates the need to repeat a common query. However, if the effort of processing the data or formatting the output is substantial, using the cfsavecontent
tag can save processing time.
Using this technique, if the variable exists, the page uses the cached output. If the variable does not exist, the page gets the data, generates the output, and saves the results to the shared scope variable.
The following example shows this technique. It has two parts. The first part welcomes the user and prints out a random lucky number. This part runs and produces a different number each time a user opens the page. The second part performs a database query to get information that changes infrequently; in this example, a listing of the current special sale items. It uses the cfsavecontent
tag to get the data only when needed.
Tip: If you use this technique frequently, consider incorporating it in a custom CFML tag.
<!--- Greet the user. ---> <cfoutput> Welcome to our home page.<br> The time is #TimeFormat(Now())#.<br> Your lucky number is: #RandRange(1,1000)#<br> <hr><br> </cfoutput> <!--- Set a flag to indicate whether the Application scope variable exists.---> <cflock scope="application" timeout="20" type="readonly"> <cfset IsCached = Not IsDefined("Application.ProductCache")> </cflock> <!--- If the flag is false, query the DB, and save an image of the results output to a variable. ---> <cfif not IsCached> <cfsavecontent variable="ProductCache"> <!--- Perform database query. ---> <cfquery dataSource="ProductInfo" name="specialQuery"> SELECT ItemName, Item_link, Description, BasePrice FROM SaleProducts </cfquery> <!--- Calculate sale price and display the results. ---> <h2>Check out the following specials</h2> <table> <cfoutput query="specialQuery"> <cfset salePrice= BasePrice * .8> <tr> <td>#ItemNAme#</td> <td>#Item_Link#</td> <td>#Description#</td> <td>#salePrice#</td> </tr> </cfoutput> </table> </cfsavecontent> <!--- Save the results in the Application scope. ---> <cflock scope="Application" type="Exclusive" timeout=30> <cfset Application.productCache = ProductCache> </cflock> </cfif> <!--- Use the Application scope variable to display the sale items. ---> <cflock scope="application" timeout="20" type="readonly"> <cfoutput>#Application.ProductCache#</cfoutput> </cflock>
The following table describes the code and its function:
Code | Description |
---|---|
<cfoutput> Welcome to our home page.<br> The time is #TimeFormat(Now())#.<br> Your lucky number is: #RandRange(1,1000)#<br> <hr><br> </cfoutput> |
Displays the part of the page that must change each time. |
<cflock scope="application" timeout="20" type="readonly"> <cfset IsCached = IsDefined ("Application.ProductCache")> </cflock> |
Inside a read-only lock, tests to see if the part of the page that changes infrequently is already cached in the Application scope, and sets a Boolean flag variable with the result. |
<cfif not IsCached> <cfsavecontent variable="ProductCache"> |
If the flag is False, uses a |
<cfquery dataSource="ProductInfo" name="specialQuery"> SELECT ItemName, Item_link, Description, BasePrice FROM SaleProducts </cfquery> |
Queries the database to get the necessary information. |
<h2>Check out the following specials</h2> <table> <cfoutput query="specialQuery"> <cfset salePrice = BasePrice * .8> <tr> <td>#ItemNAme#</td> <td>#Item_Link#</td> <td>#Description#</td> <td>#salePrice#</td> </tr> </cfoutput> </table> |
Displays the sale items in a table. Inside a Because this code is inside a |
</cfsavecontent> |
Ends the |
<cflock scope="Application" type="Exclusive" timeout=30> <cfset Application.productCache = productcache> </cflock> |
Inside an Exclusive |
</cfif> |
Ends the code that executes only if the Application.productCache variable does not exist. |
<cflock scope="application" timeout="20" |
Inside a |