Страница не отвечает при экспорте страницы в 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-файл несколько раз.
@KJ, есть ли у вас рекомендуемая библиотека для эффективного выполнения этой операции? Можете ли вы рассказать о потоке, как он будет работать?
поток — это только начало содержимого страницы, но дело в точности, с которой он использует расчет с 16 десятичными знаками, тогда как более простое 0,567 должно быть достаточно хорошим, и все такие вычисления занимают миллисекунды. Хорошо, если их всего несколько, но каждый расчет штрихов увеличивает общее время обработки. нет реальной проблемы для небольшого количества текста на странице, изображения кажутся медленными, а затем конвертируются в 3 раза, например. 1) нарисовать HTML-страницу 2) преобразовать страницу в изображение 3) преобразовать в текстовый uri 4) преобразовать uri в изображение 5) преобразовать изображение в PDF, что и нужно для печати с помощью холста.
Пожалуйста, замените приведенную ниже функцию:
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.
полезные статьи:
Невозможно воспроизвести, на моей машине создается PDF-файл.