<NME> Node.swift
<BEF> import UIKit
import CSSLayout

public protocol Node: class, Keyable {
  weak var owner: Node? { get set }
  weak var parent: Node? { get set }
  var context: Context? { get set }
  var view: View { get }

  var children: [Node]? { get set }
  var cssNode: CSSNode? { get set }
  var type: ElementRepresentable { get }

  func build() -> View
  func update(with newElement: Element)
  func forceUpdate()
  func computeLayout(availableWidth: Float, availableHeight: Float) -> CSSLayout
  func buildCSSNode() -> CSSNode
  func updateCSSNode()
  func getContext() -> Context
  func willUpdate()
  func didUpdate()
  func willDetach()
}

public extension Node {
  }

  func updateParent() {
    for child in (children ?? []) {
      child.parent = self
    }
  }

  func getContext() -> Context {
    guard let context = context ?? owner?.getContext() else {
      fatalError("No context available")
    }
    return context
  }
}

public protocol PropertyNode: Node {
  associatedtype PropertiesType: Properties

  var element: ElementData<PropertiesType> { get set }
  var properties: PropertiesType { get set }

  func shouldUpdate(nextProperties: PropertiesType) -> Bool
  func performDiff()
}

public extension PropertyNode {
  public var key: String? {
    get {
      return properties.core.identifier.key
    }
    set {
      properties.core.identifier.key = newValue
    }
  }

  var type: ElementRepresentable {
    return element.type
  }

  func update(with newElement: Element) {
    let newElement = newElement as! ElementData<PropertiesType>
    let nextProperties = newElement.properties
    let shouldUpdate = self.shouldUpdate(nextProperties: nextProperties)
    performUpdate(with: newElement, nextProperties: nextProperties, shouldUpdate: shouldUpdate)
  }

  func forceUpdate() {
    performUpdate(with: element, nextProperties: properties, shouldUpdate: true)
  }

  }

  func performDiff(newElement: Element) {
    guard let instance = instance else {
      fatalError()
    }

    maybeUpdateProperties(instance: instance, with: newElement)
    element = newElement

    let children = newElement.children ?? []

    var currentChildren = (instance.children ?? []).keyed { index, elm in
      computeKey(index, elm)
    }

    for (index, element) in children.enumerated() {
      let key = computeKey(index, element)
      guard let instance = currentChildren[key] else {
        append(element)

  private func diffChildren(newChildren: [Element]) {
    var currentChildren = (children ?? []).keyed { index, elm in
      computeKey(index, elm)
      if shouldReplace(instance, with: element) {
        replace(instance, with: element)
      } else {
        maybeUpdateProperties(instance: instance, with: element)
        move(child: instance, to: index)
        // TODO(mcudich): Make this more generic.
        if let componentInstance = instance as? Component {
          instance.performDiff(newElement: componentInstance.render())
        } else {
          instance.performDiff(newElement: element)
        }
      }
    }

      currentChildren.removeValue(forKey: key)

      if shouldReplace(type: currentChild.type, with: element.type) {
        replace(currentChild, with: element)
      } else {
        move(child: currentChild, to: index)
        currentChild.update(with: element)
      }
    }

    for (_, child) in currentChildren {
      remove(child: child)
    }
  }

  private func computeKey(_ index: Int, _ keyable: Keyable) -> String {
    return keyable.key ?? "\(index)"
  }

  private func insert(child: Node, at index: Int) {
    children?.insert(child, at: index)
    cssNode?.insertChild(child: child.buildCSSNode(), at: index)
  }

  private func remove(child: Node) {
    guard let index = index(of: child) else {
      return
    }
    children?.remove(at: index)
    if let childNode = child.cssNode {
      cssNode?.removeChild(child: childNode)
    }
  }

  private func move(child: Node, to index: Int) {
    guard let currentIndex = self.index(of: child), currentIndex != index else {
      return
    }
    children?.remove(at: currentIndex)
    if let childNode = child.cssNode {
      cssNode?.removeChild(child: childNode)
    }
    insert(child: child, at: index)
  }

  private func index(of child: Node) -> Int? {
    return children?.index(where: { $0 === child })
  }

  private func replace(_ node: Node, with element: Element) {
    let replacement = element.build(withOwner: owner, context: nil)
    let index = self.index(of: node)!
    remove(child: node)
    insert(child: replacement, at: index)
  }

  private func append(_ element: Element) {
    let child = element.build(withOwner: owner, context: nil)
    children?.insert(child, at: children!.endIndex)
    cssNode?.insertChild(child: child.buildCSSNode(), at: children!.count - 1)
  }
}

<MSG> Make diff routine a bit more simple

<DFF> @@ -21,6 +21,9 @@ public protocol Node: class, PropertyHolder, Keyable {
   func willUpdate()
   func didUpdate()
   func willDetach()
+
+  func performDiff(newElement: Element)
+  func getDiffChildren(newElement: Element) -> [Element]?
 }
 
 public extension Node {
@@ -78,20 +81,24 @@ public extension Node {
   }
 
   func performDiff(newElement: Element) {
-    guard let instance = instance else {
-      fatalError()
-    }
+    maybeUpdateProperties(instance: self, with: newElement)
+
+    // TODO(mcudich): Only attempt to diff children if properties or state has changed since the last time we rendered.
+    diffChildren(newChildren: getDiffChildren(newElement: newElement) ?? [])
 
-    maybeUpdateProperties(instance: instance, with: newElement)
     element = newElement
+  }
 
-    let children = newElement.children ?? []
+  func getDiffChildren(newElement: Element) -> [Element]? {
+    return newElement.children
+  }
 
-    var currentChildren = (instance.children ?? []).keyed { index, elm in
+  func diffChildren(newChildren: [Element]) {
+    var currentChildren = (children ?? []).keyed { index, elm in
       computeKey(index, elm)
     }
 
-    for (index, element) in children.enumerated() {
+    for (index, element) in newChildren.enumerated() {
       let key = computeKey(index, element)
       guard let instance = currentChildren[key] else {
         append(element)
@@ -102,14 +109,8 @@ public extension Node {
       if shouldReplace(instance, with: element) {
         replace(instance, with: element)
       } else {
-        maybeUpdateProperties(instance: instance, with: element)
         move(child: instance, to: index)
-        // TODO(mcudich): Make this more generic.
-        if let componentInstance = instance as? Component {
-          instance.performDiff(newElement: componentInstance.render())
-        } else {
-          instance.performDiff(newElement: element)
-        }
+        instance.performDiff(newElement: element)
       }
     }
 

Make diff routine a bit more simple