react-native-map-clustering:慢 UI 选择更改时呈现/转换

react-native-map-clustering: Slow UI render / transition on selection change

在呈现清单时,我对我的应用程序中的当前问题有点迷茫。 react-devtools 未显示任何性能问题,但是当从列表中选择 Google 地图项时,UI 上会出现可见的延迟/某种褪色渲染。这是两个不同速度(x1.0 和 x0.3)的动画截图:

Issue @ 1.0

Issue @ 0.3

react-devtools 显示此用于呈现已更改的选择:

Changed selection rendering

这用于呈现我在当前版本中添加的 FAB 组件:

Provider and FAB rendering

这也是我之前版本没有出现这个问题的主要区别。在我当前的版本中,我使用 react-native-papers FABFAB.Group 组件:

...
<Portal>
  <FAB.Group
    style={{ paddingBottom }}
    open={open}
    onStateChange={onStateChange}
    icon={icon}
    visible={visible}
    actions={actions}
  />
</Portal>
...
$ react-native info

System:
    OS: macOS 11.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 869.95 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.20.1 - ~/.nvm/versions/node/v12.20.1/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 6.14.10 - ~/.nvm/versions/node/v12.20.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.0 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.3, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK:
      API Levels: 28, 29, 30
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.0
      System Images: android-28 | Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom_64, android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7042882
    Xcode: 12.3/12C33 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_261 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1 
    react-native: 0.63.3 => 0.63.3 
  npmGlobalPackages:
    *react-native*: Not Found

package.json

{
  ...
  "dependencies": {
    "@invertase/react-native-apple-authentication": "^2.1.0",
    "@ptomasroos/react-native-multi-slider": "^2.2.2",
    "@react-native-community/async-storage": "^1.12.1",
    "@react-native-community/datetimepicker": "^3.0.6",
    "@react-native-community/geolocation": "^2.0.2",
    "@react-native-community/google-signin": "^5.0.0",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-native-community/push-notification-ios": "^1.8.0",
    "@react-native-community/slider": "^3.0.3",
    "@react-native-firebase/analytics": "^8.0.1",
    "@react-native-firebase/app": "9.0.0",
    "@react-native-firebase/auth": "^9.3.5",
    "@react-native-firebase/crashlytics": "^8.5.2",
    "@react-native-firebase/messaging": "^8.0.1",
    "@react-native-firebase/perf": "^7.4.12",
    "@react-native-picker/picker": "^1.9.2",
    "@react-navigation/material-bottom-tabs": "^5.3.12",
    "@react-navigation/material-top-tabs": "^5.3.12",
    "@react-navigation/native": "^5.9.1",
    "@react-navigation/stack": "^5.14.0",
    "@reduxjs/toolkit": "^1.4.0",
    "@welldone-software/why-did-you-render": "^6.0.0-rc.1",
    "axios": "^0.21.0",
    "babel-plugin-wildcard": "^6.0.0",
    "color": "^3.1.3",
    "date-fns": "^2.16.1",
    "deepmerge": "^4.2.2",
    "equentry-frontend-shared": "2.15.1",
    "expo-local-authentication": "^9.5.0",
    "i18next": "^19.8.3",
    "lodash": "^4.17.20",
    "metro-config": "^0.64.0",
    "react": "17.0.1",
    "react-i18next": "^11.7.3",
    "react-native": "0.63.3",
    "react-native-device-info": "^8.0.0",
    "react-native-fbsdk": "^3.0.0",
    "react-native-gesture-handler": "^1.8.0",
    "react-native-get-random-values": "^1.5.1",
    "react-native-localize": "^2.0.0",
    "react-native-map-clustering": "^3.4.2",
    "react-native-map-link": "^2.7.20",
    "react-native-maps": "^0.27.1",
    "react-native-navigation-bar-color": "^2.0.1",
    "react-native-paper": "^4.7.0",
    "react-native-push-notification": "^7.0.0",
    "react-native-reanimated": "^1.13.1",
    "react-native-safe-area-context": "^3.1.9",
    "react-native-screens": "^2.15.2",
    "react-native-splash-screen": "^3.2.0",
    "react-native-svg": "^12.1.0",
    "react-native-swipe-gestures": "^1.0.5",
    "react-native-tab-view": "^2.15.2",
    "react-native-unimodules": "^0.12.0",
    "react-native-vector-icons": "^7.1.0",
    "react-redux": "^7.2.2",
    "redux": "^4.0.5",
    "redux-persist": "^6.0.0",
    "redux-saga": "^1.1.3",
    "reselect": "^4.0.0",
    "uuid": "^8.3.2"
  }
}

非常感谢任何帮助/提示! :) 干杯!

更新: 实际上问题在于,如果您的集群地图是使用 animationEnabled 道具 here, any following UI change is animated on iOS, see here.

启用动画的

我现在恢复了原来的更改(见下文)并简单地将 animationEnabled 属性设置为 false。

初步回答:

好吧,找到了(我的错 :))正如您从附加的 package.json 文件中看到的,我正在使用 react-native-mapsreact-navigation。由于渲染地图的屏幕未被 react-navigation 关闭,当导航到屏幕截图中显示的设置并更改设置会影响渲染哪个地图时,更改设置和以下对 redux 存储的更新会触发我的挂钩地图组件,从而重新呈现屏幕并减慢应用程序的速度。

我现在通过使用 react-navigation 事件侦听器并在失去焦点时卸载地图屏幕来解决这个问题。

const navigation = useNavigation();
const [focused, setFocused] = useState(false);

useEffect(() => {
  const u1 = navigation.addListener('focus', () => {
    setFocused(true);
  });

  const u2 = navigation.addListener('blur', () => {
    setFocused(false);
  });

  return () => {
    u1();
    u2();
  }
}, [navigation])

return focused ? <Map /> : null;

但是我仍然想知道为什么 react-devtools 不显示我的地图组件的这种行为。我错过了什么吗?任何提示表示赞赏! :)