Intent to Ship: Changes to structured clone implementation

145 views
Skip to first unread message

Jeremy Roman

unread,
Nov 22, 2016, 1:55:14 PM11/22/16
to blink-dev, Elliott Sprehn, Kentaro Hara

Contact emails

jbr...@chromium.org


Spec

https://html.spec.whatwg.org/multipage/infrastructure.html#safe-passing-of-structured-data


Summary

Structured clone is the process described in the HTML specification for cloning JavaScript objects from one realm to another, and is used by such features as postMessage, IndexedDB and CustomEvent.


This intent covers the switch to a new implementation of this feature, largely in v8 itself (v8::ValueSerializer), with a primary aim of improving performance and a secondary aim of fixing some correctness issues.


The associated bug is https://crbug.com/148757. Performance improvements are most visible for large JSON-like objects (i.e., consisting of a graph of plain JavaScript objects, arrays and primitives). The bottom line is 3-4x total round-trip speedup for such objects in a benchmark, with a particular win on the serialization side (on the order of 5-10x).


As a real-world example, the time spent in structured clone code when activating the Gmail feedback feature on my (rather powerful) Linux workstation is reduced from approximately 61 ms to approximately 14 ms.


Link to “Intent to Implement” blink-dev discussion

n/a


I did not expect this to lead to any significant web-exposed changes, so there is no Intent to Implement discussion. (esprehn@ and haraken@ requested an Intent to Ship during review.)


Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes.


Demo link

n/a


Debuggability

No change to debuggability.


Interoperability and Compatibility Risk

Low; behavior changes are in edge cases and this feature is already widely-supported by browser vendors.


Web-visible changes:

- The call stack is used for recursion over the data structure, as with JSON.stringify/parse. This means that the supported recursion depth is somewhat lower than before, but similar to JSON.stringify, which we haven't had issues with in the past. Previously we always failed at a fixed depth of 20,000. Cycles continue to be supported without issue. It is possible to switch to an explicit stack on the heap, but this makes the code more complicated and has a performance impact.

- When the depth limit is reached, we used to throw a DataCloneError DOMException. With this change, we will use V8's default stack overflow logic, which throws a stack overflow RangeError. This is consistent with what we do in JSON.stringify. Both Safari and Edge currently throw the same type of exception that they do for script overflowing the stack as well (RangeError for Safari, Error for Edge). Firefox allows arbitrarily deep objects (except possibly if you fill up the heap; I haven't managed to do that).

- Some "trivial" correctness fixes (e.g. non-enumerable properties of arrays should not be serialized).


I also expect that after shipping, some additional minor (but web-visible) changes will be shipped, like properly preserving distinction between non-existent properties and existent properties with the value undefined.


OWP launch tracking bug

n/a


Entry on the feature dashboard

No new or removed feature. Web-visible changes are performance, and the small behavior differences discussed above.

Kentaro Hara

unread,
Nov 22, 2016, 6:09:49 PM11/22/16
to Jeremy Roman, blink-dev, Elliott Sprehn
non-owner LGTM

Behavioral changes are only in super edge cases, so the compatibility risk would be very low.


On Wed, Nov 23, 2016 at 3:55 AM, Jeremy Roman <jbr...@chromium.org> wrote:

Contact emails

jbr...@chromium.org


Spec

https://html.spec.whatwg.org/multipage/infrastructure.html#safe-passing-of-structured-data


Summary

Structured clone is the process described in the HTML specification for cloning JavaScript objects from one realm to another, and is used by such features as postMessage, IndexedDB and CustomEvent.


This intent covers the switch to a new implementation of this feature, largely in v8 itself (v8::ValueSerializer), with a primary aim of improving performance and a secondary aim of fixing some correctness issues.


The associated bug is https://crbug.com/148757. Performance improvements are most visible for large JSON-like objects (i.e., consisting of a graph of plain JavaScript objects, arrays and primitives). The bottom line is 3-4x total round-trip speedup for such objects in a benchmark, with a particular win on the serialization side (on the order of 5-10x).


As a real-world example, the time spent in structured clone code when activating the Gmail feedback feature on my (rather powerful) Linux workstation is reduced from approximately 61 ms to approximately 14 ms.


Yay! This fixes the long-standing problem that postMessage() on Chrome is extremely slower than other browsers :)



Link to “Intent to Implement” blink-dev discussion

n/a


I did not expect this to lead to any significant web-exposed changes, so there is no Intent to Implement discussion. (esprehn@ and haraken@ requested an Intent to Ship during review.)


Is this feature supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

Yes.


Demo link

n/a


Debuggability

No change to debuggability.


Interoperability and Compatibility Risk

Low; behavior changes are in edge cases and this feature is already widely-supported by browser vendors.


Web-visible changes:

- The call stack is used for recursion over the data structure, as with JSON.stringify/parse. This means that the supported recursion depth is somewhat lower than before, but similar to JSON.stringify, which we haven't had issues with in the past. Previously we always failed at a fixed depth of 20,000. Cycles continue to be supported without issue. It is possible to switch to an explicit stack on the heap, but this makes the code more complicated and has a performance impact.

- When the depth limit is reached, we used to throw a DataCloneError DOMException. With this change, we will use V8's default stack overflow logic, which throws a stack overflow RangeError. This is consistent with what we do in JSON.stringify. Both Safari and Edge currently throw the same type of exception that they do for script overflowing the stack as well (RangeError for Safari, Error for Edge). Firefox allows arbitrarily deep objects (except possibly if you fill up the heap; I haven't managed to do that).

- Some "trivial" correctness fixes (e.g. non-enumerable properties of arrays should not be serialized).


I also expect that after shipping, some additional minor (but web-visible) changes will be shipped, like properly preserving distinction between non-existent properties and existent properties with the value undefined.


OWP launch tracking bug

n/a


Entry on the feature dashboard

No new or removed feature. Web-visible changes are performance, and the small behavior differences discussed above.




--
Kentaro Hara, Tokyo, Japan

Chris Harrelson

unread,
Nov 23, 2016, 1:17:27 PM11/23/16
to Kentaro Hara, Jeremy Roman, blink-dev, Elliott Sprehn
LGTM1

Awesome work! There are a lot of web developers who will appreciate these improvements.

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.

Rick Byers

unread,
Nov 26, 2016, 10:18:30 AM11/26/16
to Chris Harrelson, Kentaro Hara, Jeremy Roman, blink-dev, Elliott Sprehn
LGTM2

This is definitely awesome!  Thanks for being careful about the compat impact.  If you come across real-world sites that are impacted by these changes ping this thread with pointers to details, but I agree that the risk is very low.

Philip Jägenstedt

unread,
Nov 28, 2016, 8:28:47 AM11/28/16
to Rick Byers, Chris Harrelson, Kentaro Hara, Jeremy Roman, blink-dev, Elliott Sprehn
LGTM3

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.


Reply all
Reply to author
Forward
0 new messages