Today, Andy reported a similar issue but this time it was for jpeg images. In both the cases, performance hit is huge and it does not happen with all the images.
I spent a significant amount of time debugging it today and it turns out that the reason for both the issues are same - there is something special about these images and that is colorspace. All these images actually had a different colorspace than what java imaging uses. Because of this, when we need the pixel values of image to print it on pdf (by calling BufferedImage.getRGB()), it tries to convert this colorspace to RGB colorspace and that is very very costly. That is where the entire time goes. So how do you fix it? I opened all the images in an image editor and saved it again. This time it got saved in standard RGB colorspace and the time taken to create the pdf got reduced from 110 sec to 1.5 seconds. That is huge!!! Isn't it? But can you control all the images over the web? NO.. right? Read on.. there is more to this story.
A little bit of looking up on web pointed me to this Sun bug which is the exact same bug which we were hitting. Thankfully it got fixed in mustang i.e JDK1.6 which ColdFusion8 uses by default. But hey wait a second.. Didn't Andy say that he is seeing it on ColdFusion 8? why do we still see this happening when it is fixed in JDK1.6? It appears that this bug was fixed only in core JDK api but not in JAI (Java advanced imaging) codecLib that ColdFusion 8 uses. So what do we do now? You can do either of these two
- Remove clibwrapper_jiio.jar from "lib" folder.
- Or, set this system property to the JVM. -Dcom.sun.media.imageio.disableCodecLib=true . You can set this in [cf-install_dir]/runtime/bin/jvm.config if you are using standalone coldfusion server.
You should keep in mind that codecLib libraries are native libraries which are meant to increase the java imaging performance. So disabling it might degrade the performance of CFImage somewhere. Also keep in mind that removing this jar or disabling codecLib will not result into any loss of functionality - it just means that all image operations will be pure java.
There is another related Sun's bug which I thought might be useful to you. Image loading might get very slow if the server is running in debug mode. Your server is running in debug mode if you see something like this in your jvm.config or VM startup option.
This bug got introduced in JDK1.6 and does not exist on 1.5. So make sure that you are not running the server in debug mode.-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
To summarise, you can do following to increase the performance of image loading in cfdocument.
- If you are on JDK1.5, there is not much you can do. The only option is to change the colorspace of images. I will try to see if we can address this in ColdFusion code.
- If you are on JDK1.6,
- Disable codecLib as mentioned above.
- Disable debug mode by removing the complete debug string mentioned above
- In addition to this, you might want to use 'localurl' attribute for cfdocument tag. See this for more details.