Blocking a port is cheap: it can be done by a simple stateless firewall only inspecting up to OSI layer 4. It can also be done with the first packet already, i.e. even at the TCP handshake were no data are transferred yet.
Blocking by the actually spoken application protocol needs to analyze the payload (layer 7). This means that first it needs to collect sufficient payload for analysis, which means it cannot be blocked already at the TCP handshake. Then it needs to have some reliable heuristics to find out based on the first few bytes which kind of protocol this is. There are several protocols where the server sends data first (i.e. SMTP, IMAP, FTP...) in which case the firewall has no choice than to allow a connection to the server in order to get the first data in order to analyze the protocol. Allowing the connection initially already can have some unwanted side effects.
And even with payload it is not always clear which protocol this actually is. There are several protocols which use TLS (i.e. HTTPS, POP3S, IMAPS, ...) and it is often not possible to decide based on the initial TLS ClientHello what kind of protocol will be spoken inside the TLS connection.
To summarize: The best would be to block by port as long as this is reliable since this is cheap and can be done early. Additionally one can analyze the application layer for the ports which are not blocked if the actually spoken protocol is the allowed one.
But why block it this way instead of just blocking the HTTP protocol by its protocol number?
There is no protocol number for HTTP. And "protocol" actually has multiple meanings: there is the "application protocol" at layer 5..7, i.e. HTTP, SMTP, ... . And there is the "transport protocol" at layer 4, i.e. UDP, TCP, ... These transport protocols actually have numbers used in the IP header, i.e. 17 for UDP, 6 for TCP etc. But blocking based on transport protocol makes not much sense since blocking any kind of TCP or UDP will simply block too much.