{"id":4076,"date":"2026-08-10T09:30:39","date_gmt":"2026-08-10T01:30:39","guid":{"rendered":"https:\/\/www.gaigaiming.com\/?p=4076"},"modified":"2026-08-10T09:53:20","modified_gmt":"2026-08-10T01:53:20","slug":"3d%e5%a4%a7%e5%b1%8f%e6%80%a7%e8%83%bd%e4%bc%98%e5%8c%96%ef%bc%8c%e9%87%8d%e8%bd%bd%e5%92%8c%e5%86%85%e5%ad%98%e7%9b%91%e6%8e%a7","status":"publish","type":"post","link":"https:\/\/www.gaigaiming.com\/index.php\/2026\/08\/10\/3d%e5%a4%a7%e5%b1%8f%e6%80%a7%e8%83%bd%e4%bc%98%e5%8c%96%ef%bc%8c%e9%87%8d%e8%bd%bd%e5%92%8c%e5%86%85%e5%ad%98%e7%9b%91%e6%8e%a7\/","title":{"rendered":"3D\u5927\u5c4f\u6027\u80fd\u4f18\u5316\uff0c\u91cd\u8f7d\u548c\u5185\u5b58\u76d1\u63a7"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\u6709\u4e00\u4e2a\u9700\u6c42\u662f\u6279\u91cf\u751f\u6210\u4eff\u771f\u6570\u636e\u57283D\u5730\u56fe\u4e0a\u9762\uff0c\u6bcf\u6761\u68c0\u6d4b\u7ebf\u4f30\u8ba140\u53f0\u8f66\u5728\u5faa\u73af\u4e0d\u505c\u7684\u884c\u9a76\uff0c\u4e2d\u95f4\u4f1a\u6709\u7ebf\u8def\u4e24\u4fa7\u7684\u6444\u50cf\u5934\u544a\u8b66\uff0c\u548c\u4e0d\u540c\u901f\u5ea6\u7684\u8f66\u8f86\u5373\u5c06\u78b0\u649e\u7684\u544a\u8b66\u3002\u6570\u636e\u91cf\u5927\u7684\u8bdd\u4f1a\u51fa\u73b0\u5361\u987f\u73b0\u8c61\u3002\uff08\u5728\u7535\u8111\u5927\u5c4f\u6d4b\u8bd5\u6ca1\u95ee\u9898\uff0c\u5728\u98ce\u63a7\u673a\u4f1a\u51fa\u73b0\u5361\u987f\uff09<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u6211\u6574\u7406\u4e86\u4ee5\u4e0b\u51e0\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u56e0\u4e3a3D\u56ed\u533a\u5730\u56fe\u9875\u9762\u662f\u901a\u8fc7ifrme\u5f15\u5165\u7684\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1\u3001\u515c\u5e95\u65b9\u6848\u6bcf\u5929\u56fa\u5b9a\u65f6\u95f4\u8fdb\u884c\u91cd\u8f7d\uff0c\u901a\u8fc7\u4e00\u4e2a\u8bbe\u7f6e\u5f39\u7a97\uff0c\u91cc\u9762\u670924\u4e2a\u5c0f\u65f6\uff0c\u5982\u679c\u76f8\u5173\u4eba\u5458\u4e0a\u73ed\u7684\u65f6\u5019\u53ef\u4ee5\u8bbe\u7f6e\u51e0\u4e2a\u65f6\u95f4\u70b9\u8fdb\u884c\u624b\u52a8\u91cd\u8f7d\uff1b\u5982\u679c\u662f\u7b80\u5355\u7684\u53ef\u4ee5\u5185\u7f6e\u4ee3\u7801\u91cd\u7f6e\u6bcf\u5929\u51cc\u6668\u8fdb\u884c\u91cd\u8f7d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2\u3001\u76d1\u542c\u5185\u5b58\uff0c\u8fdb\u884c\u8fb9\u754c\u9884\u8b66\uff0c\u901a\u8fc7performance.memory\u76d1\u542c\u4f7f\u7528\u5185\u5b58\u548c\u603b\u5185\u5b58\uff0c\u8fdb\u884c\u5b9a\u65f6\u5668\u95f4\u9694\u5bf9\u6bd4\uff08\u6570\u636e\u5bc6\u96c6\u578b15s\uff0c\u666e\u901a\u5927\u5c4f60s\uff09<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3\u3001\u5176\u4ed6\u56fe\u7247\u5927\u5c0f\u548c\u63a5\u53e3\u6b21\u6570\u8c03\u7528\u7b49\uff0c\u9650\u5236\u91cd\u8f7d\u6b21\u6570\u548c\u7528\u6237\u53cb\u597d\u63d0\u793a\u7b49<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e3b\u9875\u9762\u4ee3\u7801<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ ============ \u653e\u5728\u7ec4\u4ef6\u9876\u90e8\uff0c\u66ff\u6362\u539f\u6709\u914d\u7f6e ============\n\n\/\/ \u5185\u5b58\u914d\u7f6e\nconst MEMORY_CONFIG = {\n  \/\/ \u4e3b\u9875\u9762\u9608\u503c\n  MAIN: {\n    RELOAD_THRESHOLD: 6 * 1024 * 1024 * 1024,    \/\/ 6GB \u89e6\u53d1\u91cd\u8f7d\n    EMERGENCY_THRESHOLD: 7.5 * 1024 * 1024 * 1024, \/\/ 7.5GB \u7d27\u6025\u91cd\u8f7d\n    RATIO_THRESHOLD: 0.70,                         \/\/ 70%\u5360\u6bd4\u89e6\u53d1\n  },\n  \/\/ iframe\u9608\u503c\uff083D\u573a\u666f\u901a\u5e38\u5185\u5b58\u5360\u7528\u5927\uff09\n  IFRAME: {\n    RELOAD_THRESHOLD: 2.5 * 1024 * 1024 * 1024,   \/\/ 2.5GB \u89e6\u53d1iframe\u91cd\u8f7d\n    EMERGENCY_THRESHOLD: 3.5 * 1024 * 1024 * 1024, \/\/ 3.5GB \u7d27\u6025\u91cd\u8f7d\n  },\n  \/\/ \u5168\u5c40\u914d\u7f6e\n  CHECK_INTERVAL: 8000,      \/\/ 8\u79d2\u68c0\u67e5\u4e00\u6b21\uff08\u907f\u514d\u9891\u7e41\u68c0\u67e5\u5f71\u54cd\u6027\u80fd\uff09\n  COOLDOWN: 180000,          \/\/ 3\u5206\u949f\u51b7\u5374\n  MAX_RELOAD: 3,             \/\/ \u6700\u5927\u91cd\u8f7d\u6b21\u6570\n  IFRAME_RELOAD_INTERVAL: 3600000, \/\/ iframe\u6bcf\u5c0f\u65f6\u91cd\u8f7d\u4e00\u6b21\uff08\u9632\u6b62WebGL\u6cc4\u6f0f\uff09\n};\n\n\/\/ \u72b6\u6001\u7ba1\u7406\nlet memoryCheckTimer: number | null = null;\nlet lastReloadTime = 0;\nlet reloadCount = 0;\nlet isReloading = false;\nlet iframeMemoryData = {\n  usedHeap: 0,\n  totalHeap: 0,\n  lastUpdate: 0\n};\n\n\/\/ ============ \u5185\u5b58\u76d1\u63a7\u4e3b\u51fd\u6570 ============\nfunction startMemoryMonitor() {\n  stopMemoryMonitor();\n  \n  \/\/ \u68c0\u67e5\u4e3b\u9875\u9762\u5185\u5b58API\n  if (!window.performance || !(window.performance as any).memory) {\n    console.warn('\u26a0\ufe0f \u4e3b\u9875\u9762\u4e0d\u652f\u6301 performance.memory API\uff0c\u4f7f\u7528\u964d\u7ea7\u7b56\u7565');\n    startFallbackMonitor();\n    return;\n  }\n\n  console.log('\u2705 \u5185\u5b58\u76d1\u63a7\u5df2\u542f\u52a8', {\n    \u4e3b\u9875\u9608\u503c: `${(MEMORY_CONFIG.MAIN.RELOAD_THRESHOLD \/ 1024 \/ 1024 \/ 1024).toFixed(1)}GB`,\n    iframe\u9608\u503c: `${(MEMORY_CONFIG.IFRAME.RELOAD_THRESHOLD \/ 1024 \/ 1024 \/ 1024).toFixed(1)}GB`,\n    \u68c0\u67e5\u95f4\u9694: `${MEMORY_CONFIG.CHECK_INTERVAL \/ 1000}\u79d2`\n  });\n  \n  \/\/ \u76d1\u542ciframe\u6d88\u606f\n  window.addEventListener('message', handleIframeMemoryMessage);\n  \n  \/\/ \u7acb\u5373\u68c0\u67e5\u4e00\u6b21\n  checkMemoryAndReload();\n  \n  \/\/ \u5b9a\u65f6\u68c0\u67e5\n  memoryCheckTimer = window.setInterval(() =&gt; {\n    checkMemoryAndReload();\n  }, MEMORY_CONFIG.CHECK_INTERVAL);\n}\n\n\/\/ ============ \u5904\u7406iframe\u5185\u5b58\u6d88\u606f ============\nfunction handleIframeMemoryMessage(event: MessageEvent) {\n  try {\n    const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;\n    \n    \/\/ \u53ea\u5904\u7406\u5185\u5b58\u6570\u636e\u6d88\u606f\n    if (data &amp;&amp; data.type === 'iframe_memory') {\n      iframeMemoryData.usedHeap = data.usedHeapSize || 0;\n      iframeMemoryData.totalHeap = data.totalHeapSize || 0;\n      iframeMemoryData.lastUpdate = Date.now();\n      \n      \/\/ \u68c0\u67e5iframe\u5185\u5b58\u662f\u5426\u8d85\u9650\n      checkIframeMemory();\n    }\n  } catch (error) {\n    \/\/ \u5ffd\u7565\u975eJSON\u6d88\u606f\n  }\n}\n\n\/\/ ============ \u68c0\u67e5iframe\u5185\u5b58 ============\nfunction checkIframeMemory() {\n  if (isReloading) return;\n  \n  const usedGB = iframeMemoryData.usedHeap \/ 1024 \/ 1024 \/ 1024;\n  \n  \/\/ iframe\u5185\u5b58\u8d85\u8fc7\u7d27\u6025\u9608\u503c\n  if (iframeMemoryData.usedHeap &gt; MEMORY_CONFIG.IFRAME.EMERGENCY_THRESHOLD) {\n    console.error(`\ud83d\udea8 iframe\u5185\u5b58\u7d27\u6025: ${usedGB.toFixed(2)}GB\uff0c\u7acb\u5373\u91cd\u8f7diframe`);\n    reloadIframeOnly('emergency');\n    return;\n  }\n  \n  \/\/ iframe\u5185\u5b58\u8d85\u8fc7\u91cd\u8f7d\u9608\u503c\n  if (iframeMemoryData.usedHeap &gt; MEMORY_CONFIG.IFRAME.RELOAD_THRESHOLD) {\n    console.warn(`\u26a0\ufe0f iframe\u5185\u5b58\u8fc7\u9ad8: ${usedGB.toFixed(2)}GB\uff0c\u51c6\u5907\u91cd\u8f7diframe`);\n    reloadIframeOnly('threshold');\n  }\n}\n\n\/\/ ============ \u6838\u5fc3\u68c0\u67e5\u51fd\u6570\uff08\u4e3b\u9875\u9762\uff09 ============\nfunction checkMemoryAndReload() {\n  if (isReloading) return;\n  \n  try {\n    const memory = (window.performance as any).memory;\n    \n    \/\/ \u4e3b\u9875\u9762\u5185\u5b58\n    const mainUsed = memory.usedJSHeapSize;\n    const mainTotal = memory.jsHeapSizeLimit;\n    const mainRatio = mainUsed \/ mainTotal;\n    \n    \/\/ \u603b\u5185\u5b58 = \u4e3b\u9875\u9762 + iframe\n    const totalUsed = mainUsed + (iframeMemoryData.usedHeap || 0);\n    const totalGB = (totalUsed \/ 1024 \/ 1024 \/ 1024).toFixed(2);\n    const mainGB = (mainUsed \/ 1024 \/ 1024 \/ 1024).toFixed(2);\n    const iframeGB = ((iframeMemoryData.usedHeap || 0) \/ 1024 \/ 1024 \/ 1024).toFixed(2);\n    \n    \/\/ \u6253\u5370\u5185\u5b58\u72b6\u6001\uff08\u964d\u4f4e\u9891\u7387\uff0c\u53ea\u5728\u53d8\u5316\u5927\u65f6\u6253\u5370\uff09\n    if (Math.random() &lt; 0.1) { \/\/ 10%\u6982\u7387\u6253\u5370\uff0c\u51cf\u5c11\u65e5\u5fd7\n      console.log(`\ud83d\udcca \u5185\u5b58: \u4e3b\u9875=${mainGB}GB, iframe=${iframeGB}GB, \u603b\u8ba1=${totalGB}GB`);\n    }\n    \n    \/\/ ===== \u5206\u7ea7\u9884\u8b66 =====\n    \n    \/\/ 1. \u7d27\u6025\u9608\u503c - \u7acb\u5373\u91cd\u8f7d\u6574\u4e2a\u9875\u9762\n    if (mainUsed &gt; MEMORY_CONFIG.MAIN.EMERGENCY_THRESHOLD || \n        totalUsed &gt; (MEMORY_CONFIG.MAIN.EMERGENCY_THRESHOLD + MEMORY_CONFIG.IFRAME.EMERGENCY_THRESHOLD)) {\n      console.error(`\ud83d\udea8 \u7d27\u6025\u5185\u5b58\u8d85\u9650: ${totalGB}GB\uff0c\u7acb\u5373\u5168\u9875\u91cd\u8f7d\uff01`);\n      triggerFullReload('emergency');\n      return;\n    }\n    \n    \/\/ 2. \u4e3b\u9875\u9762\u5360\u6bd4\u9608\u503c\n    if (mainRatio &gt; MEMORY_CONFIG.MAIN.RATIO_THRESHOLD) {\n      console.warn(`\u26a0\ufe0f \u4e3b\u9875\u9762\u5185\u5b58\u5360\u6bd4\u8fc7\u9ad8: ${(mainRatio * 100).toFixed(1)}%`);\n      \n      \/\/ \u68c0\u67e5\u51b7\u5374\n      const now = Date.now();\n      if (now - lastReloadTime &lt; MEMORY_CONFIG.COOLDOWN) {\n        console.log(`\u23f3 \u51b7\u5374\u4e2d\uff0c\u5c1d\u8bd5\u6e05\u7406\u5185\u5b58`);\n        attemptMemoryCleanup();\n        return;\n      }\n      \n      if (reloadCount &gt;= MEMORY_CONFIG.MAX_RELOAD) {\n        console.error(`\ud83d\udeab \u8fbe\u5230\u6700\u5927\u91cd\u8f7d\u6b21\u6570\uff0c\u53d1\u9001\u544a\u8b66`);\n        sendAdminAlert('main_memory_high');\n        return;\n      }\n      \n      triggerFullReload('threshold');\n      return;\n    }\n    \n    \/\/ 3. \u4e3b\u9875\u9762\u7edd\u5bf9\u9608\u503c\n    if (mainUsed &gt; MEMORY_CONFIG.MAIN.RELOAD_THRESHOLD) {\n      console.warn(`\u26a0\ufe0f \u4e3b\u9875\u9762\u5185\u5b58\u8d85\u8fc7\u9608\u503c: ${mainGB}GB`);\n      \n      const now = Date.now();\n      if (now - lastReloadTime &lt; MEMORY_CONFIG.COOLDOWN) {\n        attemptMemoryCleanup();\n        return;\n      }\n      \n      if (reloadCount &gt;= MEMORY_CONFIG.MAX_RELOAD) {\n        sendAdminAlert('main_memory_threshold');\n        return;\n      }\n      \n      triggerFullReload('threshold');\n    }\n    \n    \/\/ 4. \u5b9a\u671f\u6e05\u7406iframe\uff08\u9632\u6b62WebGL\u6cc4\u6f0f\uff09\n    if (iframeMemoryData.lastUpdate &gt; 0) {\n      const timeSinceIframeUpdate = Date.now() - iframeMemoryData.lastUpdate;\n      if (timeSinceIframeUpdate &gt; MEMORY_CONFIG.IFRAME_RELOAD_INTERVAL) {\n        console.log('\ud83d\udd04 iframe\u957f\u65f6\u95f4\u672a\u66f4\u65b0\u5185\u5b58\uff0c\u4e3b\u52a8\u91cd\u8f7d');\n        reloadIframeOnly('maintenance');\n      }\n    }\n    \n  } catch (error) {\n    console.error('\u274c \u5185\u5b58\u68c0\u67e5\u5f02\u5e38:', error);\n  }\n}\n\n\/\/ ============ \u53ea\u91cd\u8f7diframe ============\nfunction reloadIframeOnly(reason: string) {\n  if (isReloading) return;\n  isReloading = true;\n  \n  console.log(`\ud83d\udd04 \u91cd\u8f7diframe (\u539f\u56e0: ${reason})`);\n  \n  try {\n    const iframe = threeDRef.value as HTMLIFrameElement;\n    if (iframe) {\n      \/\/ \u663e\u793a\u901a\u77e5\n      showIframeReloadNotification(reason);\n      \n      \/\/ \u5ef6\u8fdf\u91cd\u8f7d\n      setTimeout(() =&gt; {\n        \/\/ \u5148\u6e05\u7a7asrc\n        iframe.src = 'about:blank';\n        \n        \/\/ \u7b49\u5f85\u4e00\u5e27\u540e\u518d\u6062\u590d\n        requestAnimationFrame(() =&gt; {\n          setTimeout(() =&gt; {\n            iframe.src = threeDUrl.value;\n            \/\/ \u91cd\u7f6eiframe\u5185\u5b58\u6570\u636e\n            iframeMemoryData.usedHeap = 0;\n            iframeMemoryData.lastUpdate = 0;\n            console.log('\u2705 iframe\u91cd\u8f7d\u5b8c\u6210');\n            isReloading = false;\n          }, 100);\n        });\n      }, 1000);\n    } else {\n      isReloading = false;\n    }\n  } catch (error) {\n    console.error('\u274c iframe\u91cd\u8f7d\u5931\u8d25:', error);\n    isReloading = false;\n    \/\/ \u5982\u679ciframe\u91cd\u8f7d\u5931\u8d25\uff0c\u5c1d\u8bd5\u5168\u9875\u91cd\u8f7d\n    triggerFullReload('iframe_reload_failed');\n  }\n}\n\n\/\/ ============ \u5168\u9875\u91cd\u8f7d ============\nfunction triggerFullReload(reason: string) {\n  if (isReloading) return;\n  isReloading = true;\n  \n  const now = Date.now();\n  lastReloadTime = now;\n  reloadCount++;\n  \n  console.log(`\ud83d\udd04 \u5168\u9875\u91cd\u8f7d (\u539f\u56e0: ${reason}, \u7b2c ${reloadCount} \u6b21)`);\n  \n  \/\/ \u4fdd\u5b58\u72b6\u6001\n  try {\n    saveDashboardState();\n  } catch (e) {\n    console.warn('\u4fdd\u5b58\u72b6\u6001\u5931\u8d25:', e);\n  }\n  \n  \/\/ \u663e\u793a\u5168\u5c4f\u901a\u77e5\n  showFullReloadNotification(reason);\n  \n  \/\/ \u5ef6\u8fdf\u91cd\u8f7d\n  setTimeout(() =&gt; {\n    try {\n      \/\/ \u53d1\u9001\u6d88\u606f\u7ed9iframe\u51c6\u5907\u91cd\u8f7d\n      const iframe = threeDRef.value as HTMLIFrameElement;\n      if (iframe &amp;&amp; iframe.contentWindow) {\n        iframe.contentWindow.postMessage({ type: 'page_reloading' }, '*');\n      }\n    } catch (e) {\n      \/\/ ignore\n    }\n    \n    \/\/ \u6267\u884c\u91cd\u8f7d\n    setTimeout(() =&gt; {\n      try {\n        window.location.reload();\n      } catch (e) {\n        try {\n          window.location.href = window.location.href;\n        } catch (e2) {\n          history.go(0);\n        }\n      }\n    }, 500);\n  }, 2000);\n}\n\n\/\/ ============ \u6e05\u7406\u5185\u5b58\uff08\u4e0d\u91cd\u8f7d\uff09 ============\nfunction attemptMemoryCleanup() {\n  console.log('\ud83e\uddf9 \u5c1d\u8bd5\u6e05\u7406\u5185\u5b58...');\n  \n  try {\n    \/\/ 1. \u6e05\u7406\u4e3b\u9875\u9762\u56fe\u8868\n    if (window.charts &amp;&amp; window.charts.length &gt; 0) {\n      window.charts.forEach((chart: any) =&gt; {\n        if (chart &amp;&amp; typeof chart.dispose === 'function') {\n          chart.dispose();\n        }\n      });\n      window.charts = &#91;];\n      console.log('\u2705 \u5df2\u6e05\u7406\u56fe\u8868');\n    }\n    \n    \/\/ 2. \u6e05\u7406\u6570\u636e\u7f13\u5b58\n    if (warnings.value.length &gt; 50) {\n      warnings.value = warnings.value.slice(0, 30);\n    }\n    if (historyList.value.length &gt; 50) {\n      historyList.value = historyList.value.slice(0, 30);\n    }\n    \n    \/\/ 3. \u901a\u77e5iframe\u6e05\u7406\uff08\u53d1\u9001\u6e05\u7406\u6d88\u606f\uff09\n    try {\n      const iframe = threeDRef.value as HTMLIFrameElement;\n      if (iframe &amp;&amp; iframe.contentWindow) {\n        iframe.contentWindow.postMessage({ \n          type: 'cleanup_memory',\n          timestamp: Date.now()\n        }, '*');\n        console.log('\u2705 \u5df2\u53d1\u9001\u6e05\u7406\u6d88\u606f\u5230iframe');\n      }\n    } catch (e) {\n      \/\/ ignore\n    }\n    \n    \/\/ 4. \u89e6\u53d1GC\n    if ((window as any).gc) {\n      try { (window as any).gc(); } catch (e) {}\n    }\n    \n    console.log('\u2705 \u5185\u5b58\u6e05\u7406\u5b8c\u6210');\n  } catch (e) {\n    console.warn('\u5185\u5b58\u6e05\u7406\u5931\u8d25:', e);\n  }\n}\n\n\/\/ ============ \u663e\u793aiframe\u91cd\u8f7d\u901a\u77e5 ============\nfunction showIframeReloadNotification(reason: string) {\n  const notification = document.createElement('div');\n  notification.id = 'iframe-reload-notification';\n  notification.style.cssText = `\n    position: fixed;\n    bottom: 30px;\n    left: 50%;\n    transform: translateX(-50%);\n    background: rgba(255, 165, 0, 0.9);\n    color: white;\n    padding: 12px 24px;\n    border-radius: 8px;\n    z-index: 99999;\n    font-size: 14px;\n    font-family: 'Microsoft YaHei', sans-serif;\n    box-shadow: 0 4px 20px rgba(0,0,0,0.5);\n    animation: slideUp 0.3s ease;\n  `;\n  notification.innerHTML = `\n    &lt;span&gt;\ud83d\udd04 3D\u573a\u666f\u5185\u5b58\u8fc7\u9ad8\uff0c\u6b63\u5728\u91cd\u65b0\u52a0\u8f7d...&lt;\/span&gt;\n  `;\n  document.body.appendChild(notification);\n  \n  setTimeout(() =&gt; {\n    notification.style.opacity = '0';\n    notification.style.transition = 'opacity 0.5s';\n    setTimeout(() =&gt; notification.remove(), 500);\n  }, 3000);\n}\n\n\/\/ ============ \u663e\u793a\u5168\u9875\u91cd\u8f7d\u901a\u77e5 ============\nfunction showFullReloadNotification(reason: string) {\n  const existing = document.getElementById('full-reload-notification');\n  if (existing) existing.remove();\n  \n  const reasons: Record&lt;string, string&gt; = {\n    'emergency': '\u5185\u5b58\u4e25\u91cd\u8d85\u9650',\n    'threshold': '\u5185\u5b58\u8d85\u8fc7\u9608\u503c',\n    'fps': '\u9875\u9762\u5361\u987f\u4e25\u91cd',\n    'schedule': '\u5b9a\u65f6\u5237\u65b0',\n    'iframe_reload_failed': '3D\u573a\u666f\u52a0\u8f7d\u5931\u8d25'\n  };\n  \n  const notification = document.createElement('div');\n  notification.id = 'full-reload-notification';\n  notification.style.cssText = `\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.8);\n    backdrop-filter: blur(8px);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    z-index: 999999;\n    font-family: 'Microsoft YaHei', sans-serif;\n  `;\n  notification.innerHTML = `\n    &lt;div style=\"\n      background: linear-gradient(135deg, #1a1a2e, #16213e);\n      padding: 50px 60px;\n      border-radius: 20px;\n      text-align: center;\n      border: 2px solid #ff6b6b;\n      box-shadow: 0 0 60px rgba(255, 0, 0, 0.2);\n      max-width: 500px;\n    \"&gt;\n      &lt;div style=\"font-size: 56px; margin-bottom: 16px;\"&gt;\ud83d\udd04&lt;\/div&gt;\n      &lt;h2 style=\"color: #ff6b6b; margin: 0 0 8px; font-size: 22px;\"&gt;\u7cfb\u7edf\u6b63\u5728\u5237\u65b0&lt;\/h2&gt;\n      &lt;p style=\"color: #aaa; margin: 0 0 4px; font-size: 14px;\"&gt;\n        \u539f\u56e0: ${reasons&#91;reason] || reason}\n      &lt;\/p&gt;\n      &lt;p style=\"color: #666; margin: 0 0 24px; font-size: 13px;\"&gt;\n        \u7b2c ${reloadCount} \u6b21\u91cd\u8f7d\n      &lt;\/p&gt;\n      &lt;div style=\"\n        width: 100%;\n        height: 4px;\n        background: #333;\n        border-radius: 2px;\n        overflow: hidden;\n      \"&gt;\n        &lt;div style=\"\n          width: 100%;\n          height: 100%;\n          background: linear-gradient(90deg, #ff6b6b, #ff4444);\n          animation: reloadProgress 2s ease-in-out forwards;\n        \"&gt;&lt;\/div&gt;\n      &lt;\/div&gt;\n      &lt;p style=\"color: #555; margin-top: 16px; font-size: 12px;\"&gt;\n        \u8bf7\u7a0d\u5019\uff0c\u9875\u9762\u5c06\u81ea\u52a8\u6062\u590d...\n      &lt;\/p&gt;\n    &lt;\/div&gt;\n  `;\n  \n  \/\/ \u6dfb\u52a0\u52a8\u753b\u6837\u5f0f\n  if (!document.getElementById('reload-animation-style')) {\n    const style = document.createElement('style');\n    style.id = 'reload-animation-style';\n    style.textContent = `\n      @keyframes reloadProgress {\n        0% { width: 0%; }\n        100% { width: 100%; }\n      }\n      @keyframes slideUp {\n        from { transform: translateX(-50%) translateY(20px); opacity: 0; }\n        to { transform: translateX(-50%) translateY(0); opacity: 1; }\n      }\n    `;\n    document.head.appendChild(style);\n  }\n  \n  document.body.appendChild(notification);\n}\n\n\/\/ ============ \u72b6\u6001\u4fdd\u5b58 ============\nfunction saveDashboardState() {\n  try {\n    const state = {\n      timestamp: Date.now(),\n      warnings: warnings.value.slice(0, 20),\n      history: historyList.value.slice(0, 20),\n      scheduleTimes: selectedTimes.value,\n      \/\/ \u4fdd\u5b58iframe\u5185\u5b58\u6570\u636e\n      iframeMemory: iframeMemoryData\n    };\n    localStorage.setItem('dashboard_reload_backup', JSON.stringify(state));\n  } catch (e) {\n    \/\/ ignore\n  }\n}\n\n\/\/ ============ \u7ba1\u7406\u5458\u544a\u8b66 ============\nfunction sendAdminAlert(type: string) {\n  try {\n    const data = {\n      type: 'dashboard_memory_critical',\n      subType: type,\n      reloadCount: reloadCount,\n      timestamp: Date.now(),\n      url: window.location.href,\n      memory: {\n        main: (window.performance as any).memory ? {\n          used: (window.performance as any).memory.usedJSHeapSize,\n          total: (window.performance as any).memory.jsHeapSizeLimit\n        } : null,\n        iframe: iframeMemoryData\n      }\n    };\n    \n    if (navigator.sendBeacon) {\n      navigator.sendBeacon('\/api\/monitor\/alert', JSON.stringify(data));\n    }\n  } catch (e) {\n    \/\/ ignore\n  }\n}\n\n\/\/ ============ \u5907\u7528\u76d1\u63a7\u7b56\u7565 ============\nfunction startFallbackMonitor() {\n  console.log('\u26a0\ufe0f \u4f7f\u7528\u5907\u7528\u76d1\u63a7\u7b56\u7565');\n  \n  let checkCount = 0;\n  let lastCheckTime = Date.now();\n  \n  memoryCheckTimer = window.setInterval(() =&gt; {\n    checkCount++;\n    const now = Date.now();\n    \n    \/\/ \u68c0\u6d4b\u4e3b\u9875\u9762\u54cd\u5e94\n    try {\n      const start = performance.now();\n      document.body.getBoundingClientRect();\n      const end = performance.now();\n      \n      if (end - start &gt; 200) {\n        console.warn(`\u26a0\ufe0f \u9875\u9762\u54cd\u5e94\u7f13\u6162: ${(end - start).toFixed(0)}ms`);\n        if (end - start &gt; 500) {\n          console.error('\ud83d\udea8 \u9875\u9762\u65e0\u54cd\u5e94\uff0c\u89e6\u53d1\u91cd\u8f7d');\n          triggerFullReload('fallback');\n        }\n      }\n    } catch (e) {\n      console.error('\u274c \u9875\u9762\u5d29\u6e83\uff0c\u89e6\u53d1\u91cd\u8f7d');\n      triggerFullReload('crash');\n    }\n    \n    \/\/ \u6bcf30\u5206\u949f\u68c0\u67e5iframe\u662f\u5426\u5b58\u6d3b\n    if (checkCount % 60 === 0) { \/\/ 60 * 30\u79d2 = 30\u5206\u949f\n      checkIframeAlive();\n    }\n    \n    lastCheckTime = now;\n    \n    \/\/ \u6bcf2\u5c0f\u65f6\u5f3a\u5236\u5168\u9875\u91cd\u8f7d\n    if (checkCount &gt; 240) {\n      console.log('\ud83d\udd04 \u5907\u7528\u7b56\u7565: \u5b9a\u65f6\u5168\u9875\u91cd\u8f7d');\n      triggerFullReload('schedule');\n      checkCount = 0;\n    }\n    \n  }, 30000);\n}\n\n\/\/ ============ \u68c0\u67e5iframe\u662f\u5426\u5b58\u6d3b ============\nfunction checkIframeAlive() {\n  try {\n    const iframe = threeDRef.value as HTMLIFrameElement;\n    if (iframe &amp;&amp; iframe.contentWindow) {\n      \/\/ \u53d1\u9001ping\u6d88\u606f\n      iframe.contentWindow.postMessage({ type: 'ping', timestamp: Date.now() }, '*');\n      \n      \/\/ \u8bbe\u7f6e\u8d85\u65f6\u68c0\u6d4b\n      let pingTimeout = setTimeout(() =&gt; {\n        console.warn('\u26a0\ufe0f iframe\u65e0\u54cd\u5e94\uff0c\u5c1d\u8bd5\u91cd\u8f7d');\n        reloadIframeOnly('timeout');\n      }, 5000);\n      \n      \/\/ \u76d1\u542cpong\u54cd\u5e94\n      const pongHandler = (event: MessageEvent) =&gt; {\n        try {\n          const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;\n          if (data &amp;&amp; data.type === 'pong') {\n            clearTimeout(pingTimeout);\n            window.removeEventListener('message', pongHandler);\n          }\n        } catch (e) {\n          \/\/ ignore\n        }\n      };\n      window.addEventListener('message', pongHandler, { once: true });\n    }\n  } catch (e) {\n    console.warn('\u68c0\u67e5iframe\u5b58\u6d3b\u5931\u8d25:', e);\n  }\n}\n\n\/\/ ============ \u505c\u6b62\u76d1\u63a7 ============\nfunction stopMemoryMonitor() {\n  if (memoryCheckTimer) {\n    clearInterval(memoryCheckTimer);\n    memoryCheckTimer = null;\n  }\n  window.removeEventListener('message', handleIframeMemoryMessage);\n  \n  \/\/ \u79fb\u9664\u901a\u77e5\n  document.querySelectorAll('&#91;id$=\"-reload-notification\"]').forEach(el =&gt; el.remove());\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">iframe\u5185\u90e8\u4ee3\u7801\uff0c\u628a\u9875\u9762\u5185\u5b58\u4f20\u9012\u7ed9\u4e3b\u9875<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ ============ \u653e\u5728iframe\u9875\u9762\u4e2d ============<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ \u76d1\u542c\u7236\u9875\u9762\u6d88\u606f<br>window.addEventListener(&#8216;message&#8217;, function(event) {<br>try {<br>const data = typeof event.data === &#8216;string&#8217; ? JSON.parse(event.data) : event.data;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>switch (data.type) {\n  case 'ping':\n    \/\/ \u54cd\u5e94ping\n    event.source.postMessage({ type: 'pong', timestamp: Date.now() }, '*');\n    break;\n\n  case 'cleanup_memory':\n    \/\/ \u6e05\u74063D\u573a\u666f\u5185\u5b58\n    cleanupThreeScene();\n    break;\n\n  case 'page_reloading':\n    \/\/ \u7236\u9875\u9762\u5373\u5c06\u91cd\u8f7d\uff0c\u4fdd\u5b58\u72b6\u6001\n    saveThreeState();\n    break;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">} catch (e) {<br>\/\/ ignore<br>}<br>});<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ \u5b9a\u65f6\u62a5\u544a\u5185\u5b58\u4f7f\u7528\uff08\u5982\u679c\u652f\u6301\uff09<br>function reportMemoryUsage() {<br>if (window.performance &amp;&amp; (window.performance as any).memory) {<br>const memory = (window.performance as any).memory;<br>window.parent.postMessage({<br>type: &#8216;iframe_memory&#8217;,<br>usedHeapSize: memory.usedJSHeapSize,<br>totalHeapSize: memory.jsHeapSizeLimit,<br>timestamp: Date.now()<br>}, &#8216;*&#8217;);<br>}<br>}<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ \u6bcf10\u79d2\u62a5\u544a\u4e00\u6b21\u5185\u5b58<br>setInterval(reportMemoryUsage, 10000);<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ \u6e05\u74063D\u573a\u666f<br>function cleanupThreeScene() {<br>console.log(&#8216;\ud83e\uddf9 \u6e05\u74063D\u573a\u666f\u5185\u5b58&#8217;);<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">try {<br>\/\/ \u5982\u679c\u4f7f\u7528Three.js<br>if (window.renderer) {<br>window.renderer.dispose();<br>}<br>if (window.scene) {<br>window.scene.traverse((child: any) =&gt; {<br>if (child.geometry) {<br>child.geometry.dispose();<br>}<br>if (child.material) {<br>if (Array.isArray(child.material)) {<br>child.material.forEach(m =&gt; m.dispose());<br>} else {<br>child.material.dispose();<br>}<br>}<br>});<br>}<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u89e6\u53d1GC\nif ((window as any).gc) {\n  try { (window as any).gc(); } catch (e) {}\n}\n\nconsole.log('\u2705 3D\u573a\u666f\u6e05\u7406\u5b8c\u6210');<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">} catch (e) {<br>console.warn(&#8216;\u6e05\u74063D\u573a\u666f\u5931\u8d25:&#8217;, e);<br>}<br>}<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\/\/ \u4fdd\u5b583D\u72b6\u6001<br>function saveThreeState() {<br>try {<br>const state = {<br>timestamp: Date.now(),<br>\/\/ \u4fdd\u5b58\u76f8\u673a\u4f4d\u7f6e\u7b49<br>camera: window.camera ? {<br>position: window.camera.position.toArray(),<br>target: window.camera.target ? window.camera.target.toArray() : null<br>} : null<br>};<br>localStorage.setItem(&#8216;three_scene_backup&#8217;, JSON.stringify(state));<br>} catch (e) {<br>\/\/ ignore<br>}<br>}<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u5173\u952e\u4f18\u5316\u70b9\u603b\u7ed3<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">\u4f18\u5316\u9879<\/th><th class=\"has-text-align-left\" data-align=\"left\">\u4f5c\u7528<\/th><th class=\"has-text-align-left\" data-align=\"left\">\u6548\u679c<\/th><\/tr><\/thead><tbody><tr><td><strong>\u53cc\u5185\u5b58\u76d1\u63a7<\/strong><\/td><td>\u540c\u65f6\u76d1\u63a7\u4e3b\u9875\u9762\u548ciframe\u5185\u5b58<\/td><td>\u63d0\u524d\u53d1\u73b0\u5185\u5b58\u95ee\u9898<\/td><\/tr><tr><td><strong>\u5206\u7ea7\u9884\u8b66<\/strong><\/td><td>\u9608\u503c\/\u5360\u6bd4\/\u7d27\u6025\u4e09\u7ea7\u9884\u8b66<\/td><td>\u907f\u514d\u6d4f\u89c8\u5668\u5d29\u6e83<\/td><\/tr><tr><td><strong>iframe\u72ec\u7acb\u91cd\u8f7d<\/strong><\/td><td>\u53ea\u91cd\u8f7d3D\u573a\u666f\uff0c\u4e0d\u5237\u65b0\u6574\u4e2a\u9875\u9762<\/td><td>\u63d0\u5347\u7528\u6237\u4f53\u9a8c<\/td><\/tr><tr><td><strong>\u5b9a\u671f\u6e05\u7406<\/strong><\/td><td>\u6bcf\u5c0f\u65f6\u91cd\u8f7diframe<\/td><td>\u9632\u6b62WebGL\u5185\u5b58\u6cc4\u6f0f<\/td><\/tr><tr><td><strong>\u5185\u5b58\u6d88\u606f\u901a\u4fe1<\/strong><\/td><td>\u4e3b\u9875\u9762\u4e0eiframe\u53cc\u5411\u901a\u4fe1<\/td><td>\u5b9e\u65f6\u76d1\u63a7iframe\u5185\u5b58<\/td><\/tr><tr><td><strong>\u52a0\u8f7d\u72b6\u6001<\/strong><\/td><td>\u663e\u793aiframe\u52a0\u8f7d\u72b6\u6001<\/td><td>\u6539\u5584\u7528\u6237\u4f53\u9a8c<\/td><\/tr><tr><td><strong>\u72b6\u6001\u4fdd\u5b58<\/strong><\/td><td>\u91cd\u8f7d\u524d\u4fdd\u5b58\u5173\u952e\u72b6\u6001<\/td><td>\u6570\u636e\u4e0d\u4e22\u5931<\/td><\/tr><\/tbody><\/table><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\u6709\u4e00\u4e2a\u9700\u6c42\u662f\u6279\u91cf\u751f\u6210\u4eff\u771f\u6570\u636e\u57283D\u5730\u56fe\u4e0a\u9762\uff0c\u6bcf\u6761\u68c0\u6d4b\u7ebf\u4f30\u8ba140\u53f0\u8f66\u5728\u5faa\u73af\u4e0d\u505c\u7684\u884c\u9a76\uff0c\u4e2d\u95f4\u4f1a\u6709\u7ebf\u8def\u4e24\u4fa7\u7684\u6444\u50cf\u5934\u544a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-4076","post","type-post","status-publish","format-standard","hentry","category-4"],"_links":{"self":[{"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/posts\/4076","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/comments?post=4076"}],"version-history":[{"count":3,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/posts\/4076\/revisions"}],"predecessor-version":[{"id":4091,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/posts\/4076\/revisions\/4091"}],"wp:attachment":[{"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/media?parent=4076"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/categories?post=4076"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gaigaiming.com\/index.php\/wp-json\/wp\/v2\/tags?post=4076"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}