Due to serialization, most of the time we make at least two copies in the process of sending a message (this is necessary in general, because we cannot synchronize the sender and receiver).
1. (zero-copy) If the sender and receiver are in the same isolate (e.g. two frames in the same page), then we can take a zero-copy path by just passing a handle to the v8 string. Unlike objects, strings are not attached to a particular context. This makes the cost constant in the length of the string.
2. (one-copy) If the sender and receiver are in the same process, then we can copy the string into an isolated copy WTF::String that can be sent to another thread, and then create an external v8 string from that (without a further copy).
These both seem fairly straightforward if MessageEvent is refactored slightly (it already supports a variety of kinds of objects as data, not just SerializedScriptValue).
These don't help more complicated objects, though, so cases like {someKey:"hugestringhere"} aren't improved. It would be possible to generalize this to work inside objects (and avoid a performance cliff), by giving v8::ValueSerializer an ability to delegate large strings to its delegate (and then hanging these off the SerializedScriptValue, like transferables).
I already have the quick and easy (1) working (and it's fast -- probably slightly faster yet because we don't have to set up a serializer at all), but it's a little weird to end up with a state such that strings are fast, but only if you _just_ send a string.
Comment 1 by jbroman@chromium.org
, Mar 22 2017