Version 1 (modified by 5 years ago) ( diff ) | ,
---|
DOM Bindings, Event Loop & More
by Ryosuke Niwa
- C++ and JS Objects
- C++ objects define behavior
- JS wrappers expose them to JavaScript
- Injected scripts have their own DOM wrapper “world”
- Converting Objects
- toJS(node) to get a JS wrapper
- toWrapped(node) / jsNode.wrapped() to get C++ object
- Cache main world’s wrapper via ScriptWrappable
- When should we use it?
- Use it when performance matters
- Cost is one extra object; memory concern
- Wrapped object is always fast
- Lifecycle of DOM Objects
- JS wrapper keeps C++ object alive
- Ref<> in JSDOMWrapper
- Two ways to keep JS wrappers alive
- Visit children
- Reachable from Opaque Roots
- Visit children? Implement visitChildren function and do something?
- Yes
- Inspector GC heap, you can look at it in Web Inspector
- JS wrapper keeps C++ object alive
- Common misconception
- C++ objects do NOT keep their JS wrappers alive by default
class Some : RefCounted<Some> {
… Ref<Other> m_other; <<— JS other will still go away
} class Other : RefCounted<Other> { }
- Lifecycle: Visit Children
- JSCustomMarkFunction in IDL
- Add JS*::visitAdditionalChildren in JS*Custom.cpp
- Visit JS object kept by WebCore
- Lifecycle: Opaque Roots
- GeneratelsReachable=Impl* or CustomlsReachable in IDL
- addOpaqueRoot in visitAdditionalChildren
- JS*::isReachableFromOpaqueRoots
- Lifecycle: Concurrency
- Visiting & opaque root checks happen in non-main threads
- Can’t make createWeakPtr or ref / deref RefCounted objects
- Cant lookup HashMap
- What ones run with the main thread stopped vs what runs when main thread is not stopped?
- VisitChildren runs when the main thread is running, runs on background threads when the main thread is not running
- IsOpaqueRoots stops the main thread and runs on background threads
- Lifecycle: Common Cases
- Keeping JS object alive → Visit Children
- Store JSC::Weak<JSC::JSObject>
- ActiveDOMCallback for callbacks
- C++ object relationship → Opaque Roots
- Agree on opaque root; typically root Node
- Write thread safe code to get opaque root
- Keeping JS object alive → Visit Children
- Lifecycle: NodeLists
- Diagram
- Lifecycle: DOM Nodes
- Node is alive if it has refCount > 0 or has parent node
- Node increments Document’s m_referencingNodeCount
- Document is alive if refCount > 0 or m_referencingNodeCount > 0
- Node::removedLastRef on Element
- ContainerNode::removeDetachedChildren in ~ContainerNode
- Turn into flat linked list in deletion queue
- Document::removedLastRef() must clear any Ref / RefPtr to Node
- Not safe to traverse DOM tree during destruction
- Node Insertion & Removal
- Node::insertedIntoAncestor / removedFromAncestor
- Called whenever node’s ancestor changes
- Either “this” or its ancestor got inserted or removed
- Don’t assume tree scope or document change
- No script execution in insertedIntoAncestor or removedFromAncestor
- Will hit release assertion
- Use didFinishInsertingNode instead
- Node::insertedIntoAncestor / removedFromAncestor
- Node Insertion Order
- insertedIntoAncestor called in tree order
- Only talk to nodes earlier in tree order
- Node Removal Order
- removedFromAncestor called in tree order
- Only talk to nodes earlier in tree order
- Run layout tests with --world-leaks
- Lifecycle: Delayed Use
- Asynchronous use of “this” - XHR, media, …
- Make “this” ActiveDOMObject
- Asynchronous use of Node - MutationObserver, ResizeObserver, …
- GCReachableRef ← This is a leak!
- Asynchronous use of “this” - XHR, media, …
- Lifecycle: ActiveDOMObject
- Async work → dispatchEvent on this
- Reachable if hasPendingActivity is true
- Suspendable for back-forward cache
- HTML5 Event Loop
- WindowEventLoop has been added
- WorkerEventLoop is coming
- WindowEventLoop is shared across documents of similar origins
- Event Loop: In New Code
- Do NOT USE
- Timer / SuspendableTimer
- GenericEventQueue / GenericTaskQueue
- Do NOT USE
(rniwa is a genius. officially.)
Attachments (2)
-
Better-DOM-Code.pdf
(74.5 KB
) - added by 5 years ago.
Better DOM code slides
-
Back-Forward-Cache.pdf
(32.9 KB
) - added by 5 years ago.
Back forward cache slides
Download all attachments as: .zip
Note:
See TracWiki
for help on using the wiki.