Accelerate the generation speed by using JsPDF to convert canvas to PDF

I need to optimize the download speed of a specific div on my webpage as a PDF using jspdf and canvas. Currently, it takes 2 or 3 seconds which is too slow for my client's liking. Is there a way to make this process faster? Additionally, the file size is quite large at 8MB. Any suggestions on how to reduce the file size?

Here is the code snippet:

$('#print').click(function (e) { 
    e.preventDefault();
    let HTML_Width = $(".report").width();
    let HTML_Height = $(".report").height();
    let top_left_margin = 1;
    let PDF_Width = HTML_Width + (top_left_margin * 2);
    let PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2);
    let canvas_image_width = HTML_Width;
    let canvas_image_height = HTML_Height;
    let totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1;
    html2canvas($(".report")[0]).then(function (canvas) {
        let imgData = canvas.toDataURL("image/png", 1.0);
        let pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
        pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height);
        for (let i = 1; i <= totalPDFPages; i++) {
            pdf.addPage(PDF_Width, PDF_Height);
            pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height);
        }
        pdf.save("Report.pdf");
        $(".html-content").hide();
    });
});

Answer №1

Two main factors significantly impacted the performance of this process: the volume of data and the compression used.

To reduce the data load, opting for a lower DPI setting such as 72 for screen-reading documents is advisable, although it may not be ideal for printing purposes.

In our case with html2canvas, we adjusted the scale to 3.125 in order to decrease pixel density (as part of the options parameter), which roughly equated to around 96dpi.

When it comes to compression, experimenting with various options can make a difference; we saw improvements using 'FAST' compression with pdf.addImage.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to incorporate a JavaScript variable into an ERB tag

Exploring the integration of a JavaScript variable within erb <% %> tags has led me to consider using AJAX (refer to How to pass a javascript variable into a erb code in a js view?). As someone new to JavaScript and AJAX, it would be extremely helpfu ...

Exploring the intricacies of debugging async/await in Node.js with the help of

Having trouble debugging an "await" instruction in my async function. Every time I try, a promise is returned instead of the expected value. I've noticed there's supposed to be an "Async" button where the red square is located in this picture but ...

Managing errors in React Router on the server-side

I am currently working on an isomorphic application using react-router and express. My goal is to implement custom error pages that will be displayed in case of server-side errors, rendering errors, or when a page is not found. However, I am facing difficu ...

Initial page load experiencing issues with paroller.js functionality

Upon hard refreshing the page in the middle section, there seems to be an issue with the paroller js transform: translateY(); CSS effect not functioning properly on the <div class="col col-6" data-paroller-factor="0.4" data-paroller-type="foreground" da ...

Attempting to pass a limit argument to a query in urql, Strapi, and Next JS for the Query.posts field has resulted in a combination of errors including graphQLErrors

I need help figuring out how to pass a variable for the limit parameter in my GraphQL query. I am currently working with urql, Strapi, and its GraphQL plugin in a Next.js application. My goal is to introduce a variable for the limit to restrict the number ...

jQuery offset(coords) behaves inconsistently when called multiple times

I am attempting to position a div using the jQuery offset() function. The goal is to have it placed at a fixed offset from another element within the DOM. This is taking place in a complex environment with nested divs. What's puzzling is that when I ...

Multiple instances of the identical 'Angular application' displayed simultaneously on the webpage

We've created a unique Angular 1.0 application that we aim to embed as a 'widget' within another website built with classic asp.net. During the development phase of our angular app, we take advantage of a range of gulp tools for tasks such ...

The error message "email() is not a valid function when using the onclick attribute

Can anyone lend a hand? I feel like I must be overlooking something really obvious. I'm having trouble calling my function to execute my ajax call. Any assistance would be greatly appreciated. Thank you! Here is an excerpt of the HTML code: $(docu ...

What is the best way to showcase content based on data hooks?

I am facing an issue where my form is not displaying the desired entry as expected from my code. The goal is to show a message indicating that the phone number entered by the user is already in use and display it as invalid. I have implemented logic to ch ...

Struggling with dynamically updating fields based on user input in real time

I have a goal to update a field based on the inputs of two other fields. Currently, all the fields are manual input. Below is the code I'm using to try and make the "passThru" field update in real-time as data is entered into the other fields. The ma ...

Maximizing the efficiency of table search with AngularJS filter

Currently, I am implementing pagination in my tables using a library called Angular Table. This library utilizes the ng-repeat directive to create its own array from the data I provide. Due to this implementation, I am unable to utilize the search filter ...

The troubleshooting issue with jQuery animate Scrolltop malfunctioning

My goal is to use jQuery to scroll the page to a specific div when a button is clicked. Despite not seeing any errors in the JavaScript console, the page does not actually scroll to the desired location. I have tried placing the jQuery js file before and a ...

What steps can I take to ensure that the browser prints out a PDF copy of a webpage?

Imagine you have a website page saved as example.html, and also a printable file named example.pdf. Is there a way to prompt the browser to open and print example.pdf instead of example.html when users attempt to print? If this isn't achievable, how ...

What is the best method for checking for JavaScript errors when using Selenium WebDriver in conjunction with NodeJS?

When it comes to coding in JavaScript, not Java, my focus is on running a specific website like foo.com. I typically set it up as follows: var webdriver = require("selenium-webdriver"); By = webdriver.By, until = webdriver.until; var chrome = req ...

Animate the height transition of contenteditable after a line of text is added (using shift+enter) or removed

Currently, the contenteditable attribute is being utilized on the <div> tag to enable autogrow functionality similar to a textbox. Additionally, there is an attempt to incorporate a height transition. While most aspects are functioning correctly, the ...

Ways to incorporate a dynamic HTML form that allows for input elements to be added both horizontally and vertically while maintaining connected lines

Looking to design a form that showcases HTML elements in both vertical and horizontal positions, with lines connecting them as seen in this example: https://i.sstatic.net/jB12f.png. Can anyone offer guidance on how to achieve this? Thanks! ...

Executing a search within the current connection in Node.js

In the code snippet provided, the need is to execute the second SQL query (query2) after constructing it based on the results of the first query (query1). However, even though the second query is successfully built, it is not being executed. Assistance i ...

Tips for showing various column information as tooltips in ag grid's pivot mode

var ColumnDefinitions = [{ headerName: "Column A", field: 'colA', rowGroup: true }, { headerName: "Column B", field: 'colB', pivot: true, enablePivot: true }, { headerName: "Column C", field: ...

I need to find a way to identify when empty JSON data is being submitted to my RESTful HTTP POST endpoint. This issue is causing

I've set up a REST endpoint to handle JSON data sent via an HTTP post request using XMLHttpRequest as my client. Everything seems to be working smoothly until I wanted to test how the server would handle receiving no data at all, specifically null. To ...

Inquiries regarding the vuex dynamic registration module result in a complete refresh of all Vue components

When trying to create a new Vue component, I encounter the issue of having to call store.registerModule() before creation. However, this action results in all existing Vue components being destroyed and recreated. The same issue happens when using store. ...