Repository: napari/napari

Issue:
Dimension slider is very slow with points layer
## 🐛 Bug

Since 0.4.17rc2 the dimension slider is slow if points layers are added to the viewer. It used to be very smooth in 0.4.16.

https://user-images.githubusercontent.com/40591297/191882100-cc139050-8e58-4e7b-8c18-884b34377809.mp4


## To Reproduce

Steps to reproduce the behavior:

1. Run following lines.

```python
import napari
viewer = napari.Viewer()
viewer.add_image(np.random.random((100, 100, 100)))
viewer.add_points(np.random.random((300, 3))*100)
```
2. Grab and move dimension slider.

<!-- If you have a code sample, error messages, stack traces, please provide it here as well -->

## Expected behavior

Slider should move smoothly.

## Environment

 - Please copy and paste the information at napari info option in help menubar here:

```
napari: 0.4.17rc2
Platform: Windows-10-10.0.22621-SP0
Python: 3.9.7 | packaged by conda-forge | (default, Sep 29 2021, 19:20:16) [MSC v.1916 64 bit (AMD64)]
Qt: 5.15.2
PyQt5: 5.15.6
NumPy: 1.23.2
SciPy: 1.9.1
Dask: 2022.9.0
VisPy: 0.11.0
magicgui: 0.5.1
superqt: 0.3.2
in-n-out: 0.1.5
app-model: 0.0.9
npe2: 0.6.1

OpenGL:
- GL version: 4.6.0 - Build 27.20.100.9621
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 1368x912, scale 2.0

```

 - Any other relevant information:

## Additional context

<!-- Add any other context about the problem here. -->



Discussion:
Hello. Could you provide information what GPU did you use? It is dedicated card from Nvidia or ATI or integrated in the procesor?
Intel(R) Iris(R) Plus Graphics (integrated one in Surface pro7)
Thanks for the report @hanjinliu. I found a similar performance issue, though it occurs when adding and moving points.

Downgrading vispy to 0.10 is the only thing I found that fixes the issue for me, but I believe that will cause other problems with napari.

I also have integrated Intel Iris Plus Graphics (1536 MB), though on a macbook pro. For completeness, here's my napari info.

```
napari: 0.4.17rc2
Platform: macOS-10.16-x86_64-i386-64bit
System: MacOS 12.5
Python: 3.9.13 (main, Aug 25 2022, 18:29:29) [Clang 12.0.0 ]
Qt: 5.15.2
PyQt5: 5.15.7
NumPy: 1.23.3
SciPy: 1.9.1
Dask: 2022.9.1
VisPy: 0.11.0
magicgui: 0.5.1
superqt: 0.3.5
in-n-out: 0.1.5
app-model: 0.0.9
npe2: 0.6.1

OpenGL:
- GL version: 2.1 INTEL-18.8.4
- MAX_TEXTURE_SIZE: 16384

Screens:
- screen 1: resolution 1920x1080, scale 1.0
```

Resolving patch:
diff --git a/examples/clipping_planes_interactive_.py b/examples/clipping_planes_interactive_.py
--- a/examples/clipping_planes_interactive_.py
+++ b/examples/clipping_planes_interactive_.py
@@ -118,7 +118,8 @@ def shift_plane_along_normal(viewer, event):
     plane_position_data_vispy = np.array(volume_layer.experimental_clipping_planes[0].position)[[2, 1, 0]]
 
     # Get transform which maps from data (vispy) to canvas
-    visual2canvas = viewer.window.qt_viewer.layer_to_visual[volume_layer].node.get_transform(
+    # note that we're using a private attribute here, which may not be present in future napari versions
+    visual2canvas = viewer.window._qt_viewer.layer_to_visual[volume_layer].node.get_transform(
         map_from="visual", map_to="canvas"
     )
 
diff --git a/napari/_vispy/layers/base.py b/napari/_vispy/layers/base.py
--- a/napari/_vispy/layers/base.py
+++ b/napari/_vispy/layers/base.py
@@ -154,11 +154,15 @@ def _on_matrix_change(self):
         self._master_transform.matrix = affine_matrix
 
     def _on_experimental_clipping_planes_change(self):
-        if hasattr(self.node, 'clipping_planes'):
-            self.node.clipping_planes = (
-                # invert axes because vispy uses xyz but napari zyx
-                self.layer.experimental_clipping_planes.as_array()[..., ::-1]
-            )
+        # TODO: this check is only necessary until vispy #2383 comes to napari
+        if hasattr(self.node, 'clipping_planes') and hasattr(
+            self.layer, 'experimental_clipping_planes'
+        ):
+            prev = self.node.clipping_planes
+            # invert axes because vispy uses xyz but napari zyx
+            new = self.layer.experimental_clipping_planes.as_array()[..., ::-1]
+            if not np.array_equal(prev, new):
+                self.node.clipping_planes = new
 
     def reset(self):
         self._on_visible_change()


Test patch: