can*_*his 12 javascript performance svg d3.js leaflet
我正在用传单和d3创建一个地图.很多圆圈都会在地图上绘制出来.在浏览器兼容性方面,预计会限制浏览器可以呈现多少svg元素.然而,就用户体验而言,我希望用户可以在地图上看到尽可能多的元素(否则用户可能需要不断地放大和缩小,并且需要等待ajax返回数据).我需要考虑一些优化(用户等待时间用户与服务器查询负载与浏览器可以处理的内容相比).
请参见图,现在对服务器返回的点数有一个限制,因此只填充了一部分地图.
浏览器无法在此处理完全填充的映射,用户也需要等待太长时间才能响应服务器响应.
我想通过回答两个问题需要解决我面临的问题:
我正在考虑以下几点,但我不确定它是否会有所帮助;
虽然在开始看到明显的减速(取决于大小,使用渐变填充等)之前,您只能渲染~2-5k SVG元素,但您可以在客户端存储和操作更大的数据集.您通常可以在SVG中有效地处理数十或数十万个数据点:诀窍是对实际渲染的内容非常有选择性,并且只在必要时使用debouncing等技术重绘.
(对于非常大的数据集:是的,您需要聚合/子采样点或预渲染.)
考虑到这一点,我特别用于d3地图的一种技术是用于d3.geom.quadtree()
在用户平移/缩放时动态剔除点.更具体地说,我避免绘制要点
在JS-ish伪代码中,这看起来大致如下:
function getIndicesToDraw(data, r, bbox) {
var indicesToDraw = [];
var Q = d3.geom.quadtree();
// set bounds in pixel space
for (var i = 0; i < data.length; i++) {
var d = data[i];
var p = getPointForDatum(d);
if (isInsideBoundingBox(bbox, p) && !hasPointWithinRadius(Q, r, p)) {
Q.add(p);
indicesToDraw.push(i);
}
}
return indicesToDraw;
}
function redraw(svg, data, r, bbox) {
var indicesToDraw = getIndicesToDraw(data, r, bbox);
var points = svg.selectAll('.data-point')
.data(indicesToDraw, function(i) { return i; });
// draw new points for points.enter()
points.exit().remove();
// update positions of points (or SVG transforms, etc.)
}
Run Code Online (Sandbox Code Playgroud)