diff --git a/common/src/app/common/files/helpers.cljc b/common/src/app/common/files/helpers.cljc
index 287bb7bb8..d6a15fcd4 100644
--- a/common/src/app/common/files/helpers.cljc
+++ b/common/src/app/common/files/helpers.cljc
@@ -16,6 +16,8 @@
    [clojure.set :as set]
    [cuerdas.core :as str]))
 
+#?(:clj (set! *warn-on-reflection* true))
+
 (declare reduce-objects)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -327,12 +329,9 @@
   "Selects the shape that will be the base to add the shapes over"
   [objects selected]
   (let [;; Gets the tree-index for all the shapes
-        indexed-shapes (indexed-shapes objects)
-
+        indexed-shapes (indexed-shapes objects selected)
         ;; Filters the selected and retrieve a list of ids
-        sorted-ids (->> indexed-shapes
-                        (filter (comp selected second))
-                        (map second))]
+        sorted-ids     (map val indexed-shapes)]
 
     ;; The first id will be the top-most
     (get objects (first sorted-ids))))
@@ -486,43 +485,62 @@
 
     (reduce add-element (d/ordered-set) ids)))
 
-(defn indexed-shapes
-  "Retrieves a list with the indexes for each element in the layer tree.
-   This will be used for shift+selection."
-  [objects]
-  (letfn [(red-fn [cur-idx id]
-            (let [[prev-idx _] (first cur-idx)
-                  prev-idx (or prev-idx 0)
-                  cur-idx (conj cur-idx (d/vec2 (inc prev-idx) id))]
-              (rec-index cur-idx id)))
-          (rec-index [cur-idx id]
-            (let [object (get objects id)]
-              (reduce red-fn cur-idx (reverse (:shapes object)))))]
-    (into {} (rec-index '() uuid/zero))))
+(defn- indexed-shapes
+  "Retrieves a vector with the indexes for each element in the layer
+  tree. This will be used for shift+selection."
+  [objects selected]
+  (loop [index   1
+         result  (transient [])
+         ;; Flag to start adding elements to the index
+         add?    false
+         ;; Only add elements while we're in the selection, we finish when the selection is over
+         pending (set selected)
+         shapes  (-> objects
+                     (get uuid/zero)
+                     (get :shapes)
+                     (rseq))]
+
+    (let [shape-id (first shapes)]
+      (if (and (d/not-empty? pending) shape-id)
+        (let [shape   (get objects shape-id)
+              add?    (or add? (contains? selected shape-id))
+              pending (disj pending shape-id)
+              result  (if add?
+                        (conj! result (d/vec2 index shape-id))
+                        result)]
+          (if-let [children (get shape :shapes)]
+            (recur (inc index)
+                   result
+                   add?
+                   pending
+                   (concat (rseq children) (rest shapes)))
+            (recur (inc index)
+                   result
+                   add?
+                   pending
+                   (rest shapes))))
+        (persistent! result)))))
 
 (defn expand-region-selection
   "Given a selection selects all the shapes between the first and last in
    an indexed manner (shift selection)"
   [objects selection]
-  (let [indexed-shapes (indexed-shapes objects)
-        filter-indexes (->> indexed-shapes
-                            (filter (comp selection second))
-                            (map first))
-
-        from (apply min filter-indexes)
-        to   (apply max filter-indexes)]
-    (->> indexed-shapes
-         (filter (fn [[idx _]] (and (>= idx from) (<= idx to))))
-         (map second)
-         (into #{}))))
+  (let [selection      (if (set? selection) selection (set selection))
+        indexed-shapes (indexed-shapes objects selection)
+        indexes        (map key indexed-shapes)
+        from           (apply min indexes)
+        to             (apply max indexes)
+        xform          (comp
+                        (filter (fn [[idx _]] (and (>= idx from) (<= idx to))))
+                        (map val))]
+    (into #{} xform indexed-shapes)))
 
 (defn order-by-indexed-shapes
-  [objects ids]
-  (let [ids (if (set? ids) ids (set ids))]
-    (->> (indexed-shapes objects)
-         (filter (fn [o] (contains? ids (val o))))
-         (sort-by key)
-         (map val))))
+  "Retrieves a ordered vector for each element in the layer tree and
+  filted by selected set"
+  [objects selected]
+  (let [selected (if (set? selected) selected (set selected))]
+    (sequence (map val) (indexed-shapes objects selected))))
 
 (defn get-index-replacement
   "Given a collection of shapes, calculate their positions