尝试在react-google-maps上卸载4k +标记时冻结浏览器

时间:2019-03-07 10:14:58

标签: javascript google-maps react-redux google-maps-markers react-google-maps

我正在构建一个React应用,其中许多标记都显示在react-google-maps地图上。用户可以过滤标记,以便不能一次显示所有标记。使用MarkerClusterer显示4000个标记可以正常工作。显示它们需要花费合理的时间,之后地图才响应。

现在,当我尝试在渲染4000之前仅显示一个或几个标记时,就会出现我的问题。浏览器冻结,我再也无法在浏览器中执行任何操作。没有无限循环警告或错误。控制台在冻结之前不会显示任何对我有帮助的东西。

显示地图组件的代码:

import React from 'react';
import { compose, withProps, withHandlers } from "recompose"
import { withScriptjs, withGoogleMap, GoogleMap, TrafficLayer } from "react-google-maps"
import { connect } from 'react-redux';

import MarkersList from './MarkersList';

const { MarkerClusterer } = require("react-google-maps/lib/components/addons/MarkerClusterer");

const Map = compose(
    withProps({
      googleMapURL: "https://maps.googleapis.com/maps/api/js?key=*******&callback=initMap",
      loadingElement: <div style={{ height: `100%` }} />,
      containerElement: <div style={{ height: `100vh` }} />,
      mapElement: <div style={{ height: `100%` }} />
    }),
    withHandlers({
      onMarkerClustererClick: () => (markerClusterer) => {
        const clickedMarkers = markerClusterer.getMarkers()
        console.log(`Current clicked markers length: ${clickedMarkers.length}`)
        console.log(clickedMarkers)
      }
    }),
    withScriptjs,
    withGoogleMap
  )((props) => 
       <GoogleMap
            defaultZoom={5.76}
            defaultCenter={{ lat: 49.4299758, lng: 14.0531568 }}
            mapTypeId="terrain"
            fullscreenControl={false}
            >
              <TrafficLayer autoUpdate />
              <MarkerClusterer
                onClick={props.onMarkerClustererClick}
                averageCenter
                enableRetinalIcons
                gridSize={60}
                >
                  {props.isMarkerShown && <MarkersList/>}
                </MarkerClusterer>
        </GoogleMap>

);

export default connect()(Map);

MarkersList组件:

import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Marker, InfoWindow } from 'react-google-maps';

import { markersActionCreators } from './MarkersActions';

class MarkersList extends React.Component {
    componentDidMount() {
        if(this.props.markers.length === 0) {
            this.props.requestMarkers();
        }
    }

    render() {
        var listComponent = this.props.displayedMarkers.map((marker, index) => 
                <Marker 
                    key={index}
                    position={{lat: marker.currentPositionLat, lng: marker.currentPositionLng}} 
                    onClick={() => this.props.onToggleOpen(index)} 
                    tracksViewChanges={false}
                >
                    {this.props.isOpen && this.props.infoIndex === index &&
                    <InfoWindow onCloseClick={() => this.props.onToggleOpen(index)}>
                        <div>
                            <h6>Truck Id: {marker.vehicleName}</h6>
                            <b>Registration Plate: {marker.registrationNumber}</b>
                            <br/>
                            <p>
                                Position recorded on <i>{marker.time}</i> <br/>
                                Engine is [{marker.currentIgnitionState}] <br/>
                                Fuel Level: {marker.currentFuelLevel} L left <br/>
                                Speed: {marker.currentSpeed} Km/h <br/>
                            </p>

                        </div>
                    </InfoWindow>}
                </Marker>
            );
        return <div>{listComponent}</div>;
    }
};

export default connect(
    state => state.mainArea.markersReducer,
    dispatch => bindActionCreators(markersActionCreators, dispatch)
  )(MarkersList);

我确保在选择某些内容后displayMarkers具有正确的值(在这种情况下,displayMarkers从4000个条目更改为1个)。我逐步浏览了整个应用程序,以确保在发生这种不幸行为时,我计算出的每个值都是正确的。此外,在冻结之前不会再次调用render方法。从4000个显示的标记更改为3999或3980可以正常工作。

为更好地了解该应用程序,我制作了一个CodeSandbox(由于api键和数据丢失,它无法呈现任何内容):https://codesandbox.io/s/v830m9p7ry?fontsize=14&view=editor

我是新来的反应者和还原者,我真的不知道该怎么做,我应该测试或下一步做什么。

在此先感谢您的帮助!

编辑:Added performance analysis。并且 this is displayed after the 30 second mark in the performance analysis。 它正在渲染每个标记,并正在将它们逐个删除。

0 个答案:

没有答案