Best for performance is not using GDI, of course. Neither do I think that GDI is particularly "clean" or "simple".

That aside, the best method is to use BitBlt (or a similar function - you might need masking) to blit sprites to an offscreen buffer and then blit it all to the screen. (Yes, you should do that even in non-frame-based games.)
As for the canvas, that should be a plain window.