Reducing DataGrid load time for PDF generation

Is this still the best answer for this problem?

I have an app that allows to either see the preview of the report or create and download it as PDF.

Showing the preview works well. It can require many round trips to collect the required data, but it works.

Printing also works well, but only if the total time for starting the headless Chrome and rendering all the forms, each with its own roundtrip, is less than 30 seconds, which is the case the 99% of the times.

I thought about creating many small PDF files and stitching them together at the end, but this would mean spinning a new headless Chrome for each PDF, which would increase the time from 30 seconds to 30 minutes.

I tried passing the data as an argument to the formā€™s constructor as suggested, but I got an anvil.server.SerializationError error.

My next step will be to try to make my classes portable or create my own serialization and pass a 10MB json string to the form constructor. But itā€™s frustrating to be sitting in front of an app and thinking "this app is working, but I need to spend a few days on it so I can generate that one large PDF that shows up once every 3 months ".

This is roughly what happens when you click the Print and the Show preview buttons:

    def print_click(self, **event_args):
        # render the form and show it in an alert
        anvil.js.window.location = anvil.server.call(
            'create_pdf',
            truck_number=self.truck_number,
            preview_mode=False   # this will hide the PDF footer
        )

    def show_preview_click(self, **event_args):
        # ask the server to render the form as PDF
        print_pdf = PrintPDF(
            self.truck_number, 
            preview_mode=True    # this will show the footer
        )
        alert(self.print_pdf, buttons=[], large=True)

And this is how the PDF is generated:

class PrintPDF(PrintPDFTemplate):
    def __init__(self, truck_number, preview_mode=False, **properties):
        self.truck = Trucks(truck_number)   # triggers one round trip

        self.init_components(**properties)  # uses self.trucks in the databinding

        self.add_component(TruckPDF(self.truck, preview_mode))
        for crate in self.truck.crates:     # generator triggers one round trip per item
            self.add_component(PageBreak()) # anvil_extras.PageBreak
            self.add_component(CratePDF(crate, preview_mode))

Hi Stefano,

Firstly, Iā€™d like to note for posterity that this is an old thread, and the problems we discussed here are solved: DataGrid and PDF rendering is now a lot faster than it was last year (primarily thanks to sterling work from @stucork), so rendering the DataGrids themselves no longer causes PDF timeouts.

Of course, you can still see timeouts if your form loads too slowly (for example, if itā€™s calling server functions that do a lot of computation) - and if thatā€™s what youā€™re seeing then yes, precomputing the data before rendering the PDF is the correct response. It sounds like this is your issue:

Iā€™d suggest getting to the bottom of exactly what nonserialisable data youā€™re trying to send, and seeing if you can make it serialisable - and for that, weā€™d need a little more information about what you tired to do. But that definitely merits another thread :slight_smile:

I apologize for reviving this old tread. The subject does mention the DataGrid, but after reading it with the PDF generation timeout problem in mind, I thought that was the main subject.

And I apologize for crying frustration too quickly. Adding the serialization didnā€™t take days, it was just an hour of work (thanks to the test driven development that allows to work and test the serialization in PyCharm and allows to store all the required data in one singleton, parts of which were already serializable).