diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -225,7 +225,7 @@
 Disadvantages of 'type-of-html':
 - a bit noisy syntax (don't write types!)
 - sometimes unusual type error messages
-- compile times (30sec for a medium sized page, with `-O0` only ~3sec)
+- compile times (30sec for a medium sized page, with `-O0` only ~2sec)
 - needs at least ghc 8.2
 
 I'd generally recommend that you put your documents into an extra
diff --git a/src/Html/Convert.hs b/src/Html/Convert.hs
--- a/src/Html/Convert.hs
+++ b/src/Html/Convert.hs
@@ -1,5 +1,3 @@
-{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
-
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE FlexibleInstances          #-}
 {-# LANGUAGE TypeOperators              #-}
diff --git a/src/Html/Type.hs b/src/Html/Type.hs
--- a/src/Html/Type.hs
+++ b/src/Html/Type.hs
@@ -665,28 +665,44 @@
   CountContent ()            = 0
   CountContent _             = 1
 
+-- | We need efficient cons, snoc and append.  This API has cons(O1)
+-- and snoc(O1) but append(On).  Optimal would be a real 2-3
+-- FingerTree.
+data FingerTree = FingerTree [Symbol] Symbol
+
+type family (<|) (s :: Symbol) (t :: FingerTree) :: FingerTree where
+  (<|) l ('FingerTree (s ': ss) r) = 'FingerTree (AppendSymbol l s ': ss) r
+  (<|) l ('FingerTree '[] r) = 'FingerTree '[] (AppendSymbol l r)
+
+type family (|>) (t :: FingerTree) (s :: Symbol) :: FingerTree where
+  (|>) ('FingerTree ss r) rr = 'FingerTree ss (AppendSymbol r rr)
+
+type family (><) (t1 :: FingerTree) (t2 :: FingerTree) :: FingerTree where
+  (><) ('FingerTree ss r) ('FingerTree (s ': ss2) r2) = 'FingerTree (Append ss (AppendSymbol r s ': ss2)) r2
+  (><) ('FingerTree ss r) ('FingerTree '[] r2) = 'FingerTree ss (AppendSymbol r r2)
+
+type family ToList (t :: FingerTree) where
+  ToList ('FingerTree ss r) = Append ss '[r]
+
 -- | Flatten a html tree of elements into a type list of tags.
-type family ToTypeList a where
-  ToTypeList (() # b)       = ToTypeList b
+type family ToTypeList a :: FingerTree where
   ToTypeList (a # ())       = ToTypeList a
-  ToTypeList (a # b)        = Append (ToTypeList a) (ToTypeList b)
-  ToTypeList (a > ())       = If (HasContent (GetInfo a)) '[Just (AppendSymbol (OpenTag a) (CloseTag a))] '[Just (OpenTag a)]
-  ToTypeList ((a :@: b) ()) = Append (Just (AppendSymbol "<" (ShowElement a)) ': ToTypeList b) (If (HasContent (GetInfo a)) '[Just (AppendSymbol ">" (CloseTag a))] '[Just ">"])
-  ToTypeList (a > b)        = Append (Just (OpenTag a) ': ToTypeList b) '[Just (CloseTag a)]
-  ToTypeList ((a :@: b) c)  = Append (Just (AppendSymbol "<" (ShowElement a)) ': ToTypeList b) (Append (Just ">" ': ToTypeList c) '[Just (CloseTag a)])
-  ToTypeList (a := b)       = '[Just (AppendSymbol (AppendSymbol " " (ShowAttribute a)) "=\""), Nothing, Just "\""]
-  ToTypeList (Proxy x)      = '[Just x]
-  ToTypeList ()             = '[]
-  ToTypeList x              = '[Nothing]
+  ToTypeList (() # b)       = ToTypeList b
+  ToTypeList (a # b)        = ToTypeList a >< ToTypeList b
+  ToTypeList (a > ())       = 'FingerTree '[] (If (HasContent (GetInfo a)) (AppendSymbol (OpenTag a) (CloseTag a)) (OpenTag a))
+  ToTypeList ((a :@: b) ()) = AppendSymbol "<" (ShowElement a) <| ToTypeList b |> If (HasContent (GetInfo a)) (AppendSymbol ">" (CloseTag a)) ">"
+  ToTypeList (a > b)        = OpenTag a <| ToTypeList b |> CloseTag a
+  ToTypeList ((a :@: b) c)  = (AppendSymbol "<" (ShowElement a) <| ToTypeList b) >< (">" <| ToTypeList c |> CloseTag a)
+  ToTypeList (a := b)       = 'FingerTree '[AppendSymbol (AppendSymbol " " (ShowAttribute a)) "=\""] "\""
+  ToTypeList (Proxy x)      = 'FingerTree '[] x
+  ToTypeList x              = 'FingerTree '[""] ""
 
 -- | Append two type lists.
 --
 -- Note that this definition is that ugly to reduce compiletimes.
 -- Please check whether the context reduction stack or compiletimes of
 -- a big html page get bigger if you try to refactor.
-type family Append xs ys :: [k] where
-  Append xs '[]
-        = xs
+type family Append xs ys :: [Symbol] where
 
   Append (x1 ': x2 ': x3 ': x4 ': x5 ': x6 ': x7 ': x8 ': x9 ': x10 ': x11 ': x12 ': x13 ': x14 ': x15 ': x16 ': x17 ': x18 ': x19 ': x20 ': x21 ': x22 ': x23 ': x24 ': x25 ': x26 ': x27 ': x28 ': x29 ': x30 ': x31 ': x32 ': x33 ': x34 ': x35 ': x36 ': x37 ': x38 ': x39 ': x40 ': x41 ': x42 ': x43 ': x44 ': x45 ': x46 ': x47 ': x48 ': x49 ': x50 ': x51 ': x52 ': x53 ': x54 ': x55 ': x56 ': x57 ': x58 ': x59 ': x60 ': x61 ': x62 ': x63 ': x64 ': xs) ys
         = x1 ': x2 ': x3 ': x4 ': x5 ': x6 ': x7 ': x8 ': x9 ': x10 ': x11 ': x12 ': x13 ': x14 ': x15 ': x16 ': x17 ': x18 ': x19 ': x20 ': x21 ': x22 ': x23 ': x24 ': x25 ': x26 ': x27 ': x28 ': x29 ': x30 ': x31 ': x32 ': x33 ': x34 ': x35 ': x36 ': x37 ': x38 ': x39 ': x40 ': x41 ': x42 ': x43 ': x44 ': x45 ': x46 ': x47 ': x48 ': x49 ': x50 ': x51 ': x52 ': x53 ': x54 ': x55 ': x56 ': x57 ': x58 ': x59 ': x60 ': x61 ': x62 ': x63 ': x64 ': Append xs ys
@@ -717,35 +733,6 @@
   HasContent (ElementInfo _ NoContent) = False
   HasContent _                         = True
 
--- | Fuse neighbouring non empty type level strings.
---
--- Note that this definition is that ugly to reduce compiletimes.
--- Please check whether the context reduction stack or compiletimes of
--- a big html page get bigger if you try to refactor.
-type family Fuse a where
-  Fuse '[Just a, Nothing] = '[a, ""]
-  Fuse (Just x1 ': Nothing ': Just x2 ': Nothing ': x ': xs) = x1 ': x2 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Nothing ': Just x3 ': Nothing ': x ': xs) = AppendSymbol x1 x2 ': x3 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Nothing ': Just x2 ': Just x3 ': Nothing ': x ': xs) = x1 ': AppendSymbol x2 x3 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Nothing ': Just x4 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 x3) ': x4 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Nothing ': Just x3 ': Just x4 ': Nothing ': x ': xs) = AppendSymbol x1 x2 ': AppendSymbol x3 x4 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Nothing ': Just x2 ': Just x3 ': Just x4 ': Nothing ': x ': xs) = x1 ': AppendSymbol x2 (AppendSymbol x3 x4) ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Just x4 ': Nothing ': Just x5 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 (AppendSymbol x3 x4)) ': x5 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Nothing ': Just x4 ': Just x5 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 x3) ': AppendSymbol x4 x5 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Nothing ': Just x3 ': Just x4 ': Just x5 ': Nothing ': x ': xs) = AppendSymbol x1 x2 ': AppendSymbol x3 (AppendSymbol x4 x5) ': Fuse (x ': xs)
-  Fuse (Just x1 ': Nothing ': Just x2 ': Just x3 ': Just x4 ': Just x5 ': Nothing ': x ': xs) = x1 ': AppendSymbol x2 (AppendSymbol x3 (AppendSymbol x4 x5)) ': Fuse (x ': xs)
-
-  Fuse (Just x1 ': Nothing ': xs) = x1 ': Fuse xs
-  Fuse (Just x1 ': Just x2 ': Nothing ': x ': xs) = AppendSymbol x1 x2 ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 x3) ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Just x4 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 (AppendSymbol x3 x4)) ': Fuse (x ': xs)
-  Fuse (Just x1 ': Just x2 ': Just x3 ': Just x4 ': Just x5 ': Nothing ': x ': xs) = AppendSymbol x1 (AppendSymbol x2 (AppendSymbol x3 (AppendSymbol x4 x5))) ': Fuse (x ': xs)
-
-  Fuse (Just x1 ': Just x2 ': xs)  = Fuse (Just (AppendSymbol x1 x2) ': xs)
-  Fuse (Just a ': xs) = '[a]
-  Fuse (Nothing ': xs) = "" ': Fuse xs
-  Fuse '[] = '[]
-
 -- | Type level drop.
 --
 -- Note that this definition is that ugly to reduce compiletimes.
@@ -783,7 +770,6 @@
   Last (_ ': _ ': x ': xs) = Last (x ': xs)
   Last (_ ': x ': xs) = Last (x ': xs)
   Last (x ': xs) = x
-  Last _         = ""
 
 -- | Type of type level information about tags.
 data ElementInfo
@@ -839,7 +825,7 @@
 
 newtype Tagged (proxies :: [Symbol]) target = Tagged target
 
-type Symbols a = Fuse (ToTypeList a)
+type Symbols a = ToList (ToTypeList a)
 
 -- | Get type list of valid elements for a given attribute.  An empty list signifies global attribute.
 type family GetAttributeInfo a where
diff --git a/type-of-html.cabal b/type-of-html.cabal
--- a/type-of-html.cabal
+++ b/type-of-html.cabal
@@ -1,5 +1,5 @@
 name:                 type-of-html
-version:              0.5.1.0
+version:              0.5.1.1
 synopsis:             High performance type driven html generation.
 description:          This library makes most invalid html documents compile time errors and uses advanced type level features to realise compile time computations.
 license:              BSD3
