I'd be surprised if you'd really need to optimize that often.
If you do need to optimize table T while minimizing table lock time, you could
1. Create a new table N
2. copy all data from T to N
3. lock T
4. copy all data from T to N where T.id > MAX N.id
5. remove T
6. rename N to T.
That should minimize the time when T is locked.
Also, if deletions is a problem, you don't really need to continously delete from online. Keep a status field, such as a TINYINT UNSIGNED, which can be 0 for offline or 1 for online. When someone goes online, you INSERT INTO online ... ON DUPLICATE KEY UPDATE set status=1.
This way, you always insert into online when someone goes online. If the user allready exist in online, make sure status is set to 1.
But, for purposes of showing an online list, the people who have status offline have the same effect as if they were deleted (fragmentation). What you may save is some indexing work, except for index on online.status.
If you don't use indexes, there would be no gain with this approach, and this leads me to believe your problem is proper indexing rather than a dire need for optimize table. Sure, indexes take time to update, making each insert/update/delete slower while speeding up selects. But this is where I'd start looking.
Another approach is to forgo the DB completely, e.g. by using memcached.