Skip to content

Web Worker Rendering

Matthew Phillips edited this page Jun 17, 2015 · 5 revisions

These are notes on the implementation of Web Worker Rendering.

Lifecycle

Page Load

User application is loaded in a Web Worker. can-min loads in the Browser window to handle event delegation and diffing/patching the real DOM.

  • (worker) Initial render to virtual DOM. postMessage diff.
  • (worker) Sends message on which DOM events need to be listened to.
  • (browser) Receive initial result. Diff/patch existing DOM.
  • (browser) Receives DOM event list, sets up listeners.

Data change

When data changes it will trigger can/view/live to update the Virtual DOM. We can wrap live.listen to hook into all DOM changes.

  • (worker) Send changed vdom element with its path like "0.2.0.1".
    • Or possibly an id assigned to each Node.
    • Batch changes together to reduce the number of messages needed.
  • (browser) Receive vdom diff, find real DOM counterpart and apply patch.

DOM Events

When a DOM event occurs (like a user clicks a button) we must send the event to the worker side so user code can act.

  • (browser) Has listener for each event the application is interested in. Captures and calls preventDefault(). Sends event object to the worker side.
    • Includes path/id to the target element.
  • (worker) Triggers event on the vdom element with a wrapped preventDefault.
  • (worker) If preventDefault is not called sends message back to browser side.
  • (browser) Receives event again and re-triggers on the target element.

Data Structures

These are data structures for passing messages back and forth between the Worker and

Render Message

This is the message that is sent from worker -> browser when a render takes place.

{
  changes: [VDOMDiff],
  events: [EventDescriber]
}

VDOMDiff

An object containing a path to the element that changed and a diff that can be applied to update it.

{
  path: "0.0.1.2.0", // Path starting with document.documentElement to find the element.
  diff: {}
}

EventDescriber

These are action that need to be taken on DOM events happening on the browser side.

{
  elementPath: "0.0.1.2.0",
  event: "click",
  action: "bind" // or "unbind"
}

Event Message

Sent from browser -> worker when a DOM event occurs matching one of the EventDescribers. Sent back from worker -> browser when the worker code doesn't call preventDefault()

{
  elementPath: "0.0.1.2.0",
  event: Event
}

Questions

  • How to identify a Node. Either an id or path. What is the most efficient way to generate a path?