Reputation: 51
Page is getting unresponsive while exporting the page into pdf, refer the below screenshot.
Here is the stackblitz code: The below code is used to convert the chart into image which is causing the performnce issue.
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
);
});
}
}
Please help me here to solve page unresponsive error.
Expected Results: Should not display page unresponsive error while generating the pdf.
Upvotes: 1
Views: 174
Reputation: 1652
This issue didn't happen because of performance. It occurred because you ran your long-processing code on the Main Thread
The main thread is where a browser processes user events and paints. By default, the browser uses a single thread to run all the JavaScript in your page, as well as to perform layout, reflows, and garbage collection. This means that long-running JavaScript functions can block the thread, leading to an unresponsive page and a bad user experience.
so it will completely freeze and block your UI during the iteration and PDF generation.
JavaScript used to be a single-threaded language, so the only way to run long-processing tasks was by using setTimeout (as mentioned in the previous answer). This approach chunks the process and adds them to the stack, allowing the user to interact with the browser UI simultaneously.
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.log(result))
console.log('Waiting for the result...')
Nowadays, it is also possible to achieve this with Promises and Web Workers.
useful articles:
Upvotes: 0
Reputation: 318
Please replace the below function:
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);
}
Upvotes: 3