Страница не отвечает при создании кнопки экспорта в формате PDF

Страница не отвечает при экспорте страницы в PDF, см. снимок экрана ниже.

Вот код stackblitz: Код ниже используется для преобразования диаграммы в изображение, что вызывает проблемы с производительностью.

  private convertChartToPng(listOfCharts: any, reportLayoutElement: any) {
for (let i = 0; i < listOfCharts.length; i++) {
  const chartCtrlId = '#' + listOfCharts[i].id;
  const chartElementRef = reportLayoutElement.querySelector(chartCtrlId);

  this.convertChartToImg(chartCtrlId).subscribe((image) => { // It is taking more time to convert chart to image which sometimes makes the page unresponsiveness

    const pngImgage = document.createElement('img');
    pngImgage.src = image;
    chartElementRef.innerHTML = '';
    chartElementRef.appendChild(pngImgage);
    this.validateChartsRenderedAndGeneratePdf(
      i,
      listOfCharts,
      reportLayoutElement
    );
  });
}

}

Пожалуйста, помогите мне решить ошибку, из-за которой страница не отвечает.

Ожидаемые результаты: при создании PDF-файла не должна отображаться ошибка «не отвечает страница».

Невозможно воспроизвести, на моей машине создается PDF-файл.

JSON Derulo 31.07.2024 12:14

Спасибо за быстрый ответ. Пожалуйста, попробуйте создать PDF-файл несколько раз.

Sathya 31.07.2024 12:34

@KJ, есть ли у вас рекомендуемая библиотека для эффективного выполнения этой операции? Можете ли вы рассказать о потоке, как он будет работать?

Sathya 01.08.2024 05:29

поток — это только начало содержимого страницы, но дело в точности, с которой он использует расчет с 16 десятичными знаками, тогда как более простое 0,567 должно быть достаточно хорошим, и все такие вычисления занимают миллисекунды. Хорошо, если их всего несколько, но каждый расчет штрихов увеличивает общее время обработки. нет реальной проблемы для небольшого количества текста на странице, изображения кажутся медленными, а затем конвертируются в 3 раза, например. 1) нарисовать HTML-страницу 2) преобразовать страницу в изображение 3) преобразовать в текстовый uri 4) преобразовать uri в изображение 5) преобразовать изображение в PDF, что и нужно для печати с помощью холста.

K J 01.08.2024 12:49
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Пожалуйста, замените приведенную ниже функцию:

 private convertChartToPng(listOfCharts: any, reportLayoutElement: any) {
    const processChunk = (index: number) => {
      if (index < listOfCharts.length) {
        const chartCtrlId = '#' + listOfCharts[index].id;
        const chartElementRef = reportLayoutElement.querySelector(chartCtrlId);
        this.convertChartToImg(chartCtrlId).subscribe((image) => {
          const pngImgage = document.createElement('img');
          pngImgage.src = image;
          chartElementRef.innerHTML = '';
          chartElementRef.appendChild(pngImgage);
          this.validateChartsRenderedAndGeneratePdf(
            index,
            listOfCharts,
            reportLayoutElement
          );
          setTimeout(() => processChunk(index + 1), 0);
        });
      }
    };
    processChunk(0);
  }

Эта проблема возникла не из-за производительности. Это произошло из-за того, что вы запустили код длинной обработки в Main Thread

В основном потоке браузер обрабатывает пользовательские события и рисует. По умолчанию браузер использует один поток для выполнения всего кода JavaScript. на вашей странице, а также для выполнения макетирования, перекомпоновки и удаления коллекция. Это означает, что долго выполняющиеся функции JavaScript могут заблокируйте ветку, что приведет к тому, что страница не будет отвечать и плохой пользователь опыт.

поэтому он полностью заморозит и заблокирует ваш пользовательский интерфейс во время итерации и создания PDF-файла.

Раньше JavaScript был однопоточным языком, поэтому единственным способом запуска задач длительной обработки было использование setTimeout (как упоминалось в предыдущем ответе). Этот подход разбивает процесс на части и добавляет их в стек, позволяя пользователю одновременно взаимодействовать с пользовательским интерфейсом браузера.

function myFunctionWithCallback(a, b, callback) {
  setTimeout(() => {
    // Do something
    const c = a + b
 
    // Call the callback
    if (callback && callback instanceof Function) {
      callback(c)
    }
  }, 0)
}

myFunctionWithCallback(1, 2, (result) => console.info(result))
console.info('Waiting for the result...')

Сегодня этого также можно добиться с помощью Promises и Web Workers.

полезные статьи:

Другие вопросы по теме