Did Bitcoin Core relay blocks sequentially or in parallel to peers before Compact Blocks? As I can see in the Bitcoin code, currently a node sends a block in parallel to all its peers. This makes sense as the block sending time is relatively small compared to the P2P latency. However, my question is how this mechanism worked before BIP152 when a peer had to send 1MB block? In that case, it makes more sense to send the block first to 1 peer before start sending to the others. This is because if we finish sending the block to the first peer, we will utilize his upload bandwidth faster.
It isn't as simple as "sending sequentially" or "sending in parallel".  Each connection is its own socket and the kernel performs packet scheduling. The Bitcoin protocol doesn't have any acknowledgement. When a node sends a message it hands it to the TCP stack which often will just immediately accept the whole message. It's then up to the kernel to send it out.

So in one sense it's not even really possible to send it out 'sequentially' without some kind of massive redesign,  but it also wouldn't be generally desirable to do so: TCP won't send more than the current receive window without getting an acknowledgement. So if you were to wait until TCP has sent all the data to one peer before starting to send the next, you would find yourself waiting around sending nothing part of the time.  You would also increase exposure to tarpit attacks, where a malicious peer intentionally slows down reception in order to delay propagation to everyone else.

So Bitcoin has always gone through the peer list and handed whatever it had to send to each peer, leaving it up to the kernel to schedule the packets.   It has been proposed in the past to hand it to just a few and then wait for them to get it before hitting the rest, but it's not obvious how to robustly prevent tarpits,  and BIP152 largely moots the question.