Skip to content

JsPdf is saving a pdf but takes too long time to show it in google chrome #3137

Description

@stounej

I'm using JsPDF to download an html styled element, but when it is downloaded, it takes too long to be showed in google chrome as pdf (shows just an empty pdf document at first and charge it after long time),

the size of the file is only 300KB, I don't know why I have this problem however it's showed correctly in mozilla firefox browser

Please do you know how could I solve this problem.

this is my code

generatePDF = () => {
var doc = new jsPDF('p','pt',"a4");
const inp = document.getElementById("cv");
doc.html( inp , {
html2canvas: {
scale: 0.75,
},
callback: function (doc) {
var pageCount = doc.internal.getNumberOfPages();
doc.deletePage(pageCount)
doc.save("download.pdf");
}
});
}

this is the pdf file:
downloaded.pdf

Activity

  1. HackbrettXXX commented on Apr 20, 2021

    @HackbrettXXX
    Collaborator

    Please attach the PDF document.

  2. stounej commented on Apr 20, 2021

    @stounej
    Author

    I have edited my post and included the pdf document, this is the code rendered in the pdf document:

    import` '../App.css;
    import personalInfo from '../Contexts/personalInfo';
    import Grid from '@material-ui/core/Grid';
    import {Typography} from '@material-ui/core';
    import clsx from 'clsx';
    import {makeStyles} from '@material-ui/core/styles';
    
    const useStyles = makeStyles({
      paragraphes: {
        fontSize: "12px",
        overflow: "hidden",
        whiteSpace: "pre-wrap"
      },
      Typography: {
        textAlign: "center"
      },
      title: {
        fontSize: "20px",
        marginTop: "45px",
        textAlign: "center",
        fontFamily: "bold",
        backgroundColor: "#96b0bc",
        color: "white"
      },
      dates: {
        marginTop: "40px",
        fontSize: "12px",
        marginLeft: "13px"
      },
      h4: {
        fontSize: "15px",
        fontWeight: "bold",
        marginBottom: "8px",
        marginTop: "10px"
      }
    });
    
    //width: "21cm",height:"29.7cm"{width: "248.0px",height:"350.8px"
    function PaperA4() {
      const classes = useStyles();
      return (
        <div class="page" data-size="A4" id="cv">
          <personalInfo.Consumer>
            {({
              fullname,
              email,
              phone,
              address,
              zip,
              city,
              country,
              driving,
              status,
              nationality
            }) => (
              <Grid container xs={12} direction="column" justify="center">
                <Grid
                  item
                  xs={12}
                  justify="center"
                  alignItems="center"
                  style={{
                  lineHeight: "5px",
                  marginTop: "20px"
                }}>
                  <Typography align="center" variant="h5">{fullname}</Typography>
                </Grid>
                <Grid item xs={12}>
                  <Typography className={clsx(classes.Typography, classes.paragraphes)}>
                    {email}&nbsp; {phone}&nbsp; {address}
                    &nbsp; &nbsp; {city}
                    &nbsp; {country}
                    &nbsp; {nationality}
                    &nbsp; {status}
                    &nbsp; {zip}
                    &nbsp;{driving}
                  </Typography>
                </Grid>
    
              </Grid>
            )}
          </personalInfo.Consumer>
          <Grid container xs={12} direction="column" justify="center">
            <Typography className={classes.title} variant="h5">Professional Experience
            </Typography>
            <personalInfo.Consumer>
              {({experience}) => (experience.map((exp, i) => {
                return (
                  <div key={i}>
                    <Grid container xs={12} spacing={false}>
                      <Grid xs={3}>
                        <Typography className={classes.dates}>
                          {exp.startdate}-{exp.enddate}<br/> {exp.city},{exp.country}
                        </Typography>
                      </Grid>
                      <Grid xs={8}>
                        <Typography className={classes.paragraphes}>
                          <Typography className={classes.h4}>
                            {exp.job}
                            <br/> {exp.employer}
                          </Typography>
                          {exp.description}
                        </Typography>
                      </Grid>
                    </Grid>
                  </div>
    
                )
              }))}
            </personalInfo.Consumer>
          </Grid>
          <Typography className={classes.title} variant="h5">Education
          </Typography>
          <personalInfo.Consumer>
            {({education}) => (education.map((edu, i) => {
              return (
                <div key={i}>
                  <Grid container xs={12} spacing={false}>
                    <Grid xs={3}>
                      <Typography className={classes.dates}>
                        {edu.startdate}-{edu.enddate}<br/> {edu.city},{edu.country}
                      </Typography>
                    </Grid>
                    <Grid xs={8}>
                      <Typography className={classes.h4}>
                        {edu.degree}
                        <br/> {edu.school}
                      </Typography>
                      <Typography className={classes.paragraphes}>
                        {edu.description}
                      </Typography>
                    </Grid>
                  </Grid>
                </div>
    
              )
            }))}
          </personalInfo.Consumer>
    
        </div>
    
      );
    }
    
    export default PaperA4;`
    
  3. HackbrettXXX commented on Apr 22, 2021

    @HackbrettXXX
    Collaborator

    The performance issue seems to be that each letter is written as a single chunk of text. Why that is, I don't know, yet.

  4. stounej commented on Apr 22, 2021

    @stounej
    Author

    I tried to transform the document to an Image before saving it and it worked but the text inside the pdf can't be copied,
    I need the text to be copyable.

  5. gkurt commented on Jul 26, 2021

    @gkurt
    Contributor

    Seems like if there is letter-spacing in CSS, this will happen. Here is the workaround I am using to remove letter-spacing for PDF:

            onclone: async (d: HTMLDocument) => {
              const styleSheet = `
                * {
                  letter-spacing: initial !important;
                }
              `;
              const style = document.createElement('style');
              style.innerText = styleSheet;
              d.head.appendChild(style);
            }
  6. kevinmelo commented on Sep 10, 2021

    @kevinmelo

    Any return? have the same issue

  7. gkurt commented on Oct 1, 2021

    @gkurt
    Contributor

    In addition to letter-spacing, too many words can also cause this issue. When letter-spacing is not 0, each letter is rendered separately. But when it is 0, html2canvas renders each word separately and that still makes the PDF size grow too much and cause performance problems.

    I created this PR in html2canvas which significantly improves the performance by rendering multiple words in a line together.

  8. CollenZhou commented on Dec 20, 2021

    @CollenZhou

    I have the same problem. The pdf generated from html is loaded very slow by chrome and edge and scrolling is choppy.

  9. DanLopess commented on Dec 20, 2021

    @DanLopess

    Hi, @KurtGokhan I've tried the mentioned solution of removing the letter-spacing but it made no difference. The PDF is still extremely choppy on chromium browsers (e.g. Edge is a chromium browser).

  10. gkurt commented on Dec 20, 2021

    @gkurt
    Contributor

    @DanLopess

    In addition to letter-spacing, too many words can also cause this issue.

    One workaround I found is to render the text to an image, and print that into PDF. But text will not be selectable in the PDF if you do that.

  11. DanLopess commented on Dec 20, 2021

    @DanLopess

    @KurtGokhan Yeah unfortunately that wouldn't be ideal. However if I did that, since my HTML converts into multiple pages the image would have to be split (still haven't figured out how to do that) and I would have to calculate how many pages would be needed.

  12. CollenZhou commented on Jan 6, 2022

    @CollenZhou

    Hi dear authors any update?

  13. CollenZhou commented on Jan 7, 2022

    @CollenZhou

    Hi, just FYI. I noticed if a single table cell contains too much text will cause the performance issue. Hope it helps.

  14. github-actions commented on Apr 8, 2022

    @github-actions

    This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

  15. prasheel888 commented on Oct 18, 2022

    @prasheel888

    Also having the same issue, Any Suggestions guys??

  16. kevinmelo commented on Oct 18, 2022

    @kevinmelo

    Also having the same issue, Any Suggestions guys??

    At the end the best solution was using Puppeeter with my nodejs backend

  17. prasheel888 commented on Oct 18, 2022

    @prasheel888

    Also having the same issue, Any Suggestions guys??

    At the end the best solution was using Puppeeter with my nodejs backend

    Thanks For Suggestion!!

  18. haaah commented on Jan 3, 2024

    @haaah

    trying @KurtGokhan css hack does improve the rendering speed a little but when there's Word Starting With Upper Case it will sometimes join 2 word together --> WordWord.

    Is there any other workaround ?

  19. adamturski commented on Feb 28, 2024

    @adamturski

    In my case generated PDF was loading fine in Ubuntu Document Viewer, but not in Chrome PDF viewer. Rendering was slow for some pages, visible especially on scrolling (but also on load if I put problematic element on first page). I could narrow down the issue to border-radius style on my table element. If text was short then there was no issue, but for long texts it was loading very long (forever). I set border-radius to 0 on my table container class and problem disappeared. I do not know why is that.
    I also played with letter-spacing style and set 0 globally, but it helped just a little I would say - finally border-radius solved the issue.

    Html:

    <div id="exported-content">
            <div class="table-container">
            <table>
                <tr>
                    <td>Test</td>
                    <td>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec purus feugiat, molestie ipsum et, consequat nibh. Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo. Fusce malesuada vulputate faucibus. Integer in hendrerit nisi. Praesent a hendrerit urna. In non imperdiet elit, sed molestie odio. Etiam auctor sit amet odio et luctus. Quisque in massa a libero luctus suscipit. Cras metus purus, iaculis ut aliquam non, varius quis nibh. Quisque a interdum augue. Nam ut nibh mauris.
                    </td>
                </tr>
            </table>
            </div>
     </div>
    

    Css:

    .table-container {
        border-radius: 8px !important; // !!! This line was causing an issue with rendering PDF in Chrome.
        overflow: hidden;
        background-color: white;
    }
    

    JS:

    new jsPDF({
                orientation: 'p',
                unit: 'mm',
                format: this.paperFormat,
                putOnlyUsedFonts: true,
                compress: true,
            }).html(document.getElementById('exported-content'), {
                html2canvas: {
                    async: true,
                    letterRendering: false,
                    logging: true,
                    removeContainer: true,
                },
                callback: (doc) => {
                    doc.save("test.pdf");
                },
                margin: [15, 15, 15, 15],
                autoPaging: true,
                width: 180,
                windowWidth: 1080,
            });
    
  20. Amatewasu commented on Feb 28, 2024

    @Amatewasu

    @adamturski Thank you for the update. I just tested and I reproduce that removing the border radius in my generated pdf make them way faster in chrome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions