Wednesday, December 19, 2007

Friday, December 14, 2007

Firefox (Adblock plus) blocks even Google adsense

I have been using my new laptop at work (my old one crashed at MAX) for two weeks and its been pretty good. Not because the laptop is something extraordinary, its because I installed the latest versions of all the softwares and plugins I use. And the most pleasant part of it is - it has been completely ads free. I did not notice it earlier but once I landed up on sys-con's site to read some article and I was pleasantly surprised to find no irritating video ad there. For a moment, I thought that may be sys-con has grown up but that was just for a moment :-). The snapshot shows it all.

IE

cfdj_ie_1

Firefox

cfdj_firefox_1

Its actually a firefox plugin adblock plus that does it automatically. The most interesting thing was that it even removed google text ads. Its interesting because we have always seen Google promoting firefox and firefox as a browser closer to Google. So now a firefox plugin that blocks google adsense and in turn hurts Google revenue is certainly not going to go well with Google. It will be interesting to see how Google plays it.

So how exactly does adblock plus block the ads? Gecko engine - the engine underneath Firefox, uses a content policy which decides which content should be loaded and which should not. Adblock defines its own policy which gets added to the browser's policy. It comes with a predefined huge collection of filters and if the url to be loaded matches any of that, it does not let the browser make a request for it. For google adsense, the url contains 'pagead2' which you can see in the adblock preference below.

adp

Its also going to hurt many bloggers as lot of them earn substantially from ads and mainly adsense.  Even my blog page contains adsense but I dont mind adblock plus as I haven't yet earned anything from it anyway. I'm loving it. :-)

Images and CFDocument performance

Sometime back one of our customer reported that using png images in cfdocument makes it very very slow. I could not replicate it with any png image but it did happen with his png image.

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

  1. Remove clibwrapper_jiio.jar from "lib" folder.
  2. 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.

-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
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.

To summarise, you can do following to increase the performance of image loading in cfdocument.
  1. 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.
  2. If you are on JDK1.6,
    • Disable codecLib as mentioned above.
    • Disable debug mode by removing the complete debug string mentioned above
  3. In addition to this, you might want to use 'localurl' attribute for cfdocument tag. See this for more details.

Wednesday, December 12, 2007

Missing text in pdf created by CFDocument

I had heard about people not getting images in the generated pdf but this one was something new and spooky. Yesterday Andy Matthews posted it on cf-talk where he says that for his content, though a pdf containing 15 pages gets created but only the first page has some content and rest of the pages are blank. I ran his code on my machine and sure enough it was happening. All the content including text and image on all the pages except the first page was gone. So what was wrong? I simplified his code and here is a simple example which you can try.

<cfdocument format="pdf">
Text Outside div
<div style="width:300px;overflow:auto;">
This is text inside the div. Will it show up?
</div><br>
</cfdocument>
In the generated pdf you will see only "Text Outside div". Spooky.. isn't it? The reason it happened was because of css style 'overflow:auto'. The rendering engine used by CFDocument underneath does not handle overflow:auto and it simply ignores the content in the div. The weird part is - it considers that content for all rendering calculations including page number and page break calculation.

Something you should watch out for if you use css styles in cfdocument. A workaround for the time being is not to use overflow:auto style. So modifying the above code like this will make it work.

<cfdocument format="pdf">
Text Outside div
<div style="width:300px;">
This is text inside the div. Will it show up?
</div><br>
</cfdocument>