Oui et non pour l’asynchrone. Pygame ne sert que pour l’affichage, donc si tu veux de l’asynchrone, faudrait le faire toi même avec des async def par exemple (par contre faudra installer pygame via la source, car c’est une feature de python 3.5 si je dis pas de bêtise, or pygame a pas dû etre packagé en .msi/.exe pour py 3.5)
Ensuite, c’est totalement faisable d’avoir des anims qui ne bouffent pas les perfs, faut juste bien jouer avec le dt que tu passes à ta fonction d’update
Mettre à jour une seule partie de l’écran est totalement inutile. Car cela veut dire savoir quelles parties mettre à jour via pygame.display.update(..) à chaque instant. Pygame peut effectivement fonctionner en BUFFERED, mais aussi en simple superposition (mais c’est pas utile en soit de vouloir optimiser en actualiser que un rectangle de taille (x,y) avec x < screen width et y < screen height, parce que tu devras sûrement flip plusieurs coins de ton écran. C’est pas opti en soit, autant tout réactualiser. Ta CG va être contente de seulement modifier quelques milliers de triangles en un seul coup plutot que des paquets de ~200-500 plusieurs fois par frame)
Les images hors de l’écran, c’est pas pygame qui gère ça normalement, c’est directement la SDL qui est en dessous. Si par "images qui n’apparaissent pas à l’écran" tu entends les images que l’on a affiché en dehors de l’écran, je crois bien que la SDL les supprime. A noter que tout de meme afficher quelque chose, dans ou hors de l’écran consommera du temps processeur, donc faut bien gérér ton affichage. Mais si par "images qui n’apparaissent pas à l’écran" tu veux dire des images que l’on a chargé mais que l’on ne blit pas sur l’écran, Pygame ne fait rien dessus, il n’a pas la main tout simplement ! C’est python et son garbage collector qui vont faire un tour pour nettoyer si besoin dans ce cas.