- From: Dominic Cooney <dominicc@google.com>
- Date: Fri, 10 Jul 2015 17:11:05 +0900
- To: Anne van Kesteren <annevk@annevk.nl>
- Cc: WebApps WG <public-webapps@w3.org>
- Message-ID: <CAHnmYQ-7UtasEdnb-habMp1GcajeAXz-B6rnShUvAJuMVtXz3Q@mail.gmail.com>
On Thu, Jul 2, 2015 at 4:05 PM, Anne van Kesteren <annevk@annevk.nl> wrote: > In the interest of moving forward I tried to more seriously consider > Dmitry's approach. Based on es-discussion discussion > https://esdiscuss.org/topic/will-any-new-features-be-tied-to-constructors > it seems likely new JavaScript features (such as private state) will > be tied to object creation. This makes the prototype-swizzling design > even less appealing, in my opinion. > Ironically this is a minor reason that Chromium preferred prototype swizzling to "blessing" author-provided constructors: When allocating JavaScript objects to wrap DOM objects ("wrappers"), Chromium adds extra internal space to hold the address of the corresponding C++ object. (V8 calls this "extra internal space" mechanism an "Internal Field" <https://code.google.com/p/chromium/codesearch#chromium/src/v8/include/v8.h&q=v8.h%20include/v&sq=package:chromium&type=cs&l=4660>.) This is efficient (the space is accessed by offset; they don't have names like properties do) and private (this mechanism is ancient--it predates symbols--and is inaccessible to JavaScript because the space has no name and is separate to how properties are stored.) Because Custom Elements did not change how wrappers were allocated, Custom Elements wrappers in Chromium continue to have the necessary extra storage space. Because the Custom Element constructor was controlled by the user agent, we could ensure that it used the same mechanism for allocating wrappers. We can't do that with a user-provided constructor, because V8 has already allocated the object (for "this") by the time the constructor starts to run. Any solution in this space may force Chromium to allocate an additional object with the extra space. This may not be a disaster because, first, generational GC makes allocating lots of short-lived objects relatively cheap; and second, like Objective-C, JavaScript allows constructors to return a different object (and my understanding is that doing this in an ES6 constructor effectively sets "this".) But it is a bit gross. Around summer 2012? 2013? I experimented with using a Symbol-like thing (which V8 calls Hidden Fields) to store the pointer to the C++ object on Custom Element wrappers in Chromium. (So those wrappers had a different shape to most element wrappers.) We felt this design was not feasible because it was slower to access, made the objects larger, and complicated Chromium's DOM bindings which now needed to fall back to checking for this property. I think the most important question here, though, is not constructors or prototype swizzling. It's whether elements created before a definition is available get enlivened with the definition when it is available. I don't like prototype swizzling, but I do like what it lets us do: - Progressive Enhancement. The author can write more things in markup and present them while loading definitions asynchronously. Unlike progressive enhancement by finding and replacing nodes in the tree, prototype swizzling means that the author is free to detach a subtree, do a setTimeout, and reattach it without worrying whether the definition was registered in the interim. - Fewer (no?) complications with parsing and cloning. Prototype swizzling makes it possible to decouple constructing the tree, allocating the wrapper, and running Custom Element initialization. For example, if you have a Custom Element in Chromium that does not have a createdCallback, we don't actually allocate its wrapper until it's touched (like any Element.) But it would not be possible to distinguish whether a user-provided constructor is trivial and needs "this." It's a tradeoff. There are definite disadvantages to the current specification; prototype swizzling is one of them. Not sure if that background is useful... > Meanwhile, I have not made much progress on the cloning question. As > Domenic pointed out, that would also either require > prototype-swizzling or invoking the constructor, there's not really a > third way. I guess for that to work cloneNode() and various editing > operations would have to become resilient against JavaScript executing > in the middle of them, Could you share a list of things that use the cloning algorithm? > something that has caused (is causing?) us a > ton of headaches with mutation events. (Or the alternative, have some > kind of mode switch for the DOM which is similarly a large > undertaking.) > What do you mean by mode switch? > Not sure what to do now :-/ > > > -- > https://annevankesteren.nl/ > >
Received on Friday, 10 July 2015 08:11:33 UTC