For most of plain text messages we have two FETCH commands now:
C: FH12 UID FETCH 4790 (UID RFC822.SIZE FLAGS INTERNALDATE BODYSTRUCTURE BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY)]) [08-Jan-2009 15:21:29 +0100]: C: ftch FETCH 640 (BODY.PEEK[1])
We can prefetch a small part of message body (first part) using BODY.PEEK[1]<0.4096> in first FETCH. Then we should check if message is realy a plain text and if body size (from BODYSTRUCTURE) is not bigger than 4096 bytes. If so we can skip the second FETCH.
A.L.E.C wrote:
C: FH12 UID FETCH 4790 (UID RFC822.SIZE FLAGS INTERNALDATE BODYSTRUCTURE BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY)]) [08-Jan-2009 15:21:29 +0100]: C: ftch FETCH 640 (BODY.PEEK[1])
And another idea after reading IMAP's RFC. For unseen messages we're using STORE command which tooks some time (ca. the same as FETCH). We can use BODY[...] instead of BODY.PEEK[...] to set \Seen flag implicitly by server and skip STORE call. I'm not sure if this is true for all IMAP implementations.