Back in old times canvas drawing wasn't double buffered by default. Mostly because it would have consumed too much system resources and all possible usage cases weren't predictable. It was up to programmer himself to manage back buffer, so optimizing resource usage of his program was also his task, not OS's task. As result, it was always needed to redraw picture on screen, when it was "damaged" somehow. It actually happens not only when you change something by yourself, but also when other window overlaps part of window and when part of your window goes offscreen. OnPaint message is fired every time it happens. And Canvas.ClipRect property allows you to get "damaged" part of canvas to be redrawn.
Please note! Some changes were made to this process since Vista, that implemented "indirect" painting on screen. It was exact moment, when built-in double buffering was implemented to OS itself. You no longer paint on screen itself. You paint on some back buffer, that is managed by window manager, i.e. DWM. Actual drawing is performed via hardware accelerated D3D. I'm not 100% sure, what has changed. In what cases OnPaint is fired and in what cases it no longer does.
And it's up to you to optimize redrawing process. Bitmap is usually used for this purpose. Problem is - you don't know, what size your window will have and resizing bitmap may be slow. Creating one big screen size back buffer - is always the fastest way. But it consumes the most resources. It's not problem now, but it was back in old times.
So, optimal ways to handle OnPaint are:
1) Fast way - you have back buffer bitmap, you draw on, and just need to copy ClipRect part of it to your main window's Canvas. Or just use TImage, that does it automatically.
2) Optimized way - you have list of items, that are identified by their rects. You check, if YourItem.Rect.IntersectsWith(ClipRect) and redraw item, if it does.