Ask a Jedi: CFIMAGE performance concerns

This post is more than 2 years old.

James asks:

I'm hoping you might be able to give me some insight into performance considerations when using CF8 image manipulation functions. Basically, I have an image upload function where the user can add 5 images into a list and then click a single upload button to upload them. When they click upload, multiple asyncronous Ajax requests are fired which upload the images to the server (using the Ajax upload code you blogged about recently).

Upon upload, the file upload service then resizes the images to a thumbnail and large size. This is performed via the CF8 image tag.

My concern is that when these 5 images are all being uploaded and processed at the same time my development server CPU jumps to 100%. Obviously image processing is going to put some strain on the system but I'm a little worried that when the site goes into production it could be an issue.

Do you think it's wise to upload and process all 5 images simultaneously or should I do them one at a time. Any idea if CFTHREAD would be useful here.

There are a couple things going on here. So let me try to break this out a bit.
  • The first thing I want to address is the 100% CPU issue. I do not know this for a fact, but from what I remember hearing from smarter folks, is that this is normal behavior, and simply reflects ColdFusion using all the power available because, well, it's available. I would think you would want ColdFusion (or any other process needing resources) to be able to use the full resources of your box. But again - I'm definitely not sure on this.
  • I definitely agree with you on image processing being intensive. I've seen odd delays in the past with image resize. Typically though this was always with very large images, and you can kind of expect some delays in that area. ColdFusion actually provides 17 different algorithms for resizing images, so you have a lot of choices there for tweaking quality and performance. By default ColdFusion uses the highest quality resize.
  • You mentioned CFTHREAD. If you were uploading all 5 at the same time, I'd say sure, do it. But if you are doing an Ajax based upload, you may be doing them all at the same time. I don't know exactly how you are sending the data so you have to tell me, but if you are sending all 5 with one POST operation, CFTHREAD could indeed be useful here to run all the requests at once. You just want to be careful. If you have 250 users all uploaded 5 images at once, you are going to quickly run out of threads you can use. Sorry - I just reread your question and you said you are definitely doing the uploads one at a time, so in that case, I don't think CFTHREAD will help - you already have 5 separate requests.
  • And lastly, I hope you are keeping those resized images. I assume you do the upload, resize and store. If not - you definitely want to do that. With resize being (possibly) a bit slow, you want to ensure you do it once and save it to the file system.
Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by James Allen posted on 3/28/2008 at 11:08 PM

Thanks for answering my question Ray - much appreciated.

I didn't realise that CFIMAGE offered many different algorithms for resize. I'll have to check them out. No point processing in cpu intensive HQ mode if a lower mode would suffice (my process images aren't going to be huge I don't think).

Yeah in terms of the uploads they are being done asyncronously via hidden IFrames for each of the 5 upload input boxes.

I was just alittle concerned that by allowing 5 uploads to happen at the same time per user it might lead to huge server load as more users begin using the site.

I suppose it might have to be a case of testing when the site goes live and then maybe refactoring so that the images are uploaded in a queue if there are performance / load issues.

When each image is uploaded I resize to two difference sizes and store in a folder relating to the question being posted (the user can upload images to support a question). I then delete the source image.
Definetly not a good idea to do this dynamically.. I shudder to think how a site doing that would perform..

Once we go live, if we do have problems I'll post a comment on this post to let you know.

Comment 2 by Raul Riera posted on 3/28/2008 at 11:28 PM

@James

I would recommend you use the MultiFileUpload Flex component, because it uploads the files on at a time and beign Flex you have a lot of control with the use of Events (Im an AJAX newbie, I assume ajax has them as well)

http://www.adobe.com/devnet...

I modifed this component so it shows me the images after upload using a Cover Flow effect, I can share that with you if you want to, but I cant promise you the code would be pretty hehe.

Comment 3 by David Buhler posted on 3/28/2008 at 11:31 PM

Your processing time and CPU intensity will be less if you use a lower quality setting. The default quality is too good, and I'd highly suggest going lower, down to medium quality.

Also, if you're resizing images, you may want to consider resizing images from the last, larger image that was just manipulated. The quality suffers but the speed improves and typically, your users don't really care.

Imagemajik is even worse than CF8 for the CPU intensity.

If your site is successful, you can always defer image processing to a dedicated box.

Comment 4 by Patrick posted on 3/29/2008 at 1:48 AM

I also had some trouble processing images. Resizing 10 images slowed my mac down till the timeout for cfoutput. The reason was, that the images where processed in photoshop and saved with an ICC-Profile (ECI-RGB). I converted the images, to have no ICC-Profile asigned and the processing worked fast and fine!

Greets from germany

Patrick

Comment 5 by James Allen posted on 3/29/2008 at 4:50 AM

Some great suggestions - thanks guys.

I hadn't considered a Flex approach to be honest, although I'm finding the multi-upload method I've built using an Ajax upload JQuery extension pretty cool. My only concern is the multiple uploads of 5 images, though I could change that to a queue system down the line if necessary.

The idea of using the last largest image to resize is pretty clever. Definetely worth some testing as I can see that helping greatly with CPU load when handling lots of images.

Comment 6 by Michael Evangelista posted on 4/3/2008 at 6:53 AM

@James Allen:

>> although I'm finding the multi-upload method I've built using an Ajax upload JQuery extension pretty cool.

Which jQuery uploader are you using?
I need to do something very similar, very soon!

Comment 7 by Jonas posted on 4/3/2008 at 12:42 PM

Same here - it's on my list of medium importance list to improve our admin site, so any sharing of your multi-file ajax upload solution would be awesome. :-)
Very interesting thread so far, thanks guys - always a learning experience to stop by here.

Comment 8 by James Allen posted on 4/3/2008 at 2:34 PM

As some of you are interested to hear how I did the multi-file upload I thought I'd post on here about it.

Firstly I used the code that Ray used in his example Ajax Upload post here:

http://www.coldfusionjedi.c...

This works nicely and it's pretty easy to modify, which I did to support the multiple uploads.

Now, the actual interface I built to do this was an absolute, grade a pain in the ass! The reason being is that I have one single upload box followed by a list of 5 images which is dynamically populated as the user browses for and selects the images for upload.

Now, obviously to upload 5 images in the browser you *need* 5 individual upload boxes - no getting around this. Therefore, I had to build a complex and hair pullingly frustrating upload box switcher which would hide the current upload box and switch it with the next one in the list each time the user finished selecting their image (via an onchange event on the upload control). This was made even harder due to having to support the ability to remove images from the list.. It's painful just thinking back to that. LOL.

Anyway, that was the hardest part and you may not want to do things this way. You could just have 5 upload boxes on the page which would make it alot easier.

On clicking the 'Upload' button I call a function that loops over the 5 upload boxes and calls the Ajax upload function (similar to the example one Ray used but modified to accept the field number). This then takes care of uploading the images one by one, but as this is Ajax they are uploaded asyncronously. I also added a list position parameter to the upload function so that I can turn the upload progress animation on and off against each upload box.

The upload controller I use is a simple CFM template which instantiates my FileUploadService and calls some methods to receive the file being uploaded and then automatically resizes them to the relevant target sizes.

The script then returns the filename of the thumbnail (to sllow a dynamic preview).

That's it in a nutshell. Crazy single upload box switching side, it's not too bad to modify the example Ray gave to support multiple uploads. I think I had a proof of concept knocked up quite quickly, so I recommend you try it out.

I may get around to blogging about this in more detail at some point and will add a comment if I do.

Comment 9 by Felix Kreitner posted on 4/16/2008 at 11:32 PM

Hi,
i tried to resize a 5MB JPEG with cfimage and it tooks 24sek. on my developer engine.
After that i tried cfx_imagecr3 from www.efflare.com and it tooks 4sek.
I was suprised how much faster cfx_imagecr can resize images.

Comment 10 by Raymond Camden posted on 4/16/2008 at 11:42 PM

Did you try multiple types of resizing algorithms Felix?

Comment 11 by Felix Kreitner posted on 4/16/2008 at 11:55 PM

Hi Raymond,
no i tried
<cfimage action="resize" destination="thumb_sample.jpg" height="100" isbase64="false" overwrite="false" source="sample.jpg" width="" />

But i will play a little bit with cfimage to get a comparison.
I will let you know.

Comment 12 by Raymond Camden posted on 4/16/2008 at 11:57 PM

If you read the blog entry above (I know I skim things myself) you will notice that CF has 17 kinds of ways to resize.

Comment 13 by Felix Kreitner posted on 4/17/2008 at 12:19 AM

Hi,
yes i read it, but did you think this will save 20sek.?
I think it will not, but it will be interesting to know which is the fastest solution an setting for cfimage in CF.

Comment 14 by Raymond Camden posted on 4/17/2008 at 12:23 AM

Errr yes. From the text above:

"ColdFusion actually provides 17 different algorithms for resizing images, so you have a lot of choices there for tweaking quality and performance. By default ColdFusion uses the highest quality resize."

ColdFusion goes for quality by default. That would definitely impact performance.

I'm not saying it will equal cfx_imagecr, but....

Comment 15 by Felix Kreitner posted on 4/17/2008 at 1:57 AM

Hi,

i played a little bit with ImageResize and cfimage. You are right the needed time is a little be better than before. The quality is not the same as cfx_imagecr, but OK.
Here is my demo i played with
http://www.jivespace.de/cfi...
It tooks 1 min. to open :-)

Comment 16 by Andy Urban posted on 4/4/2011 at 1:20 AM

Just for people still checking this, I did what Patrick instructed above by removing the ICC profiles and my images resized very quickly. As a rule of thumb use "Save for Web" from Photoshop with the images you are going to push to the webpage and the profiles will be removed.

Comment 17 by James Moberg posted on 7/29/2011 at 3:45 AM

I finally had to search for a CFImage alternative. The imageScaleToFit() function to rescale images was killing the server.

I checked out Efflare's cfx_imagecr3, but it failed with an "Expired, please buy a license" warning the first time it was installed & run. (LAME)

I tried CFX_OpenImage and discovered that it rescales images about 75-90% faster and creates images that are about 64-72% smaller than CFImage. Even getting the image dimensions is about 96% faster than CFImage.
http://www.kolumbus.fi/~kr0...
(NOTE: Only available for Win32)

Comment 18 by Dave Morris posted on 11/24/2011 at 6:02 PM

Troubling, since I recently started a massive conversion process to move everything I had written using Jukka Manner's 32-bit CFX_Image tag over to the native CFImage so I could run on a 64-bit server. Now my servers are locking up, running out of memory all the time, and the time to process an image is an order of magnitude longer than with Jukka's custom tag. I've had to implement a 5 minute watchdog timer that automatically reboots CF server when it has been more than 5 minutes since CF last responded. This is ridiculous.

Comment 19 by Raymond Camden posted on 11/24/2011 at 8:32 PM

Are you running 901+latest hot fixes?

Comment 20 by Dave Morris posted on 11/24/2011 at 8:56 PM

I just bought and installed 9,0,0,251028 and didn't see anything in the hotfix bug list that addressed anything related to CFImage. Did I miss something?

Comment 21 by Raymond Camden posted on 11/24/2011 at 9:05 PM

Don't know - but it is normally recommended to use the latest/greatest. There is 901+2 Cumulative Hot Fixes you should pick up.

Comment 22 by Dave Morris posted on 11/26/2011 at 12:19 AM

OK, I installed 9.0.1 and also read up on the complex JVM memory allocation and garbage collection. I set my heap size to 2GB and we'll see if that helps any. One good thing about installing the 9.0.1 upgrade is that all of a sudden my Performance Monitor started working again and had all of the various parameters available, which were completely absent before.