You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel与AngularJS实现鼠标悬停数据快速预览的技术方案咨询

Optimizing Menu Preview Feature for 12 Complex Report Menus

Hey there! Let’s tackle this menu preview challenge you’re facing. First, let’s unpack the pain points of your current approach, then dive into practical, optimized solutions that’ll make the feature smoother for users and easier to maintain.

Current Approach Limitations

Your current setup fires 12 API requests on first login—this can lead to:

  • Slow initial page load (especially with complex report queries, the backend might take time to process each request)
  • Unnecessary backend load if the user never hovers over some menus
  • Stale data in localStorage, since there’s no mechanism to refresh when reports update

1. Lazy Load + On-Demand Caching

Instead of fetching all 12 reports upfront, only fetch data the first time a user hovers over a menu. Then store that data in localStorage for subsequent hovers (and page reloads). This cuts down initial load time drastically and avoids wasting resources on unused reports.

Here’s a quick code snippet to illustrate this:

// Handle menu hover event
async function handleMenuHover(menuId) {
  // Check localStorage for cached data
  const cachedEntry = localStorage.getItem(`report_preview_${menuId}`);
  const parsedEntry = cachedEntry ? JSON.parse(cachedEntry) : null;

  if (parsedEntry) {
    // Use cached data to render preview
    renderPreview(parsedEntry.data);
    return;
  }

  // Fetch fresh data if no cache exists
  try {
    const response = await fetch(`api/reports/${menuId}/preview?limit=5`);
    const data = await response.json();
    // Store in localStorage for future use
    localStorage.setItem(`report_preview_${menuId}`, JSON.stringify({ data }));
    // Render preview
    renderPreview(data);
  } catch (error) {
    console.error(`Failed to fetch preview for menu ${menuId}:`, error);
    // Fallback to empty state or error message
    renderEmptyPreview();
  }
}

// Attach hover listener to all report menus
document.querySelectorAll('.report-menu').forEach(menu => {
  menu.addEventListener('mouseenter', () => handleMenuHover(menu.dataset.id));
});

2. Batch API Request (If Pre-Load is Necessary)

If you absolutely need pre-loaded data (e.g., for instant preview on first hover), replace 12 individual requests with a single batch API call. Work with your backend team to create an endpoint that returns preview data for all 12 reports at once.

This reduces HTTP overhead (1 request instead of 12) and lets the backend optimize batch processing of complex queries. Example:

// On initial login completion
async function preloadAllPreviews() {
  try {
    const response = await fetch('api/reports/batch-preview?limit=5');
    const allPreviews = await response.json();
    // Store each report's data in localStorage
    Object.entries(allPreviews).forEach(([menuId, data]) => {
      localStorage.setItem(`report_preview_${menuId}`, JSON.stringify({ data }));
    });
  } catch (error) {
    console.error('Failed to preload report previews:', error);
  }
}

// Trigger once after user logs in
preloadAllPreviews();

3. Add Cache Expiration

Reports are likely to update over time—so add an expiration timestamp to your cached data to avoid showing stale info. Modify the caching logic to store both data and an expiration time:

// When storing fresh data
const cacheEntry = {
  data: fetchedData,
  expireAt: Date.now() + 3600000 // 1 hour expiration (adjust based on your data refresh needs)
};
localStorage.setItem(`report_preview_${menuId}`, JSON.stringify(cacheEntry));

// When checking cache validity
const cachedEntry = JSON.parse(localStorage.getItem(`report_preview_${menuId}`));
if (cachedEntry && Date.now() < cachedEntry.expireAt) {
  // Use valid cached data
  renderPreview(cachedEntry.data);
} else {
  // Fetch fresh data and update cache
  fetchAndCachePreview(menuId);
}

4. Debounce Hover Events

Prevent accidental, rapid-fire requests if the user quickly swipes through menus. Add a debounce function to delay the API call until the user has hovered for a short period (e.g., 300ms):

// Simple debounce utility
function debounce(func, delay = 300) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

// Wrap the hover handler with debounce to avoid spam requests
const debouncedHandleHover = debounce(handleMenuHover);

// Attach listener with debounced function
menu.addEventListener('mouseenter', () => debouncedHandleHover(menu.dataset.id));

Page Reload Handling

Since localStorage persists across page reloads, your cached data will still be available when the user refreshes. Just make sure to combine this with the cache expiration check to ensure users don’t see outdated reports after a reload.

内容的提问来源于stack exchange,提问作者Mohd Mobeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:04:00