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

如何为jspdf+html2canvas添加加载Spinner?React状态更新异常求助

Fixing Delayed Loading Spinner When Exporting Large PDFs with jsPDF & html2canvas

Hey there, I’ve run into this exact issue before—let’s break down why your spinner isn’t showing up immediately and how to fix it!

The Root Cause

React’s setState is asynchronous, and html2canvas is a resource-heavy operation that blocks the main thread. When you call setState({ isDownloading: true }) followed immediately by html2canvas, the main thread gets tied up processing the canvas conversion before React can finish updating the state and rendering your spinner. That’s why the spinner only pops up right before the PDF downloads—once the heavy work is almost done.

Solution 1: Use setState’s Callback to Delay Heavy Work

React’s setState accepts a second callback parameter that runs after the state has been updated and the component has re-rendered. This ensures your spinner is visible before html2canvas starts chugging away.

Here’s how to adjust your code:

printDocument() {
  const input = document.getElementById('container');
  // Update state first, then run html2canvas in the callback
  this.setState({ isDownloading: true }, () => {
    html2canvas(input)
      .then((canvas) => {
        const imgData = canvas.toDataURL('image/png');
        const pdf = new pdfConverter("p", "mm", "a4");
        const width = pdf.internal.pageSize.width;
        const height = pdf.internal.pageSize.height;
        pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
        pdf.save("download.pdf");
        this.setState({ isDownloading: false });
      });
  });
}

Solution 2: Add a Tiny Delay with setTimeout (For Stubborn Cases)

If the callback alone doesn’t work (sometimes the main thread still gets blocked before rendering), wrap the html2canvas call in a setTimeout with a 0ms delay. This pushes the heavy work to the end of the browser’s event queue, giving it time to finish rendering the spinner first.

Modified code:

printDocument() {
  const input = document.getElementById('container');
  this.setState({ isDownloading: true }, () => {
    // Give the browser a moment to render the spinner
    setTimeout(() => {
      html2canvas(input)
        .then((canvas) => {
          const imgData = canvas.toDataURL('image/png');
          const pdf = new pdfConverter("p", "mm", "a4");
          const width = pdf.internal.pageSize.width;
          const height = pdf.internal.pageSize.height;
          pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
          pdf.save("download.pdf");
          this.setState({ isDownloading: false });
        });
    }, 0);
  });
}

Bonus: Optimize Large Content (Optional)

If your page is really large, consider these extra tweaks to speed up the process:

  • Exclude non-critical elements from the input container to reduce what html2canvas has to process.
  • Adjust html2canvas options like scale (lower it slightly if image quality allows) or useCORS (if you’re loading external images) to speed up rendering.
  • For ultra-large content, look into chunking the PDF into multiple pages instead of rendering everything as one big canvas.

Hope this fixes your spinner issue—let me know if you run into any other snags!

内容的提问来源于stack exchange,提问作者Johnson Samuel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:39:43