In reality, the transport you use for your data doesn't make much of a difference. First of, you (hopefully) have a layer of abstraction between your code and XMLHttpRequest that takes whatever data structure you throw at it and serializes it into XML or JSON. If all goes well, you'll never even see the data in its serialized form and so whether its particularly easy to read or complete gibberish shouldn't matter. Secondly, the real problem with web services is not the amount of data you transfer back and forth but the fact that in a worst case scenario, you'll have to re-establish a TCP-connection for every request you make - something not even JSON can prevent (to some degree, the keep-alive mechanism can).
The gritty details
I come from a background of traditional (read non-web) programming and so for me the problem of serializing a variable into a stream of bytes seemed trivial. If you've programmed in a language like C or C++ before, you'll probably know that these languages support the concept of pointers. Now pointers aren't particularly popular anymore, but they allow you to do something that modern programming languages aren't so good at: treat a variable as something that it's not. Let's say you have a 64 bit floating point variable and you want to save it to a file or send it over a socket connection. In order to turn the variable into a stream of bytes, all you have to do is create a byte-pointer and have it point at the floating point variable. Then you can access the individual bytes of the floating point variable and do whatever you want with them.
However, when I looked at the size of the messages I was sending, I quickly noticed that I had yet another problem. The XMLHttpRquest object's send method automatically applies utf-8 encoding to anything it sends. This may be fine for text messages, but what I was sending wasn't exactly text. Now utf-8 encoding will encode characters with a numeric represtation that is larger than 128 with anything between two and four bytes. Meaning that when I was thinking I had sent a single byte, I might have actually sent four. Now this problem I could not yet circumvent and while sending and receiving works just fine, the messages are a lot bigger than they have to be. Typically they're about the same size as a JSON message but sometimes they're also bigger.
The bottom line
So now I have a binary web service protocol and an implementation that sort of works but that suffers from a problem that I cannot fix and that makes the whole thing a lot less useful. I guess the most sensible thing to do now is to come up with a catchy name for it and get it out there. How about BISON (binary interchange standard and object notation)? It sounds remotely like JSON and is very Web 2.0.