This is not really a question because I just solved the problem, but I think the nature of the problem is common for many iPhone devs and the solution wasn't really plainly obvious so I wanted to share my experience. To keep with the StackOverflow "question/answer" format, I'm going to put the details into the question and my solution into the answer.
Details:
I had a tableview full of cells with two labels and a custom toggle switch control I put together from scratch. If I hid the toggle control, the tableview scrolled like a champ. However, with the toggle control shown, scrolling was painfully choppy / slow on the iPhone 3G. My tableview cells have no transparent components (other than the mask for the layer) and I'm reusing cells.
The custom toggle control extends UIButton and it's layer has two components - a UIImageView that contains the sliding "switch" part of the toggle and an elongated ellipse that is used as the mask, with a background drawn behind the layer in -drawRect:
.
How did I fix it? Answer coming shortly...
I found out that the source of the slowness / choppiness was coming from having to re-composite the Layer with the mask sublayer on scrolling. I guess it was having to re-draw the toggle switch every time the screen was re-drawn.
My solution is to hide the toggle switch layer/mask unless it's changing state. When it's sitting fully in the on or off positions, I hide the toggle switch layer and replaced it with an image of the toggle switch. When the user touches the toggle, the dummy image hides, the actual toggleswitch component shows and does the animation to the opposite state. When the animation finishes, I hide the toggle switch component and show the dummy image, making sure to change the image to the current state. This improved scrolling performance SIGNIFICANTLY...I dare say that it's almost as good as a native default tableview cell.