优化加载
This commit is contained in:
@@ -5,15 +5,18 @@
|
||||
|
||||
let mapInitialized = false;
|
||||
|
||||
async function initMap3D() {
|
||||
async function initMap3D(geoDataPromise = null, threeJSPromise = null) {
|
||||
if (mapInitialized) return;
|
||||
mapInitialized = true;
|
||||
|
||||
const container = document.getElementById("map");
|
||||
if (!container) return;
|
||||
|
||||
// 动态导入 Three.js 模块
|
||||
const threeModule = await import('https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js');
|
||||
// 使用预加载的模块或动态导入
|
||||
const threeModule = threeJSPromise
|
||||
? (await threeJSPromise) ? (await import('https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js')) : null
|
||||
: await import('https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js');
|
||||
|
||||
const THREE = threeModule.default || threeModule;
|
||||
|
||||
const [
|
||||
@@ -22,13 +25,21 @@ async function initMap3D() {
|
||||
{ Line2 },
|
||||
{ LineMaterial },
|
||||
{ LineGeometry }
|
||||
] = await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/controls/OrbitControls.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/renderers/CSS2DRenderer.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/Line2.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineMaterial.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineGeometry.js')
|
||||
]);
|
||||
] = threeJSPromise && (await threeJSPromise)
|
||||
? [
|
||||
await import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/controls/OrbitControls.js'),
|
||||
await import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/renderers/CSS2DRenderer.js'),
|
||||
await import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/Line2.js'),
|
||||
await import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineMaterial.js'),
|
||||
await import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineGeometry.js')
|
||||
]
|
||||
: await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/controls/OrbitControls.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/renderers/CSS2DRenderer.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/Line2.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineMaterial.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineGeometry.js')
|
||||
]);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
|
||||
@@ -353,11 +364,11 @@ async function initMap3D() {
|
||||
map.position.z = map.position.z - center.z - offset[1];
|
||||
};
|
||||
|
||||
// 加载 GeoJSON 数据
|
||||
// 加载 GeoJSON 数据(使用预加载或重新加载)
|
||||
const url = "/assets/100000_full.json";
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
const data = await res.json();
|
||||
const data = geoDataPromise ? await geoDataPromise : await (await fetch(url)).json();
|
||||
if (!data) throw new Error("No data available");
|
||||
const map = createMap(data, 0.05);
|
||||
map.add(createPulseRings(data, 0.05));
|
||||
scene.add(map);
|
||||
@@ -371,14 +382,53 @@ function setupLazyMap() {
|
||||
const mapContainer = document.getElementById("map");
|
||||
if (!mapContainer) return;
|
||||
|
||||
// 预加载 GeoJSON 数据
|
||||
const preloadGeoData = async () => {
|
||||
const url = "/assets/100000_full.json";
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
return await res.json();
|
||||
} catch (err) {
|
||||
console.error("Failed to preload map data:", err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 预加载 Three.js 模块
|
||||
const preloadThreeJS = async () => {
|
||||
try {
|
||||
await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/controls/OrbitControls.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/renderers/CSS2DRenderer.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/Line2.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineMaterial.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/three@latest/examples/jsm/lines/LineGeometry.js')
|
||||
]);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("Failed to preload Three.js:", err);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if ('IntersectionObserver' in window) {
|
||||
let geoDataPromise = null;
|
||||
let threeJSPromise = null;
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
if (entries[0].isIntersecting) {
|
||||
initMap3D();
|
||||
// 开始并行预加载
|
||||
geoDataPromise = preloadGeoData();
|
||||
threeJSPromise = preloadThreeJS();
|
||||
|
||||
// 立即初始化地图
|
||||
initMap3D(geoDataPromise, threeJSPromise);
|
||||
observer.disconnect();
|
||||
}
|
||||
}, {
|
||||
rootMargin: '200px' // 提前 200px 开始加载
|
||||
rootMargin: '1200px', // 提前 800px 开始加载(更早触发)
|
||||
threshold: 0.1 // 10% 可见时即触发
|
||||
});
|
||||
observer.observe(mapContainer);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user