显示:none on Deck.gl React 组件导致巨大的性能问题
Display: none on Deck.gl React component causes huge performance issue
编辑: 此问题特定于此设置。如果您想提供帮助,请使用此处的代码。谢谢!
我正在使用 Deck.gl 和 React 来显示地图。当我尝试使用 display: none 隐藏地图时,它开始冻结我的整个计算机。我已经通过使用 visibility: collapse 来解决这个问题,但我想知道为什么 display: none 会导致这个问题。
控制台开始不断充满警告:
luma: Device pixel ratio clamped context.js:202:84
Error: WebGL warning: clear: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) bundle.min.js line 15214 > eval:32:191695
Error: WebGL warning: drawingBufferWidth: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 15214 > eval:32:60490
Source map error: Error: NetworkError when attempting to fetch resource.
Resource URL: webpack:///./node_modules/@luma.gl/webgl/dist/esm/context/context.js?
Source Map URL: context.js.map
Error: WebGL warning: drawingBufferWidth: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18246x6954 was too large, but resize to 9123x3477 succeeded. bundle.min.js line 15214 > eval:32:60490
我查看了 React 分析器的性能:
React Profiler output
在每次处理时间比正常时间长的提交中,它表明 AutoSizer 需要很长时间来呈现。
重现问题:
节点版本:v10.16.3
- 运行 create-react-app my-app.
- 复制下面的代码。
- 在包含地图的任何元素上应用显示:none,包括由 Deck.gl 呈现的元素。
警告:重现此问题会占用大量资源并可能使您的计算机崩溃!
代码
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import 'mapbox-gl/dist/mapbox-gl.css';
import {GeoMapChart} from './GeoMapChart'
ReactDOM.render(<GeoMapChart />, document.getElementById('root'));
serviceWorker.unregister();
GeoMapChart.tsx
import * as React from 'react';
import DeckGL from '@deck.gl/react';
import {StaticMap} from 'react-map-gl';
export function GeoMapChart() {
const [viewState, setViewState] = React.useState(INITIAL_VIEW_STATE);
return (
<DeckGL viewState={viewState} controller={true} width={'100%'} height={'100%'} layers={[]} onViewStateChange={
({viewState, oldViewState, interactionState}) => {
const newViewState = {...viewState};
setViewState(newViewState);
}}>
<StaticMap width={'100%'} height={'100%'} mapStyle={MAPBOX_BASE_LAYER}/>
</DeckGL>
)
}
const MAX_ZOOM = 19;
const MIN_ZOOM = 2;
const INITIAL_VIEW_STATE = {
latitude: 37.77,
longitude: -122.42,
zoom: 5,
bearing: 0,
pitch: 0,
maxZoom: MAX_ZOOM,
minZoom: MIN_ZOOM
};
const BASEMAP_TILE_SOURCE_NAME = 'simple-tiles';
const BASEMAP_TILE_SERVERS = [
'http://a.tile.osm.org/{z}/{x}/{y}.png',
'http://b.tile.osm.org/{z}/{x}/{y}.png',
'http://c.tile.osm.org/{z}/{x}/{y}.png',
//'//stamen-tiles-a.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
//'//stamen-tiles-b.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
//'//stamen-tiles-c.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
];
const BASEMAP_ATTRIBUTION = `Map tiles by <a href="http://stamen.com">Stamen Design</a>, under
<a href="http://creativecommons.org/licenses/by/3.0"> CC BY 3.0</a>. Data by
<a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">
ODbL</a>.`.replace(/\n/gm, '');
const COMMON_LAYER_CONFIG = {
minZoom: 2,
maxZoom: 17, // New data will be requested until this level
pixelScaleFactor: 8,
tileSize: 256,
isTms: true,
topoLayerClusteringSwithLevel: 13,
maxVisibleRasterLayers: 3,
maxConfigurableLayers: 26,
};
const MAP_CONFIG = {
MIN_ZOOM: 1,
MAX_ZOOM: 18,
INITIAL_ZOOM: 9,
SHOW_TILE_BOUNDARIES: false,
DRAG_ROTATE: false,
ZOOM_NO_DATA: 2,
SEARCH_DEFAULT_ZOOM: 14,
};
const MAPBOX_BASE_LAYER = {
version: 8,
sources: {
[BASEMAP_TILE_SOURCE_NAME]: {
type: 'raster',
tiles: BASEMAP_TILE_SERVERS,
tileSize: COMMON_LAYER_CONFIG.tileSize,
attribution: BASEMAP_ATTRIBUTION,
}
},
layers: [
{
id: BASEMAP_TILE_SOURCE_NAME,
type: 'raster',
source: BASEMAP_TILE_SOURCE_NAME,
minzoom: MAP_CONFIG.MIN_ZOOM,
maxzoom: MAP_CONFIG.MAX_ZOOM,
}
],
};
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Deck.gl performance issue</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
package.json
{
"name": "NOT_PUBLIC",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/lodash": "^4.14.149",
"@types/node": "13.1.8",
"@types/react": "16.8.3",
"@types/react-dom": "16.0.11",
"@types/react-router-dom": "5.1.3",
"axios": "0.19.0",
"deck.gl": "7.3.7",
"jss": "10.0.0-alpha.3",
"lodash": "4.17.15",
"react": "16.8.5",
"react-dom": "16.8.5",
"react-map-gl": "5.1.3",
"react-router-dom": "5.1.2"
},
"scripts": {
"start": "webpack-dev-server --mode development --hot",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@danmarshall/deckgl-typings": "^3.4.3",
"@types/react-map-gl": "^5.0.3",
"@types/uuid": "^3.4.6",
"awesome-typescript-loader": "^5.2.1",
"babel-jest": "^23.6.0",
"css-loader": "^2.1.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-to-json": "^3.3.5",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"jest": "^23.6.0",
"node-sass": "^4.11.0",
"react-scripts": "2.1.2",
"react-test-renderer": "^16.7.0",
"sass-loader": "^7.1.0",
"source-map-loader": "^0.2.4",
"style-loader": "^0.23.1",
"typescript": "3.7.4",
"webpack": "^4.28.1",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
},
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
devServer: {
port: 9012,
historyApiFallback: true,
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader'
},
{
test:/\.css$/,
use:['style-loader','css-loader', 'sass-loader']
},
{
test: /\.scss$/,
use:["css-loader",'sass-loader']
},
{
test: /\.(?:png|jpg|svg)$/,
loader: 'url-loader'
},
{
test: /\.(ico|jpeg|gif|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader'
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: '!!html-loader!./src/index.html'
}),
]
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": false,
"module": "commonjs",
"target": "es6",
"jsx": "react",
// "suppressImplicitAnyIndexErrors": true,
},
"include": [
"./src/**/*"
]
}
我会尽力澄清这里的困惑。也许它回答了你的问题。
您已尝试使用 display: none
设置 div
隐藏,但它使用的内存比 display: block
或将样式设置为 visibility: collapse
时使用的内存多得多.我认为这是问题陈述。
以下是在 html 中隐藏元素的选项:-
- 不透明度:0
- 可见性:隐藏
- 能见度:崩溃
- 显示:none
现在,这些样式的实际作用html如下
- opacity: 0 - 隐藏一个元素,但确实在布局中占据space,可以点击该元素。
- visibility: hidden - 隐藏一个元素,但它 确实 在布局中占据 space,无法点击。
- visibility: collapse - 隐藏元素,但它 确实 占据布局中的 space,无法点击。 (如果元素是 table,它 不会 在布局中占据 space)
- 显示:none - 完全隐藏一个元素,它不占据布局中的任何space,不可能点击。
从这个比较我们可以了解到display: none;
不允许元素占用space,所以clientHeight
和clientWidth
的属性=10=] 将为零。以下只是我的假设。
事实证明,标记为“100%”的宽度和高度可能导致了零。但是库 set/reset 这个高度和宽度更高一些,可能基于一些验证和屏幕高度和屏幕宽度(我不确定,但在我的系统中,它是 8144x4072
而你的似乎是 9123x3477
)。此外,库似乎在渲染过程中缓存 canvas 值。因此,这些计算和缓存在内存和 CPU.
方面可能很昂贵
因此,这些可能(您可以想象存储一个大小为 8144x4072
的数组)导致了内存问题,尤其是当审计正在进行时,RAM 很容易被填满并导致问题。
希望这能让您清楚一些。
将我所有的依赖项升级到最新版本解决了我的问题。
抱歉,我懒得查明是哪个包导致了问题。也许我会在以后的生活中花时间在上面。
同样在 typescript@3.7.5
上需要编译器选项 skipLibCheck: true
。
节点版本 12.16.0
package.json:
{
"name": "NOT_PUBLIC",
"version": "0.1.0",
"private": true,
"dependencies": {
"@eds/vanilla": "3.4.0",
"@types/lodash": "^4.14.149",
"@types/node": "13.7.4",
"@types/react": "16.9.20",
"@types/react-dom": "16.9.5",
"@types/react-redux": "7.1.7",
"@types/react-router-dom": "5.1.3",
"axios": "0.19.2",
"d3": "5.15.0",
"deck.gl": "^8.0.15",
"dragula": "3.7.2",
"immer": "5.3.6",
"jss": "10.0.4",
"lodash": "4.17.15",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-map-gl": "5.2.3",
"react-redux": "7.2.0",
"react-router-dom": "5.1.2",
"redux": "4.0.5",
"redux-thunk": "2.3.0"
},
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@types/react-map-gl": "^5.2.0",
"@types/uuid": "^3.4.7",
"awesome-typescript-loader": "^5.2.1",
"babel-jest": "^25.1.0",
"css-loader": "^3.4.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.4.4",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"jest": "^25.1.0",
"node-sass": "^4.13.1",
"react-scripts": "3.4.0",
"react-test-renderer": "^16.12.0",
"sass-loader": "^8.0.2",
"source-map-loader": "^0.2.4",
"style-loader": "^1.1.3",
"typescript": "3.7.5",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
编辑: 此问题特定于此设置。如果您想提供帮助,请使用此处的代码。谢谢!
我正在使用 Deck.gl 和 React 来显示地图。当我尝试使用 display: none 隐藏地图时,它开始冻结我的整个计算机。我已经通过使用 visibility: collapse 来解决这个问题,但我想知道为什么 display: none 会导致这个问题。
控制台开始不断充满警告:
luma: Device pixel ratio clamped context.js:202:84
Error: WebGL warning: clear: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawElements: Drawing to a destination rect smaller than the viewport rect. (This warning will only be given once) bundle.min.js line 15214 > eval:32:191695
Error: WebGL warning: drawingBufferWidth: Requested size 21535x8218 was too large, but resize to 10767x4109 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20020x7637 was too large, but resize to 10010x3818 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18609x7099 was too large, but resize to 9304x3549 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 15214 > eval:32:60490
Source map error: Error: NetworkError when attempting to fetch resource.
Resource URL: webpack:///./node_modules/@luma.gl/webgl/dist/esm/context/context.js?
Source Map URL: context.js.map
Error: WebGL warning: drawingBufferWidth: Requested size 17297x6598 was too large, but resize to 8648x3299 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21925x8361 was too large, but resize to 10962x4180 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20379x7772 was too large, but resize to 10189x3886 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 18943x7225 was too large, but resize to 9471x3612 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17607x6715 was too large, but resize to 8803x3357 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 22314x8510 was too large, but resize to 11157x4255 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 20743x7911 was too large, but resize to 10371x3955 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19280x7354 was too large, but resize to 9640x3677 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 17925x6834 was too large, but resize to 8962x3417 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 16662x6351 was too large, but resize to 8331x3175 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 21115x8049 was too large, but resize to 10557x4024 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 15214 > eval:32:60490
Error: WebGL warning: drawingBufferWidth: Requested size 19626x7482 was too large, but resize to 9813x3741 succeeded. bundle.min.js line 7141 > eval:201:9
Error: WebGL warning: clear: Requested size 18246x6954 was too large, but resize to 9123x3477 succeeded. bundle.min.js line 15214 > eval:32:60490
我查看了 React 分析器的性能: React Profiler output
在每次处理时间比正常时间长的提交中,它表明 AutoSizer 需要很长时间来呈现。
重现问题:
节点版本:v10.16.3
- 运行 create-react-app my-app.
- 复制下面的代码。
- 在包含地图的任何元素上应用显示:none,包括由 Deck.gl 呈现的元素。
警告:重现此问题会占用大量资源并可能使您的计算机崩溃!
代码
index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
import 'mapbox-gl/dist/mapbox-gl.css';
import {GeoMapChart} from './GeoMapChart'
ReactDOM.render(<GeoMapChart />, document.getElementById('root'));
serviceWorker.unregister();
GeoMapChart.tsx
import * as React from 'react';
import DeckGL from '@deck.gl/react';
import {StaticMap} from 'react-map-gl';
export function GeoMapChart() {
const [viewState, setViewState] = React.useState(INITIAL_VIEW_STATE);
return (
<DeckGL viewState={viewState} controller={true} width={'100%'} height={'100%'} layers={[]} onViewStateChange={
({viewState, oldViewState, interactionState}) => {
const newViewState = {...viewState};
setViewState(newViewState);
}}>
<StaticMap width={'100%'} height={'100%'} mapStyle={MAPBOX_BASE_LAYER}/>
</DeckGL>
)
}
const MAX_ZOOM = 19;
const MIN_ZOOM = 2;
const INITIAL_VIEW_STATE = {
latitude: 37.77,
longitude: -122.42,
zoom: 5,
bearing: 0,
pitch: 0,
maxZoom: MAX_ZOOM,
minZoom: MIN_ZOOM
};
const BASEMAP_TILE_SOURCE_NAME = 'simple-tiles';
const BASEMAP_TILE_SERVERS = [
'http://a.tile.osm.org/{z}/{x}/{y}.png',
'http://b.tile.osm.org/{z}/{x}/{y}.png',
'http://c.tile.osm.org/{z}/{x}/{y}.png',
//'//stamen-tiles-a.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
//'//stamen-tiles-b.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
//'//stamen-tiles-c.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg',
];
const BASEMAP_ATTRIBUTION = `Map tiles by <a href="http://stamen.com">Stamen Design</a>, under
<a href="http://creativecommons.org/licenses/by/3.0"> CC BY 3.0</a>. Data by
<a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">
ODbL</a>.`.replace(/\n/gm, '');
const COMMON_LAYER_CONFIG = {
minZoom: 2,
maxZoom: 17, // New data will be requested until this level
pixelScaleFactor: 8,
tileSize: 256,
isTms: true,
topoLayerClusteringSwithLevel: 13,
maxVisibleRasterLayers: 3,
maxConfigurableLayers: 26,
};
const MAP_CONFIG = {
MIN_ZOOM: 1,
MAX_ZOOM: 18,
INITIAL_ZOOM: 9,
SHOW_TILE_BOUNDARIES: false,
DRAG_ROTATE: false,
ZOOM_NO_DATA: 2,
SEARCH_DEFAULT_ZOOM: 14,
};
const MAPBOX_BASE_LAYER = {
version: 8,
sources: {
[BASEMAP_TILE_SOURCE_NAME]: {
type: 'raster',
tiles: BASEMAP_TILE_SERVERS,
tileSize: COMMON_LAYER_CONFIG.tileSize,
attribution: BASEMAP_ATTRIBUTION,
}
},
layers: [
{
id: BASEMAP_TILE_SOURCE_NAME,
type: 'raster',
source: BASEMAP_TILE_SOURCE_NAME,
minzoom: MAP_CONFIG.MIN_ZOOM,
maxzoom: MAP_CONFIG.MAX_ZOOM,
}
],
};
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Deck.gl performance issue</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
package.json
{
"name": "NOT_PUBLIC",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/lodash": "^4.14.149",
"@types/node": "13.1.8",
"@types/react": "16.8.3",
"@types/react-dom": "16.0.11",
"@types/react-router-dom": "5.1.3",
"axios": "0.19.0",
"deck.gl": "7.3.7",
"jss": "10.0.0-alpha.3",
"lodash": "4.17.15",
"react": "16.8.5",
"react-dom": "16.8.5",
"react-map-gl": "5.1.3",
"react-router-dom": "5.1.2"
},
"scripts": {
"start": "webpack-dev-server --mode development --hot",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@danmarshall/deckgl-typings": "^3.4.3",
"@types/react-map-gl": "^5.0.3",
"@types/uuid": "^3.4.6",
"awesome-typescript-loader": "^5.2.1",
"babel-jest": "^23.6.0",
"css-loader": "^2.1.0",
"enzyme": "^3.8.0",
"enzyme-adapter-react-16": "^1.7.1",
"enzyme-to-json": "^3.3.5",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"jest": "^23.6.0",
"node-sass": "^4.11.0",
"react-scripts": "2.1.2",
"react-test-renderer": "^16.7.0",
"sass-loader": "^7.1.0",
"source-map-loader": "^0.2.4",
"style-loader": "^0.23.1",
"typescript": "3.7.4",
"webpack": "^4.28.1",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"
},
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
devServer: {
port: 9012,
historyApiFallback: true,
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader'
},
{
test:/\.css$/,
use:['style-loader','css-loader', 'sass-loader']
},
{
test: /\.scss$/,
use:["css-loader",'sass-loader']
},
{
test: /\.(?:png|jpg|svg)$/,
loader: 'url-loader'
},
{
test: /\.(ico|jpeg|gif|eot|otf|webp|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader'
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: '!!html-loader!./src/index.html'
}),
]
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": false,
"module": "commonjs",
"target": "es6",
"jsx": "react",
// "suppressImplicitAnyIndexErrors": true,
},
"include": [
"./src/**/*"
]
}
我会尽力澄清这里的困惑。也许它回答了你的问题。
您已尝试使用 display: none
设置 div
隐藏,但它使用的内存比 display: block
或将样式设置为 visibility: collapse
时使用的内存多得多.我认为这是问题陈述。
以下是在 html 中隐藏元素的选项:-
- 不透明度:0
- 可见性:隐藏
- 能见度:崩溃
- 显示:none
现在,这些样式的实际作用html如下
- opacity: 0 - 隐藏一个元素,但确实在布局中占据space,可以点击该元素。
- visibility: hidden - 隐藏一个元素,但它 确实 在布局中占据 space,无法点击。
- visibility: collapse - 隐藏元素,但它 确实 占据布局中的 space,无法点击。 (如果元素是 table,它 不会 在布局中占据 space)
- 显示:none - 完全隐藏一个元素,它不占据布局中的任何space,不可能点击。
从这个比较我们可以了解到display: none;
不允许元素占用space,所以clientHeight
和clientWidth
的属性=10=] 将为零。以下只是我的假设。
事实证明,标记为“100%”的宽度和高度可能导致了零。但是库 set/reset 这个高度和宽度更高一些,可能基于一些验证和屏幕高度和屏幕宽度(我不确定,但在我的系统中,它是 8144x4072
而你的似乎是 9123x3477
)。此外,库似乎在渲染过程中缓存 canvas 值。因此,这些计算和缓存在内存和 CPU.
因此,这些可能(您可以想象存储一个大小为 8144x4072
的数组)导致了内存问题,尤其是当审计正在进行时,RAM 很容易被填满并导致问题。
希望这能让您清楚一些。
将我所有的依赖项升级到最新版本解决了我的问题。
抱歉,我懒得查明是哪个包导致了问题。也许我会在以后的生活中花时间在上面。
同样在 typescript@3.7.5
上需要编译器选项 skipLibCheck: true
。
节点版本 12.16.0
package.json:
{
"name": "NOT_PUBLIC",
"version": "0.1.0",
"private": true,
"dependencies": {
"@eds/vanilla": "3.4.0",
"@types/lodash": "^4.14.149",
"@types/node": "13.7.4",
"@types/react": "16.9.20",
"@types/react-dom": "16.9.5",
"@types/react-redux": "7.1.7",
"@types/react-router-dom": "5.1.3",
"axios": "0.19.2",
"d3": "5.15.0",
"deck.gl": "^8.0.15",
"dragula": "3.7.2",
"immer": "5.3.6",
"jss": "10.0.4",
"lodash": "4.17.15",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-map-gl": "5.2.3",
"react-redux": "7.2.0",
"react-router-dom": "5.1.2",
"redux": "4.0.5",
"redux-thunk": "2.3.0"
},
"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"@types/react-map-gl": "^5.2.0",
"@types/uuid": "^3.4.7",
"awesome-typescript-loader": "^5.2.1",
"babel-jest": "^25.1.0",
"css-loader": "^3.4.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"enzyme-to-json": "^3.4.4",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"jest": "^25.1.0",
"node-sass": "^4.13.1",
"react-scripts": "3.4.0",
"react-test-renderer": "^16.12.0",
"sass-loader": "^8.0.2",
"source-map-loader": "^0.2.4",
"style-loader": "^1.1.3",
"typescript": "3.7.5",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}