diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index 7d130125b3..61aa3b5d2d 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -220,6 +220,7 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
 void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
     stopDomainAndNonOwnedEntities();
 
+    auto sessionUUID = getTree()->getMyAvatarSessionUUID();
     std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities;
     // remove all entities from the scene
     auto scene = _viewState->getMain3DScene();
@@ -227,7 +228,7 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
         for (const auto& entry :  _entitiesInScene) {
             const auto& renderer = entry.second;
             const EntityItemPointer& entityItem = renderer->getEntity();
-            if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
+            if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == sessionUUID))) {
                 fadeOutRenderable(renderer);
             } else {
                 savedEntities[entry.first] = entry.second;
@@ -238,7 +239,9 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
     _renderablesToUpdate = savedEntities;
     _entitiesInScene = savedEntities;
 
-    _layeredZones.clearNonLocalLayeredZones();
+    if (_layeredZones.clearDomainAndNonOwnedZones(sessionUUID)) {
+        applyLayeredZones();
+    }
 
     OctreeProcessor::clearDomainAndNonOwnedEntities();
 }
@@ -271,6 +274,9 @@ void EntityTreeRenderer::clear() {
 
     // reset the zone to the default (while we load the next scene)
     _layeredZones.clear();
+    if (!_shuttingDown) {
+        applyLayeredZones();
+    }
 
     OctreeProcessor::clear();
 }
@@ -363,6 +369,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
             for (const auto& processedId : processedIds) {
                 _entitiesToAdd.erase(processedId);
             }
+            forceRecheckEntities();
         }
     }
 }
@@ -537,8 +544,7 @@ void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUp
     _spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second);
 }
 
-bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) {
-    bool didUpdate = false;
+void EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar) {
     float radius = 0.01f; // for now, assume 0.01 meter radius, because we actually check the point inside later
     QVector<QUuid> entityIDs;
 
@@ -550,7 +556,7 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
         // FIXME - if EntityTree had a findEntitiesContainingPoint() this could theoretically be a little faster
         entityTree->evalEntitiesInSphere(_avatarPosition, radius, PickFilter(), entityIDs);
 
-        LayeredZones oldLayeredZones(std::move(_layeredZones));
+        LayeredZones oldLayeredZones(_layeredZones);
         _layeredZones.clear();
 
         // create a list of entities that actually contain the avatar's position
@@ -578,8 +584,8 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
 
             if (contains) {
                 // if this entity is a zone and visible, add it to our layered zones
-                if (isZone && entity->getVisible() && renderableForEntity(entity)) {
-                    _layeredZones.insert(std::dynamic_pointer_cast<ZoneEntityItem>(entity));
+                if (isZone && entity->getVisible() && renderableIdForEntity(entity) != render::Item::INVALID_ITEM_ID) {
+                    _layeredZones.emplace(std::dynamic_pointer_cast<ZoneEntityItem>(entity));
                 }
 
                 if ((!hasScript && isZone) || scriptHasLoaded) {
@@ -588,24 +594,16 @@ bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QSet<EntityItemI
             }
         }
 
-        // check if our layered zones have changed
-        if ((_layeredZones.empty() && oldLayeredZones.empty()) || (!oldLayeredZones.empty() && _layeredZones.contains(oldLayeredZones))) {
-            return;
+        if (!_layeredZones.equals(oldLayeredZones)) {
+            applyLayeredZones();
         }
-
-        applyLayeredZones();
-
-        didUpdate = true;
     });
-
-    return didUpdate;
 }
 
-bool EntityTreeRenderer::checkEnterLeaveEntities() {
+void EntityTreeRenderer::checkEnterLeaveEntities() {
     PROFILE_RANGE(simulation_physics, "EnterLeave");
     PerformanceTimer perfTimer("enterLeave");
     auto now = usecTimestampNow();
-    bool didUpdate = false;
 
     if (_tree && !_shuttingDown) {
         glm::vec3 avatarPosition = _viewState->getAvatarPosition();
@@ -623,7 +621,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
             _forceRecheckEntities = false;
 
             QSet<EntityItemID> entitiesContainingAvatar;
-            didUpdate = findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar);
+            findBestZoneAndMaybeContainingEntities(entitiesContainingAvatar);
 
             // Note: at this point we don't need to worry about the tree being locked, because we only deal with
             // EntityItemIDs from here. The callEntityScriptMethod() method is robust against attempting to call scripts
@@ -649,7 +647,6 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() {
             }
         }
     }
-    return didUpdate;
 }
 
 void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() {
@@ -696,18 +693,12 @@ bool EntityTreeRenderer::applyLayeredZones() {
     // in the expected layered order and update the scene with it
     auto scene = _viewState->getMain3DScene();
     if (scene) {
-        render::Transaction transaction;
         render::ItemIDs list;
-        for (auto& zone : _layeredZones) {
-            auto id = renderableIdForEntity(zone.zone);
-            // The zone may not have been rendered yet.
-            if (id != render::Item::INVALID_ITEM_ID) {
-                list.push_back(id);
-            }
-        }
-        render::Selection selection("RankedZones", list);
-        transaction.resetSelection(selection);
+        _layeredZones.appendRenderIDs(list, this);
 
+        render::Selection selection("RankedZones", list);
+        render::Transaction transaction;
+        transaction.resetSelection(selection);
         scene->enqueueTransaction(transaction);
     } else {
         qCWarning(entitiesrenderer) << "EntityTreeRenderer::applyLayeredZones(), Unexpected null scene, possibly during application shutdown";
@@ -1018,7 +1009,6 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
 }
 
 void EntityTreeRenderer::addingEntity(const EntityItemID& entityID) {
-    forceRecheckEntities(); // reset our state to force checking our inside/outsideness of entities
     checkAndCallPreload(entityID);
     auto entity = std::static_pointer_cast<EntityTree>(_tree)->findEntityByID(entityID);
     if (entity) {
@@ -1190,107 +1180,96 @@ void EntityTreeRenderer::updateEntityRenderStatus(bool shouldRenderEntities) {
 }
 
 void EntityTreeRenderer::updateZone(const EntityItemID& id) {
-    // Get in the zone!
-    auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(getTree()->findEntityByEntityItemID(id));
-    if (zone && zone->contains(_avatarPosition)) {
-        _layeredZones.update(zone);
+    if (auto zone = std::dynamic_pointer_cast<ZoneEntityItem>(getTree()->findEntityByEntityItemID(id))) {
+        _layeredZones.update(zone, _avatarPosition, this);
+        applyLayeredZones();
     }
 }
 
-EntityTreeRenderer::LayeredZones::LayeredZones(LayeredZones&& other) {
-    // In a swap:
-    // > All iterators and references remain valid. The past-the-end iterator is invalidated.
-    bool isSkyboxLayerValid = (other._skyboxLayer != other.end());
+bool EntityTreeRenderer::LayeredZones::clearDomainAndNonOwnedZones(const QUuid& sessionUUID) {
+    bool zonesChanged = false;
 
-    swap(other);
-    _map.swap(other._map);
-    _skyboxLayer = other._skyboxLayer;
+    auto it = c.begin();
+    while (it != c.end()) {
+        if (!(it->zone->isLocalEntity() || (it->zone->isAvatarEntity() && it->zone->getOwningAvatarID() == sessionUUID))) {
+            zonesChanged = true;
+            it = c.erase(it);
+        } else {
+            it++;
+        }
+    }
 
-    if (!isSkyboxLayerValid) {
-        _skyboxLayer = end();
+    if (zonesChanged) {
+        std::make_heap(c.begin(), c.end(), comp);
+    }
+    return zonesChanged;
+}
+
+std::pair<bool, bool> EntityTreeRenderer::LayeredZones::getZoneInteractionProperties() const {
+    auto it = c.cbegin();
+    while (it != c.cend()) {
+        if (it->zone && it->zone->isDomainEntity()) {
+            return { it->zone->getFlyingAllowed(), it->zone->getGhostingAllowed() };
+        }
+        it++;
+    }
+    return { true, true };
+}
+
+void EntityTreeRenderer::LayeredZones::remove(const std::shared_ptr<ZoneEntityItem>& zone) {
+    auto it = c.begin();
+    while (it != c.end()) {
+        if (it->zone == zone) {
+            break;
+        }
+        it++;
+    }
+    if (it != c.end()) {
+        c.erase(it);
+        std::make_heap(c.begin(), c.end(), comp);
     }
 }
 
-void EntityTreeRenderer::LayeredZones::clearNonLocalLayeredZones() {
-    std::set<LayeredZone> localLayeredZones;
-    std::map<QUuid, iterator> newMap;
+void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer) {
+    // When a zone's position or visibility changes, we call this method
+    // In order to resort our zones, we first remove the changed zone, and then re-insert it if necessary
+    remove(zone);
 
-    for (auto iter = begin(); iter != end(); iter++) {
-        LayeredZone layeredZone = *iter;
+    // Only call contains if the zone is rendering
+    if (zone->isVisible() && entityTreeRenderer->renderableIdForEntity(zone) != render::Item::INVALID_ITEM_ID && zone->contains(position)) {
+        emplace(zone);
+    }
+}
 
-        if (layeredZone.zone->isLocalEntity()) {
-            bool success;
-            iterator it;
-            std::tie(it, success) = localLayeredZones.insert(layeredZone);
+bool EntityTreeRenderer::LayeredZones::equals(const LayeredZones& other) const {
+    if (size() != other.size()) {
+        return false;
+    }
 
-            if (success) {
-                newMap.emplace(layeredZone.id, it);
+    auto it = c.cbegin();
+    auto otherIt = other.c.cbegin();
+    while (it != c.cend()) {
+        if (*it != *otherIt) {
+            return false;
+        }
+        it++;
+        otherIt++;
+    }
+
+    return true;
+}
+
+void EntityTreeRenderer::LayeredZones::appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const {
+    auto it = c.cbegin();
+    while (it != c.cend()) {
+        if (it->zone) {
+            auto id = entityTreeRenderer->renderableIdForEntityId(it->id);
+            if (id != render::Item::INVALID_ITEM_ID) {
+                list.push_back(id);
             }
         }
+        it++;
     }
-
-    std::set<LayeredZone>::operator=(localLayeredZones);
-    _map = newMap;
-    _skyboxLayer = empty() ? end() : begin();
-}
-
-void EntityTreeRenderer::LayeredZones::clear() {
-    std::set<LayeredZone>::clear();
-    _map.clear();
-    _skyboxLayer = end();
-}
-
-std::pair<EntityTreeRenderer::LayeredZones::iterator, bool> EntityTreeRenderer::LayeredZones::insert(const LayeredZone& layer) {
-    iterator it;
-    bool success;
-    std::tie(it, success) = std::set<LayeredZone>::insert(layer);
-
-    if (success) {
-        _map.emplace(it->id, it);
-    }
-
-    return { it, success };
-}
-
-void EntityTreeRenderer::LayeredZones::update(std::shared_ptr<ZoneEntityItem> zone) {
-    bool isVisible = zone->isVisible();
-
-    if (empty() && isVisible) {
-        // there are no zones: set this one
-        insert(zone);
-        return;
-    } else {
-        LayeredZone zoneLayer(zone);
-
-        // find this zone's layer, if it exists
-        iterator layer = end();
-        auto it = _map.find(zoneLayer.id);
-        if (it != _map.end()) {
-            layer = it->second;
-            // if the volume changed, we need to resort the layer (reinsertion)
-            // if the visibility changed, we need to erase the layer
-            if (zoneLayer.volume != layer->volume || !isVisible) {
-                erase(layer);
-                _map.erase(it);
-                layer = end();
-            }
-        }
-
-        // (re)insert this zone's layer if necessary
-        if (layer == end() && isVisible) {
-            std::tie(layer, std::ignore) = insert(zoneLayer);
-            _map.emplace(layer->id, layer);
-        }
-    }
-}
-
-bool EntityTreeRenderer::LayeredZones::contains(const LayeredZones& other) {
-    bool result = std::equal(other.begin(), other._skyboxLayer, begin());
-    if (result) {
-        // if valid, set the _skyboxLayer from the other LayeredZones
-        _skyboxLayer = std::next(begin(), std::distance(other.begin(), other._skyboxLayer));
-    }
-    return result;
 }
 
 CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriorityFunc = [](const EntityItem& item) -> float {
@@ -1298,14 +1277,7 @@ CalculateEntityLoadingPriority EntityTreeRenderer::_calculateEntityLoadingPriori
 };
 
 std::pair<bool, bool> EntityTreeRenderer::getZoneInteractionProperties() {
-    for (auto& zone : _layeredZones) {
-        // Only domain entities control flying allowed and ghosting allowed
-        if (zone.zone && zone.zone->isDomainEntity()) {
-            return { zone.zone->getFlyingAllowed(), zone.zone->getGhostingAllowed() };
-        }
-    }
-
-    return { true, true };
+    return _layeredZones.getZoneInteractionProperties();
 }
 
 bool EntityTreeRenderer::wantsKeyboardFocus(const EntityItemID& id) const {
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h
index 05105a2c7f..f7f5ae9f22 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.h
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.h
@@ -169,7 +169,7 @@ private:
 
     void resetEntitiesScriptEngine();
 
-    bool findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar);
+    void findBestZoneAndMaybeContainingEntities(QSet<EntityItemID>& entitiesContainingAvatar);
 
     bool applyLayeredZones();
     void stopDomainAndNonOwnedEntities();
@@ -180,7 +180,7 @@ private:
     EntityItemID _currentClickingOnEntityID;
 
     QScriptValueList createEntityArgs(const EntityItemID& entityID);
-    bool checkEnterLeaveEntities();
+    void checkEnterLeaveEntities();
     void leaveDomainAndNonOwnedEntities();
     void leaveAllEntities();
     void forceRecheckEntities();
@@ -210,48 +210,38 @@ private:
 
     class LayeredZone {
     public:
-        LayeredZone(std::shared_ptr<ZoneEntityItem> zone, QUuid id, float volume) : zone(zone), id(id), volume(volume) {}
-        LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : LayeredZone(zone, zone->getID(), zone->getVolumeEstimate()) {}
+        LayeredZone(std::shared_ptr<ZoneEntityItem> zone) : zone(zone), id(zone->getID()), volume(zone->getVolumeEstimate()) {}
 
-        bool operator<(const LayeredZone& r) const { return std::tie(volume, id) < std::tie(r.volume, r.id); }
-        bool operator==(const LayeredZone& r) const { return id == r.id; }
-        bool operator<=(const LayeredZone& r) const { return (*this < r) || (*this == r); }
+        bool operator>(const LayeredZone& r) const { return volume > r.volume; }
+        bool operator==(const LayeredZone& r) const { return zone.get() == r.zone.get(); }
+        bool operator!=(const LayeredZone& r) const { return !(*this == r); }
+        bool operator>=(const LayeredZone& r) const { return (*this > r) || (*this == r); }
 
         std::shared_ptr<ZoneEntityItem> zone;
         QUuid id;
         float volume;
     };
 
-    class LayeredZones : public std::set<LayeredZone> {
+    class LayeredZones : public std::priority_queue<LayeredZone, std::vector<LayeredZone>, std::greater<LayeredZone>> {
     public:
-        LayeredZones() {};
-        LayeredZones(LayeredZones&& other);
+        void clear() { *this = LayeredZones(); }
+        bool clearDomainAndNonOwnedZones(const QUuid& sessionUUID);
 
-        // avoid accidental misconstruction
-        LayeredZones(const LayeredZones&) = delete;
-        LayeredZones& operator=(const LayeredZones&) = delete;
-        LayeredZones& operator=(LayeredZones&&) = delete;
+        bool equals(const LayeredZones& other) const;
+        void remove(const std::shared_ptr<ZoneEntityItem>& zone);
+        void update(std::shared_ptr<ZoneEntityItem> zone, const glm::vec3& position, EntityTreeRenderer* entityTreeRenderer);
 
-        void clear();
-        void clearNonLocalLayeredZones();
-        std::pair<iterator, bool> insert(const LayeredZone& layer);
-        void update(std::shared_ptr<ZoneEntityItem> zone);
-        bool contains(const LayeredZones& other);
-
-        std::shared_ptr<ZoneEntityItem> getZone() { return empty() ? nullptr : begin()->zone; }
-
-    private:
-        std::map<QUuid, iterator> _map;
-        iterator _skyboxLayer { end() };
+        void appendRenderIDs(render::ItemIDs& list, EntityTreeRenderer* entityTreeRenderer) const;
+        std::pair<bool, bool> getZoneInteractionProperties() const;
     };
 
     LayeredZones _layeredZones;
-    float _avgRenderableUpdateCost { 0.0f };
-
     uint64_t _lastZoneCheck { 0 };
     const uint64_t ZONE_CHECK_INTERVAL = USECS_PER_MSEC * 100; // ~10hz
     const float ZONE_CHECK_DISTANCE = 0.001f;
 
+    float _avgRenderableUpdateCost { 0.0f };
+
     ReadWriteLockable _changedEntitiesGuard;
     std::unordered_set<EntityItemID> _changedEntities;
 
diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp
index 64cca404cb..e4300cca76 100644
--- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp
+++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp
@@ -92,9 +92,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
     }
 
     { // Sun 
-      // Need an update ?
         if (_needSunUpdate) {
-            // Do we need to allocate the light in the stage ?
             if (LightStage::isIndexInvalid(_sunIndex)) {
                 _sunIndex = _stage->addLight(_sunLight);
             } else {
@@ -107,9 +105,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
     { // Ambient
         updateAmbientMap();
 
-        // Need an update ?
         if (_needAmbientUpdate) {
-            // Do we need to allocate the light in the stage ?
             if (LightStage::isIndexInvalid(_ambientIndex)) {
                 _ambientIndex = _stage->addLight(_ambientLight);
             } else {
@@ -123,7 +119,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
         updateSkyboxMap();
 
         if (_needBackgroundUpdate) {
-            if (_skyboxMode == COMPONENT_MODE_ENABLED && BackgroundStage::isIndexInvalid(_backgroundIndex)) {
+            if (BackgroundStage::isIndexInvalid(_backgroundIndex)) {
                 _backgroundIndex = _backgroundStage->addBackground(_background);
             }
             _needBackgroundUpdate = false;
@@ -186,24 +182,19 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
     }
 }
 
-void ZoneEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) {
-#if 0
-    if (_model) {
-        _model->removeFromScene(scene, transaction);
-    }
-#endif
-    Parent::removeFromScene(scene, transaction);
-}
-
 void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
-    DependencyManager::get<EntityTreeRenderer>()->updateZone(entity->getID());
-
     auto position = entity->getWorldPosition();
     auto rotation = entity->getWorldOrientation();
     auto dimensions = entity->getScaledDimensions();
     bool rotationChanged = rotation != _lastRotation;
     bool transformChanged = rotationChanged || position != _lastPosition || dimensions != _lastDimensions;
 
+    auto visible = entity->getVisible();
+    if (transformChanged || visible != _lastVisible) {
+        _lastVisible = visible;
+        DependencyManager::get<EntityTreeRenderer>()->updateZone(entity->getID());
+    }
+
     auto proceduralUserData = entity->getUserData();
     bool proceduralUserDataChanged = _proceduralUserData != proceduralUserData;
 
@@ -226,25 +217,6 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
         _proceduralUserData = entity->getUserData();
     }
 
-#if 0
-    if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
-        _lastShapeURL = _typedEntity->getCompoundShapeURL();
-        _model.reset();
-        _model = std::make_shared<Model>();
-        _model->setIsWireframe(true);
-        _model->init();
-        _model->setURL(_lastShapeURL);
-    }
-
-    if (_model && _model->isActive()) {
-        _model->setScaleToFit(true, _lastDimensions);
-        _model->setSnapModelToRegistrationPoint(true, _entity->getRegistrationPoint());
-        _model->setRotation(_lastRotation);
-        _model->setTranslation(_lastPosition);
-        _model->simulate(0.0f);
-    }
-#endif
-
     updateKeyZoneItemFromEntity(entity);
 
     if (keyLightChanged) {
@@ -296,6 +268,10 @@ ItemKey ZoneEntityRenderer::getKey() {
 }
 
 bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
+    if (entity->getVisible() != _lastVisible) {
+        return true;
+    }
+
     if (entity->keyLightPropertiesChanged() ||
         entity->ambientLightPropertiesChanged() ||
         entity->hazePropertiesChanged() ||
@@ -323,25 +299,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
         return true;
     }
 
-#if 0
-    if (_typedEntity->getCompoundShapeURL() != _lastShapeURL) {
-        return true;
-    }
-
-    if (_model) {
-        if (!_model->needsFixupInScene() && (!ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() != SHAPE_TYPE_COMPOUND)) {
-            return true;
-        }
-
-        if (_model->needsFixupInScene() && (ZoneEntityItem::getDrawZoneBoundaries() || _entity->getShapeType() == SHAPE_TYPE_COMPOUND)) {
-            return true;
-        }
-
-        if (_lastModelActive != _model->isActive()) {
-            return true;
-        }
-    }
-#endif
+    // FIXME: do we need to trigger an update when shapeType changes?  see doRenderUpdateAsynchronousTyped
 
     return false;
 }
@@ -450,7 +408,6 @@ void ZoneEntityRenderer::updateKeyZoneItemFromEntity(const TypedEntityPointer& e
 }
 
 void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) {
-    // nothing change if nothing change
     if (_ambientTextureURL == ambientUrl) {
         return;
     }
@@ -466,8 +423,6 @@ void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) {
         _pendingAmbientTexture = true;
         auto textureCache = DependencyManager::get<TextureCache>();
         _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::AMBIENT_TEXTURE);
-
-        // keep whatever is assigned on the ambient map/sphere until texture is loaded
     }
 }
 
@@ -492,7 +447,6 @@ void ZoneEntityRenderer::updateAmbientMap() {
 }
 
 void ZoneEntityRenderer::setSkyboxURL(const QString& skyboxUrl) {
-    // nothing change if nothing change
     if (_skyboxTextureURL == skyboxUrl) {
         return;
     }
diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h
index 2fa55f1540..5fd9b87408 100644
--- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h
+++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h
@@ -24,9 +24,6 @@
 #include "RenderableEntityItem.h"
 #include <ComponentMode.h>
 
-#if 0
-#include <Model.h>
-#endif
 namespace render { namespace entities { 
 
 class ZoneEntityRenderer : public TypedEntityRenderer<ZoneEntityItem> {
@@ -40,7 +37,6 @@ protected:
     virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;
     virtual ItemKey getKey() override;
     virtual void doRender(RenderArgs* args) override;
-    virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
     virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
     virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
     virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
@@ -76,14 +72,7 @@ private:
     glm::vec3 _lastPosition;
     glm::vec3 _lastDimensions;
     glm::quat _lastRotation;
-
-    // FIXME compount shapes are currently broken
-    // FIXME draw zone boundaries are currently broken (also broken in master)
-#if 0
-    ModelPointer _model;
-    bool _lastModelActive { false };
-    QString _lastShapeURL;
-#endif
+    bool _lastVisible;
 
     LightStagePointer _stage;
     const graphics::LightPointer _sunLight { std::make_shared<graphics::Light>() };
@@ -137,25 +126,4 @@ private:
 
 } } // namespace 
 
-#if 0
-
-class NetworkGeometry;
-class KeyLightPayload;
-
-class RenderableZoneEntityItemMeta;
-
-class RenderableZoneEntityItem : public ZoneEntityItem, public RenderableEntityInterface  {
-public:
-    virtual bool contains(const glm::vec3& point) const override;
-    virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
-    virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
-private:
-    virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override { EntityItem::locationChanged(tellPhysics, tellChildren); notifyBoundChanged(); }
-    virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
-    void notifyBoundChanged();
-    void notifyChangedRenderItem();
-    void sceneUpdateRenderItemFromEntity(render::Transaction& transaction);
-};
-#endif
-
 #endif // hifi_RenderableZoneEntityItem_h
diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp
index 0e9672a7f2..8403d87868 100644
--- a/libraries/render-utils/src/ZoneRenderer.cpp
+++ b/libraries/render-utils/src/ZoneRenderer.cpp
@@ -43,7 +43,7 @@ const Selection::Name ZoneRendererTask::ZONES_SELECTION { "RankedZones" };
 
 void ZoneRendererTask::build(JobModel& task, const Varying& input, Varying& output) {
     // Filter out the sorted list of zones
-    const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION.c_str());
+    const auto zoneItems = task.addJob<render::SelectSortItems>("FilterZones", input, ZONES_SELECTION);
 
     // just setup the current zone env
     task.addJob<SetupZones>("SetupZones", zoneItems);
diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp
index 4f6fe3e36a..ff848aa464 100644
--- a/libraries/render/src/render/Scene.cpp
+++ b/libraries/render/src/render/Scene.cpp
@@ -277,6 +277,9 @@ void Scene::processTransactionFrame(const Transaction& transaction) {
         // removes
         removeItems(transaction._removedItems);
 
+        // handle selections
+        resetSelections(transaction._resetSelections);
+
         // add transitions
         transitionItems(transaction._addedTransitions);
         reApplyTransitions(transaction._reAppliedTransitions);
@@ -287,13 +290,6 @@ void Scene::processTransactionFrame(const Transaction& transaction) {
         _numAllocatedItems.exchange(maxID);
     }
 
-    if (transaction.touchTransactions()) {
-        std::unique_lock<std::mutex> lock(_selectionsMutex);
-
-        // resets and potential NEW items
-        resetSelections(transaction._resetSelections);
-    }
-
     resetHighlights(transaction._highlightResets);
     removeHighlights(transaction._highlightRemoves);
     queryHighlights(transaction._highlightQueries);
@@ -581,35 +577,34 @@ void Scene::resetItemTransition(ItemID itemId) {
     }
 }
 
-// This function is thread safe
 Selection Scene::getSelection(const Selection::Name& name) const {
     std::unique_lock<std::mutex> lock(_selectionsMutex);
     auto found = _selections.find(name);
     if (found == _selections.end()) {
         return Selection();
     } else {
-        return (*found).second;
+        return found->second;
     }
 }
 
-// This function is thread safe
 bool Scene::isSelectionEmpty(const Selection::Name& name) const {
     std::unique_lock<std::mutex> lock(_selectionsMutex);
     auto found = _selections.find(name);
     if (found == _selections.end()) {
         return true;
     } else {
-        return (*found).second.isEmpty();
+        return found->second.isEmpty();
     }
 }
 
 void Scene::resetSelections(const Transaction::SelectionResets& transactions) {
+    std::unique_lock<std::mutex> lock(_selectionsMutex);
     for (auto selection : transactions) {
         auto found = _selections.find(selection.getName());
         if (found == _selections.end()) {
-            _selections.insert(SelectionMap::value_type(selection.getName(), selection));
+            _selections[selection.getName()] = selection;
         } else {
-            (*found).second = selection;
+            found->second = selection;
         }
     }
 }
diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h
index 08fbf33bcd..5f4a209b66 100644
--- a/libraries/render/src/render/Scene.h
+++ b/libraries/render/src/render/Scene.h
@@ -78,9 +78,6 @@ public:
     void merge(Transaction&& transaction);
     void clear();
 
-    // Checkers if there is work to do when processing the transaction
-    bool touchTransactions() const { return !_resetSelections.empty(); }
-
 protected:
 
     using Reset = std::tuple<ItemID, PayloadPointer>;
diff --git a/libraries/render/src/render/Selection.h b/libraries/render/src/render/Selection.h
index 2c7ce710cd..05b2395b42 100644
--- a/libraries/render/src/render/Selection.h
+++ b/libraries/render/src/render/Selection.h
@@ -45,9 +45,8 @@ namespace render {
         Name _name;
         ItemIDs _items;
     };
-    using Selections = std::vector<Selection>;
 
-    using SelectionMap = std::map<const Selection::Name, Selection>;
+    using SelectionMap = std::unordered_map<Selection::Name, Selection>;
 
 }