We want to improve the performance of the CFDocument tag. We are generating 6000 pdf pages using cfdocument by looping through a text file, formatting it and creating it using cfdocument tag. We are on CF 2018 Update 5.
Regardless of how much RAM and CPU we are throwing at CF, we cannot seem to convice CF that that RAM/CPU is eligible for use for this process. Whether the server has 16 GB RAM or 256 GB, the PMT shows that there is no differnce in the perfomance, and the amount of time it takes to finish processing doesn't seem to depend on either RAM or CPU. Should we be looking elsewhere (I/O) to speed this up, or is CFDocument simply the "little engine that could"?
We have been updating JVM heap sizes for minim and maximum and increased MaxMetaSpaceSize. At this time, there are no competing threads on this test server - just the CFDocument process.
Please let us know if there are any other settings or resources or other things to look for to increase the performance and generate the pdf faster. If not, we have found an alternative solution, but would prefer to learn more as to whether CFDocument processing can be improved. Thanks in advance.
The sample code below simply writes "hello world" to a pdf. With 16GB RAM and 6 processors, it's taking 30 seconds to write 100 pages to a pdf document. We are looking for a solution to drop this down to a fraction of the time.
We quit using CFDocument back in CF8. Occasionally we'll compare the CFDocument output against WKHTMLTOPDF and we're still very glad that we're using WKHTMLTOPDF. (I believe CFDocument uses outdated libraries and hasn't been updated in a very long time.) WKHTMLTOPDF generates PDFs faster, requires less RAM, generates smaller PDF files and is compatible with CSS3/HTML5. We've also got absolute-positioned scaled SVG images to work, whereas we weren't able to reliably genereate 1px borders using CFDocument. We can even use FontAwesome icons when generating our report. Using WKHTMLTOPDF means that we can easily perform the HTML-to-PDF conversion in the background or separate server without using a single-threaded, long-timout CFThread. (We use ajax or EventSource to determine completion status.)
I replied, but my post regarding how we generate really good PDFs using ColdFusion has been marked as spam by some unknown administrator.
I'd love to hear your response - you can ping me at andy.peterson at illinoiscomptroller.gov
You're not the only one. I've had several posts marked as SPAM (pretty sure by a script) and I had to reach out to Nancy O'Shea to get it undone.
Seriously.. it's no wonder participation has dropped to almost zero. This sucks more than Jive ever did.
^ _ ^
Where do devs go nowadays? Slack channel?
I copied the initial post & my deleted reply, posted it on my own Tumblr blog and tweeted about it. I was interested in using the forum to post some upcoming articles, but now I'm not sure how I feel since being moderated & "marked as spam" by the platform. I used Slack about a year or so ago, but it's private, conversations are immediate and not very searchable IMHO. I now primarily search & view blog posts, the "ColdFusion Programmers" Facebook group, GitHub and StackOverflow for ColdFusion-related content.
30 seconds is indeed the time ColdFusion requires, I'm afraid.
To see this, use the following code, which saves the PDF as a file.
<cfset startTime=getTickCount()> <cfdocument format="PDF" pagetype="letter" marginbottom="0" margintop="0.21" marginleft="0.21" marginright="0.26" orientation="portrait" fontembed="true" scale="100" backgroundvisible="true" overwrite="true" bookmark="false" localurl="true" filename="myTestDoc.pdf"> <cfloop from="1" to="100" index="i"> <cfdocumentsection> Hello World! </cfdocumentsection> </cfloop> </cfdocument> Processing time (to nearest second): <cfoutput>#int((getTickCount()-startTime)/1000 + 0.5)# s</cfoutput> <cfabort >
Suggestion: try wkhtmlToPDF
For example, I used it as follows.
1) I downloaded the 64Bit Windows version and installed it on my test server.
2) The files testFile.cfm and htmlToPdf.cfm are in the same directory, namely, wwwroot/workspace/CF_Project/wkhtmlToPdf/. The style "page-break-before: always;" generates a new page on each pass of the loop.
3) I then ran htmlToPdf.cfm to generate and save the 100 page test PDF.
4) The processing time was 1 second. 🙂
<cfloop from="1" to="100" index="i"> <div style="page-break-before: always;"> Hello World </div> </cfloop>
<cfset startTime=getTickCount()> <!--- Set up wkhtmltopdf's header and footer options ---> <cfset wkHTMLToPDFHeader = '--header-spacing 2 --header-left "Header_left_text" --header-right "Header_right_text" --header-font-size 9 --header-line --header-font-name opensans_regular'> <cfset wkHTMLToPDFFooter = '--footer-left "footer_left_text" --footer-right "footer_right_text" --footer-font-size 9 --footer-line --footer-font-name opensans_regular'> <!--- Set up all wkhtmltopdf's options ---> <!--- Use -B or --margin-bottom -R or --margin-right -T or --margin-top -L or --margin-left -s or --page-size ---> <cfset wkHTMLToPDFOptions = "-B 25.4mm -R 25.4mm -T 25.4mm -L 25.4mm -s Letter --disable-smart-shrinking --zoom 0.9 " & wkHTMLToPDFHeader & " " & wkHTMLToPDFFooter> <cfexecute name="C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe" arguments="#wkHTMLToPDFOptions# http://localhost:8500/workspace/CF_Project/wkhtmlToPdf/testFile.cfm #expandpath('testDoc.pdf')#" timeout="20"> </cfexecute> Processing time (to nearest second): <cfoutput>#int((getTickCount()-startTime)/1000 + 0.5)#</cfoutput> <cfabort >
I posted a similar response earlier this morning and my post was promptly flagged as spam and deleted. I ended up posting my response on my personal blog so that it wouldn't get deleted and privately contacting Andy. (It's possible that the new forum doesn't like outbound links to tumblr blogs.)
I don't see anyone here proposing the CFHTMLTOPDF tag that was added in CF11--and which ends up using WKHTMLTTOPDF under the covers (running in the separate CF "addon" service, assuming one installs that with CF, or can install later.)
I realize someone may well pipe up with some scenario in which cfhtmltopdf did not work for them, while talking directly to wkhtmltopdf did. One thing to note is that the library surely has changed since CF11, and may have within updates to CF 11, 2016, or 2018, so sometimes the past experiences people report no longer apply.
Anyway, I just wanted to throw this out as something to consider. It's not at all to knock Jamo's helpful suggestion and code offered. I'm sure it will help many. Just saying that for some folks, switching from cfdocument to cfhtmltopdf may suffice to solve past problems with cfdocument (and there were many).
Are you seriously saying, Charlie, that using WKHTMLTTOPDF and cfhtmltopdf are the same code???
You may have just saved me a lot of time trying it as an alternative.
htmltopdf is broken in cf2018.
So WKHTMLTTOPDF is also?
> using WKHTMLTTOPDF and cfhtmltopdf are the same code???
No, they are not. The keyword is "using".
In ColdFusion 2018, you may use the operator "new java()" to instantiate Java objects. But it doesn't mean that instantiating an object in Java will yield the same code as instantiating an object in ColdFusion.