       (when-not (:__html inner-html)
         (throw (Exception. "Invariant Violation: `props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information."))))
     
+    (append! sb "<" tag)
+    (render-attrs! attrs sb)
+    
     (if (container-tag? tag content)
-      (str "<" tag (render-attr-map attrs) ">"
-           (if inner-html
-             (:__html inner-html)
-             (-render-html content element *key))
-           "</" tag ">")
-      (str "<" tag (render-attr-map attrs) "/>"))))
+      (do
+        (append! sb ">")
+        (if inner-html
+          (append! sb (:__html inner-html))
+          (-render-html content element *key sb))
+        (append! sb "</" tag ">"))
+      (append! sb "/>"))))
 
 
 (extend-protocol HtmlRenderer
   IPersistentVector
-  (-render-html [this parent *key]
-    (-render-element this *key))
+  (-render-html [this parent *key sb]
+    (-render-element this *key sb))
 
   ISeq
-  (-render-html [this parent *key]
-    (str/join ""
-      (for [element this]
-        (-render-html element this *key))))
+  (-render-html [this parent *key sb]
+    (doseq [element this]
+      (-render-html element this *key sb)))
 
   Named
-  (-render-html [this parent *key]
-    (name this))
+  (-render-html [this parent *key sb]
+    (append! sb (name this)))
 
   String
-  (-render-html [this parent *key]
+  (-render-html [this parent *key sb]
     (if (> (count parent) 1)
       (let [key @*key]
         (vswap! *key inc)
-        (str "<!-- react-text: " key " -->"
-             (escape-html this)
-             "<!-- /react-text -->"))
-      (escape-html this)))
+        (append! sb "<!-- react-text: " key " -->" (escape-html this) "<!-- /react-text -->"))
+      (append! sb (escape-html this))))
 
   Object
-  (-render-html [this parent *key]
-    (-render-html (str this) parent *key))
+  (-render-html [this parent *key sb]
+    (-render-html (str this) parent *key sb))
 
   nil
-  (-render-html [this parent *key]
-    ""))
+  (-render-html [this parent *key sb]
+    :nop))
 
 
 ;; https://github.com/facebook/react/blob/master/src/shared/utils/adler32.js
-(defn adler32 [^String s]
-  (let [l (count s)
+(defn adler32 [^StringBuilder sb]
+  (let [l (.length sb)
         m (bit-and l -4)]
     (loop [a (int 1)
            b (int 0)



(defn normalize-css-key [k]
  (-> (as-str k)
      (str/replace #"[A-Z]" (fn [ch] (str "-" (str/lower-case ch))))
      (str/replace #"^ms-" "-ms-")))



(defn escape-html
  "Change special characters into HTML character entities."
  ^String [^String text]
  (.. text
    (replace "&"  "&amp;")
    (replace "<"  "&lt;")
    (replace ">"  "&gt;")
