[Looking for Charlie's main web site?]

CF911: Are you finding performance problems with CFDOCUMENT? Aware of the important LOCALURL attr.?

Note: This blog post is from 2011. Some content may be outdated--though not necessarily. Same with links and subsequent comments from myself or others. Corrections are welcome, in the comments. And I may revise the content as necessary.
This is something that I find nearly no one has talked about, as a problem and solution. Did you know that by default, a single request doing a CFDOCUMENT may cause CF to execute several additional requests, each doing a CFHTTP to grab any images on the page? even if the images could be found locally on the server? This can be quite tragic.

The good news is that the problem can be solved using the simple LOCALURL attribute. The bad news is that you have to do it at all, and that if you don't do it, it can have such unfortunate and unexpected impact. (And just as bad, again, is that hardly anyone has talked about it.) This entry will elaborate on the issue (and a couple of other possible CFDocument performance issues, as a bonus.)

I've been meaning to write about the importance of this problem and solution (the LocalURL attribute) for a long time (it came out in CF8). Often when I'm helping people with CF troubleshooting problems, whether on mailing lists or in my consulting services, I've been able to show that long-running requests (or an unexpectedly excessive number of requests) were sometimes due to this very problem.

Basics of the LocalURL attribute

Before we go any further, let's start with the details of the attribute (which may surprise many). The following is extracted from a larger blog entry about various CFDocument improvements in CF8 from Adobe Engineer, Rupesh Kumar, back in 2007:

When CFDocument body contains a relative URL, ColdFusion will resolve the relative URL to an absolute URL and will send an HTTP request for this url [emphasis, mine]. A side effect of this is Server ends up sending HTTP request even for local URL or images that are lying on the local file system which obviously hurts the performance. In ColdFusion 8, we have added a new attribute "localURL" to cfdocument tag which if enabled, will try to resolve the relative URLs as file on the local machine.

  • localURL : "true" | "false" It should be enabled if the images used in cfdocument body are on the local machine. This would make the cfdocument engine retrieve the images directly from the file system rather then asking the server for it over http

This attribute helps reducing the load from the server so that the same web server thread can now serve user request instead of serving local images to CFDocument. This also addresses some of the "missing image" problems which I mentioned here. Here is a sample code using this attribute.

<cfdocument format="PDF" localUrl="true">
<table>
<tr>
<td>bird</td>
<td><image src="images/bird.jpg"></td>
</tr>
<tr>
<td>Rose</td>
<td><image src="images/rose.jpg"></td>
</tr>
</table>
</cfdocument>

So why is this an issue?

It would help to make a point of clarification: CFDOCUMENT builds a document (perhaps a PDF or Word doc) on the server, from whatever CFML and/or HTML is within the tags.

As such, CF will need to "get" whatever images (or scripts or css files) are defined on the generated HTML page (as img src, script src, link href, etc.) so it can build the resulting "document" file on the server.

And the point of the dilemma (identified on this page) is that a single CFDOCUMENT with many such img src (or similar) tags will not just cause CF to look to the file system to get the files they point to. Instead, CF will get them via CFHTTP.

Technically, the issue is that CF doesn't necessarily "know" that the location pointed to in the img src and similar tags *is* on the local server. So it presumes it has to get ANY of them using a CFHTTP call. That's what causes the problem, if there are many of them. Using the LOCALURL attribute tells CF instead that it SHOULD look for the files on the local filesystem and NOT do a CFHTTP to get them.

Sadly, this issue is only barely mentioned in the CF Docs page on CFDocument, and it would be easy to miss the point it's trying to make. (It says only that CF "requests the server for images over HTTP even though the image files are stored locally".)

How some tried to workaround the problem with file:// references

While looking around to see who else maybe had talked about this fix (which, as I noted, I found virtually no other references to it), I did find that some people had effectively "solved" the problem by telling CF to use "file:///" protocol references in the img src and similar tags.

Among the entries discussing this were:

It's understandable that people figured it out as a work-around, and perhaps someone even started sharing the idea before CF8 added this attribute, but the LOCALURL would seem generally the way to go.

Some other CFDOCUMENT performance resources

Though not related to the LocalURL attribute, there are some other things that may lead to performance problems.

First, those on CF Standard (as opposed to Enterprise or Developer edition) should know that CFDocument is one of several tags that are single-threaded through CF's "Enterprise Feature Router" (EFR).

Second, there are certainly still other possible CFDocument performance issues, and the following other resources address some of those:

Hope any or all of the info above may be helpful to some readers. Let me know what you think.

For more content like this from Charlie Arehart: Need more help with problems?
  • If you may prefer direct help, rather than digging around here/elsewhere or via comments, he can help via his online consulting services
  • See that page for more on how he can help a) over the web, safely and securely, b) usually very quickly, c) teaching you along the way, and d) with satisfaction guaranteed
Comments
This is kind of unrelated, but relevant at the same time imo. I was having an issue where cfdocument was never completing for one report I was creating. The issue turned out to be that it was trying to access an image that it was blocked from viewing, so the <img> tag was never completed and the pdf was never created. This might have been a unique issue in my case, but hopefully can save someone else some time.

Quick back story - we're going through PCI compliance and our servers that handle credit cards need to be blocked off from the servers that don't. We added an exception to the hosts file to fix this issue.
# Posted By matt | 11/19/11 8:18 PM
Great write-up Charlie. I get about 3 or 4 questions a month on poorly performing CFDOCUMENT - almost always related to a misunderstanding about how cfdocument assembles the resources under the hood. I'll file this away for future reference :)
@Matt, thanks for the extra info.

@Mark, thanks for the encouragement! As for a place to "file it away", check out my (relatively new) cf911.com, and especially the wiki, which I've been feverishly populating the past couple of days. You'll see it's a place I'm organizing info related to CF server troubleshooting, both knowledge (info) and resources (links to blog entries, articles, presos, and more) whether by me or others.

And in fact, I've started with you, so about 20% of the stuff is pointers to your blog entries. Yep, I have been going through yours (and others, as I occasionally have noticed things), and will do many others (Mike Brunt, Steven Erat, Sarge, the webapper guys, the intergral/cfconsultant.com guys, and many more.)

I want it to be a one-stop shop to find all the great stuff focused on cf server troubleshooting, organized and carefully maintained, much like my CF411 (which focuses instead on generic tools and resources of interest to all CFers, but for now just one huge page), or my UGTV (focused on recorded presos, for now a DB-driven list approach). We'll see how the wiki approach goes, and also whether I may open it up to be edited by others. :-)

But since I have a lot of your stuff (and more to come), feel free to spread the word about it if you'd like. I'll be doing so myself once I have more stuff from a few more people, and may also expand on the "info" on each topic that I may provide on some of the pages, beyond just resources.

But to your point, the idea of "filing away a resource for reference" is exactly what I want this to be, and for everyone's benefit. :-) Let me know what you think (any of you seeing this.)
Charlie,
Thank you very much for this valuable blog, I have been working on a large scale application to manipulate PDFs, I will definitely revisit my app to make sure I'm using localURL.
# Posted By Shirak | 11/20/11 11:19 PM
Interestingly, when I added localurl="true" to my CFDocument, it causes a timeout:

"The content of this document process takes more than 60000 milliseconds to process."

Without this attribute my document generates relatively quickly. Any thoughts?

Thanks,
Jason
# Posted By Jason | 11/12/13 11:29 AM
@Jason, that would be odd, as using it should PREVENT the CFDOCUMENT tag from turning your links (link href's, img src's, etc.) into the equivalent of CFHTTP calls, which WOULD make the page take longer for most people.

So I'm curious: does your HTML (or that generated by CFML) within the cfdocument have only local file references? If not, I wonder if somehow it takes longer to get external references when localurl is true. There's not really any discussion in those docs (or my experience) to tell.

But if you may have focused only on looking at img src tags, check also script src's, link href's, and so on. If any of them are not local, then it would seem you should not use the localurl (again, I don't know for sure, but the point is to use it when all those things ARE local files).

Let us know what you may find.

I'll add, as well, that you can use a tool like FusionReactor, or the CF Server Monitor or SeeFusion, to do a stack trace while that request is running, to see what it IS doing that's taking so long. See a blog entry I did:

http://www.carehart....

which shares much more info, and also points you to other resources from myself and others to understand how to use them. I can also help with that (or this in particular) via my remote, short-term CF server troubleshooting consulting services: http://www.carehart....

Either way, do let us know how you get on, Jason.
Hi Charlie,

As it turns out, I wasn't using "file:///" or ExpandPath() on the local image src reference, which was causing a timeout. Once I resolved those issues the .cfm stopped timing out.

Thanks for your response, and for this amazing resource! I was at your CFSummit troubleshooting session and you alluded to this CFDocument performance issue (which we've been fighting with for some time).

Regards,
Jason
# Posted By Jason | 11/13/13 8:39 AM
@Jason, thanks for the update and the kind regards.

So about what you observe, I'll note that I don't think you should have to use the file:// reference. You should be able to just use a relative path reference, as far as I know (and so I would not think expandpath should be needed, either, as that converts the path to an absolute one).

So I'm curious: are you saying that if you have html within a cfdocument (using localurl) where some file reference uses only a relative path, things hangup? but if you change to file:// or use an absolute reference it works? That would surprise me, but I'll admit that the whole localurl feature is not really well-documented.

If you may have some simple example that can demonstrate the problem, perhaps I or others can run it on our own machines. It may be that it's not the code itself but your machine/configuration (incuding hotfix levels, etc.) which may be at issue. Your call. :-)
Working through this a bit further...

In my large cfdocument, I have a call to a style sheet. I just changed to a CF template, wrapped it in cfoutput and cfinclude'd it. However, in the style sheet, I have a call to a background image. Can't quite get that to work. No error, but no background image.

I currently have as a body attribute:
   background-image:url("file://#ExpandPath('draft.jpg')#") repeat;

Where the file is in the same folder as the stylesheet.cfm and the calling display file (for simplicity).

Just can't get it to work...
# Posted By Randi | 1/14/14 6:27 PM
@Randi, I see you using the file:// protocal. What has prompted that? Have you tried removing it? And do you realize that expandpath creates an absolute URL? What if you just created a web-root relative URL? And are you or are you not the localurl? Some combination of these things should work, unless you have a mistaken path or perhaps a web server configuration problem.

That said, this blog entry is about using the localurl attribute of cfdocument. it really isn't a place to raise questions about (and problems with) using CFDOCUMENT in general, so I really think you want to raise this question instead on one of the Adobe CF forums. To find them, and other resources for finding help, see my cf411.com resource. Hope that helps.
Copyright ©2024 Charlie Arehart
Carehart Logo
BlogCFC was created by Raymond Camden. This blog is running version 5.005.
(Want to validate the html in this page?)

Managed Hosting Services provided by
Managed Dedicated Hosting