GetOrgChart加载含Base64图片数据过慢,异步加载图片不显示求助
Hey Sara, I totally get how frustrating it is waiting a minute for your org chart to load because of those huge Base64 images—plus the async loading not updating the chart afterward is just adding insult to injury. Let’s walk through a few practical fixes that should get your images showing up properly without killing load times.
1. Preload Images & Update Nodes Post-Render
The key here is to render the chart first with placeholder content (like a default avatar or loading spinner), then fetch your images asynchronously and update the nodes once the images are ready. GetOrgChart lets you access the DOM of each node during the renderNodeEvent, so you can hook into that to handle the async load.
Here’s a code example to implement this:
const orgChart = new getOrgChart(document.getElementById("orgChart"), { data: yourMinifiedData, // Data without Base64 images—just IDs and other text fields renderNodeEvent: function(sender, args) { // Get the node's DOM element and the node data const nodeElement = args.node.element; const nodeId = args.node.id; // Create a placeholder image (optional but improves UX) const placeholderImg = document.createElement("img"); placeholderImg.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Crect fill='%23eee' width='100' height='100'/%3E%3Ctext fill='%23ccc' x='50' y='50' text-anchor='middle' dy='.3em'%3ELoading...%3C/text%3E%3C/svg%3E"; placeholderImg.style.width = "80px"; placeholderImg.style.height = "80px"; nodeElement.querySelector(".your-image-container-class").appendChild(placeholderImg); // Async fetch your image (replace with your actual API call to get Base64 or image URL) fetch(`/api/get-image/${nodeId}`) .then(response => response.json()) .then(imageData => { // Replace placeholder with the actual image const actualImg = document.createElement("img"); actualImg.src = imageData.base64Image; // Or imageData.imageUrl if using URLs actualImg.style.width = "80px"; actualImg.style.height = "80px"; // Remove placeholder and add actual image nodeElement.querySelector(".your-image-container-class").innerHTML = ""; nodeElement.querySelector(".your-image-container-class").appendChild(actualImg); }) .catch(err => { // Handle error—maybe show a default avatar placeholderImg.src = "path/to/default-avatar.png"; }); } });
Pro tip: Add a cache layer (like a Map) to store loaded images so you don’t re-fetch them when nodes re-render.
2. Replace Base64 with Image URLs & Lazy Load
Instead of embedding huge Base64 strings in your JSON, store image URLs pointing to your server. This cuts down your initial JSON size dramatically, making the chart load in seconds. Then, use lazy loading to only load images when their nodes are visible in the viewport—this saves bandwidth and speeds up initial render even more.
Here’s how to set this up:
// Updated JSON data (no Base64, just image URLs) const orgData = [ { id: 1, name: "John Doe", imageUrl: "/images/john-doe.png" }, // ... other nodes ]; const orgChart = new getOrgChart(document.getElementById("orgChart"), { data: orgData, renderNodeEvent: function(sender, args) { const nodeElement = args.node.element; const imageUrl = args.node.data.imageUrl; // Create an image element with lazy loading const img = document.createElement("img"); img.src = "path/to/placeholder.png"; // Placeholder img.dataset.src = imageUrl; // Store actual URL in data attribute img.style.width = "80px"; img.style.height = "80px"; nodeElement.querySelector(".your-image-container-class").appendChild(img); // Check if node is in viewport to load the image const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; observer.unobserve(img); } }); }); observer.observe(img); } });
This method is my top recommendation because it solves both the initial load time issue and the async update problem—browser caching will also help with repeat visits.
3. Use GetOrgChart’s Update Method
If you prefer to keep using Base64 but want to load it after the chart renders, you can first render the chart with empty image fields, then fetch all the Base64 images in bulk, and use GetOrgChart’s updateNode method to refresh each node once its image is ready.
Example:
// Initial data without images const initialData = yourData.map(node => ({ ...node, image: "" })); const orgChart = new getOrgChart(document.getElementById("orgChart"), { data: initialData, // Configure your chart options }); // Fetch all images after chart renders Promise.all(yourData.map(node => fetch(`/api/get-image/${node.id}`).then(res => res.json()) )).then(imageResults => { imageResults.forEach(result => { // Update the node with the loaded image orgChart.updateNode(result.nodeId, { image: result.base64Image }); }); });
This works well if you need to load all images at once after the chart is visible.
Hopefully one of these solutions gets your org chart loading quickly and your images showing up as expected! Let me know if you need help tweaking any of the code.
内容的提问来源于stack exchange,提问作者Sara Ravasio

