diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72167849c5c8a4fe6a6d8333b58764a8e090cfb0..2117ef1b101d2b800af6d324726cf1b12b2b8804 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,9 +10,15 @@ Note that since we don't clearly distinguish between a public and private interf
 - Add ``Mesh`` processing helper ``.smoothEdges``
 - Smooth border of molecular-surface with ``includeParent`` enabled
 - Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful)
-- Improved ``StructureElement.Loci.size`` performance (for marking large cellpack models)
 - Fix new ``TransformData`` issues (camera/bounding helper not showing up)
-- Improve marking performance (avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``)
+- Improve marking performance
+    - Avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``
+    - Check if loci is superset of visual
+    - Check if loci overlaps with unit visual
+    - Ensure ``Interval`` is used for ranges instead of ``SortedArray``
+    - Inline ``StructureElement.Loci.size`` code
+    - Add uniform marker type
+    - Special case for reversing previous mark
 - Add optional marking pass
     - Outlines visible and hidden parts of highlighted/selected groups
     - Add highlightStrength/selectStrength renderer params
diff --git a/src/mol-model/structure/structure/element/loci.ts b/src/mol-model/structure/structure/element/loci.ts
index cce5eff09e4ad7034b57aa74df9860a7914eab83..cb68abbdd7a5597a0543514b876f0b096d8dbf4a 100644
--- a/src/mol-model/structure/structure/element/loci.ts
+++ b/src/mol-model/structure/structure/element/loci.ts
@@ -253,6 +253,14 @@ export namespace Loci {
         return isSubset;
     }
 
+    function makeIndexSet(newIndices: ArrayLike<UnitIndex>): OrderedSet<UnitIndex> {
+        if (newIndices.length > 3 && SortedArray.isRange(newIndices)) {
+            return Interval.ofRange(newIndices[0], newIndices[newIndices.length - 1]);
+        } else {
+            return SortedArray.ofSortedArray(newIndices);
+        }
+    }
+
     export function extendToWholeResidues(loci: Loci, restrictToConformation?: boolean): Loci {
         const elements: Loci['elements'][0][] = [];
         const residueAltIds = new Set<string>();
@@ -297,7 +305,7 @@ export namespace Loci {
                     }
                 }
 
-                elements[elements.length] = { unit: lociElement.unit, indices: SortedArray.ofSortedArray(newIndices) };
+                elements[elements.length] = { unit: lociElement.unit, indices: makeIndexSet(newIndices) };
             } else {
                 // coarse elements are already by-residue
                 elements[elements.length] = lociElement;
@@ -319,14 +327,6 @@ export namespace Loci {
         return element.unit.elements.length === OrderedSet.size(element.indices);
     }
 
-    function makeIndexSet(newIndices: number[]): OrderedSet<UnitIndex> {
-        if (newIndices.length > 12 && newIndices[newIndices.length - 1] - newIndices[0] === newIndices.length - 1) {
-            return Interval.ofRange(newIndices[0], newIndices[newIndices.length - 1]);
-        } else {
-            return SortedArray.ofSortedArray(newIndices);
-        }
-    }
-
     function collectChains(unit: Unit, chainIndices: Set<ChainIndex>, elements: Loci['elements'][0][]) {
         const { index } = getChainSegments(unit);
         const xs = unit.elements;
@@ -470,7 +470,10 @@ export namespace Loci {
     }
 
     function getUnitIndices(elements: SortedArray<ElementIndex>, indices: SortedArray<ElementIndex>) {
-        return OrderedSet.ofSortedArray(SortedArray.indicesOf<ElementIndex, UnitIndex>(elements, indices));
+        if (SortedArray.areEqual(elements, indices) && SortedArray.isRange(elements)) {
+            return Interval.ofLength(elements.length);
+        }
+        return makeIndexSet(SortedArray.indicesOf<ElementIndex, UnitIndex>(elements, indices));
     }
 
     export function extendToAllInstances(loci: Loci): Loci {
diff --git a/src/mol-repr/structure/units-visual.ts b/src/mol-repr/structure/units-visual.ts
index 8acaf871bab614b675e685ea392ad9bcc19d4017..e4105f9eb16589aefee9e2e547f7a5a3f2e38c67 100644
--- a/src/mol-repr/structure/units-visual.ts
+++ b/src/mol-repr/structure/units-visual.ts
@@ -290,7 +290,18 @@ export function UnitsVisual<G extends Geometry, P extends StructureParams & Geom
             return renderObject ? getLoci(pickingId, currentStructureGroup, renderObject.id) : EmptyLoci;
         },
         mark(loci: Loci, action: MarkerAction) {
-            return Visual.mark(renderObject, loci, action, lociApply, previousMark);
+            let hasInvariantId = true;
+            if (StructureElement.Loci.is(loci)) {
+                hasInvariantId = false;
+                const { invariantId } = currentStructureGroup.group.units[0];
+                for (const e of loci.elements) {
+                    if (e.unit.invariantId === invariantId) {
+                        hasInvariantId = true;
+                        break;
+                    }
+                }
+            }
+            return hasInvariantId ? Visual.mark(renderObject, loci, action, lociApply, previousMark) : false;
         },
         setVisibility(visible: boolean) {
             Visual.setVisibility(renderObject, visible);
diff --git a/src/mol-repr/structure/visual/util/element.ts b/src/mol-repr/structure/visual/util/element.ts
index b9a8ea919a3e669edfc8f0921d8456954bd33fe0..34ca57ffaf8d02daa31d2c1200c8cce4d513f6e5 100644
--- a/src/mol-repr/structure/visual/util/element.ts
+++ b/src/mol-repr/structure/visual/util/element.ts
@@ -164,8 +164,9 @@ export function eachElement(loci: Loci, structureGroup: StructureGroup, apply: (
     const { structure, group } = structureGroup;
     if (!Structure.areEquivalent(loci.structure, structure)) return false;
     const elementCount = group.elements.length;
+    const { unitIndexMap } = group;
     for (const e of loci.elements) {
-        const unitIdx = group.unitIndexMap.get(e.unit.id);
+        const unitIdx = unitIndexMap.get(e.unit.id);
         if (unitIdx !== undefined) {
             const offset = unitIdx * elementCount; // to target unit instance
             if (Interval.is(e.indices)) {
diff --git a/src/mol-repr/visual.ts b/src/mol-repr/visual.ts
index 13689cee537941376284cf6bea4b98144bee1a3e..163a47dfaff3d1d5a1c3b37f86dd80b73039c92e 100644
--- a/src/mol-repr/visual.ts
+++ b/src/mol-repr/visual.ts
@@ -84,6 +84,7 @@ namespace Visual {
                 intervalSize += Interval.size(interval);
                 return true;
             }, true);
+            if (intervalSize === 0) return false;
             if (intervalSize === count) loci = EveryLoci;
         }