In general, always integrity first, and only put size data when you need it to be there and don't have it without integrity and better don't have it without encryption either.
I get around the message size problem by using a fixed size packet and have a buffer that gathers pieces and reassembles them for longer messages. Each segment once decrypted, after identifying the receiving private key via a random+hash "cloaked key", which only the holder of the key can identify, plus a private key that was used to generate with the public key the cipher used on the encryption. I use CTR, because I handle the integrity myself with a truncated SHA256 hash prefix on the packet segment format. I don't use signatures in the algorithm - authenticity is handled by the use of session keys which double as identifiers for the sessions, and designate a sats balance to spend on the bandwidth. Generating ECDH shared secrets costs about the same processing as the signatures and the signatures you can recover keys from, like with Bitcoin tx signatures, cost 65 bytes and you have to do the ECDH operation anyway.
The "receiver" key cloak scheme makes it so an attacker cannot see a common receiver key in the message, and in the protocol it signifies what it is associated with, the outer-layer uniform sized packets are an ephemeral key that is changed periodically by volume (it's a one sided operation to tell the other side to use a new public key on their packets), and inside these packets are arbitrary length onion messages, the onions use the same encryption header format the difference is the key is connected to sessions for relaying and accounting of session balances.
I dunno, maybe I haven't thought of a problem with my scheme. I'm most glad to hear of any someone can think of.