       (some->> key (.! jsprops :key)))
     (.' js/React createElement c jsprops)))
 
-(def cached-parse (util/memoize-1 parse-tag))
+
+(def tag-name-cache #js{})
+
+(defn cached-parse [x]
+  (if-let [s (obj-get tag-name-cache (name x))]
+    s
+    (aset tag-name-cache (name x) (parse-tag x))))
+
 
 (declare as-element)
 
 (defn native-element [tag argv]
   (when (hiccup-tag? tag)
-    (let [[comp id-class] (cached-parse tag)]
+    (let [parsed (cached-parse tag)
+          comp (.' parsed :name)]
       (let [props (nth argv 1 nil)
             hasprops (or (nil? props) (map? props))
-            jsprops (convert-props (if hasprops props) id-class)
+            jsprops (convert-props (if hasprops props) parsed)
             first-child (if hasprops 2 1)]
         (if (input-component? comp)
           (-> [reagent-input argv comp jsprops first-child]

        class' (when class
                 (string/replace class #"\." " "))]
    (assert tag (str "Unknown tag: '" hiccup-tag "'"))
    [tag (when (or id class')
           [id class'])]))

(defn fn-to-class [f]
  (assert (ifn? f) (str "Expected a function, not " (pr-str f)))


;;; Props conversion

(def prop-name-cache #js{})

(defn obj-get [o k]
  (when (.hasOwnProperty o k)
    (aget o k)))

(defn cached-prop-name [x]
  (if (or (string? x)
          (not (implements? INamed x)))
    x
    (if-let [s (obj-get prop-name-cache (name x))]
      s
      (aset prop-name-cache (name x) (undash-prop-name x)))))

(defn convert-prop-value [x]
  (cond (string? x) x
