With noVNC the protocol decode/encode is done in the browser (modern browsers are plenty fast enough to do this easily), whereas with Guacamole the burden of decode/encode for every client happens on the server where the proxy/client part is running. Even if you need to run websockify to proxy/bridge noVNC, the only thing it is doing is shuttling network traffic and the python implementation of websockify can easily handle lots of simultaneous clients without breaking a sweat.
noVNC was designed with Infrastructure as a Server (IaaS) providers in mind so minimizing server CPU, memory and bandwidth was a goal in the design.
Also, guacamole does use websockets when it is available.