Prevent Modules from Loading On Start-Up

I've been embedding modules within modals or tabs. On app start up the modules and all their queries run. Is there a way to prevent this? This results in a major hit in performance based on the new Performance debug tab.

Hello there.

I've been working with child module instances inside of parent modules and parent apps for my use case, so believe me, I know the struggle!

So as far as I know, Retool does not have a way to lazy load child module instances within an app or module. The module components themselves will always be rendered immediately at pageload. I do believe that this is something on the roadmap or that they're at least looking at this.

However, here are a few things you can do to make sure the queries from those modules are only loaded at an optimal time, and some of my best practices I've learned about using modules:


If all the queries that are encapsulated within that child module only needed to be triggered by events that also occur inside the module...


Make sure all of the resource queries or JS queries that are encapsulated within that child module are set to, "Run query only when manually triggered":





Also, make sure all your child module's resource queries or JS queries have the "Run this query on page load?" option unchecked in the Advanced tab:
AdvancedTab


...then you are good to go. :metal:


But if those queries need to be triggered by events that occur outside the module...


There are 2 scenarios:

  1. For resource queries (non-JS queries) that explicitly reference values from the parent app,



    you actually now need to set it to "Run query automatically when inputs change", and make sure {{ ParentAppResult.value }} is a module data input that will access this value from the parent.


    If we stopped here, the query would run automatically at page load, so to avoid that:
    in the Advanced tab, set the "Disable query" field to whatever you expect the default value of that data input to be, at page load.
    AdvancedTab


    To be safe, I always put:

    {{ ParentAppResult.value === null || ParentAppResult.value === '' }}
    



  1. For JS queries that explicitly reference values from the parent app,
    OR
    For JS Queries/Resource Queries that do not reference any values from the parent app, but still need to be triggered from the parent


    If there is an option, set the query to "Run query only when manually triggered”,
    TriggeredQuery



    and then use a separate ‘Query JSON with SQL’ query to act as the listener.
    TriggeringListener



    The ‘Query JSON with SQL’ will be the same setup as what we just did in #1:
    "Run query automatically when inputs change",
    explicitly reference the data input you want to watch,
    and disable the data input’s default value at page load.

    Finally, we add our JS Query or Resource Query as a success handler to that ‘Query JSON with SQL’:




An important thing to remember is that, as of right now, the Watched Inputs feature in the Advanced tab (which is designed to allow you to add ‘auto trigger’ exceptions to a query that is currently set to ‘manually trigger’) ONLY works within the module scope itself. It does not work on module data inputs that are being changed by the parent.

If you ever need to trigger anything inside a module in response to that module’s data inputs, the only way to do that is by setting a resource query to "Run query automatically when inputs change", referencing the data input within the query, and then disabling the query during page load using the Disable Query field in the Advanced tab.
And that resource query can either be the query itself, or, (in the case of all JS queries, or resource queries that don’t explicitly include data inputs in the query definition) that resource query can be a separate triggering listener.


-Alex

2 Likes

Thanks AJ, I'll try it out and let you know.

this is a great method for module inputs, just don't use it on custom components (the only other thing w inputs, so some ignorant fool might think they would work the same.... they don't and I'm that fool :sunglasses: )

I had a query in my parent app trigger on changes to the components input (customComponent1.model.myVa)r and found out that if ANY input variable, even if ones that don't trigger the query are updated with duplicate values it will trigger the query. This also means if your query updates the model, and the query is triggered by any attempt to set any input value, you end up in an infinite loop of doom.... just pray you don't have it hooked up to an API that uses tokens. I forgot to disable a fetch and blew through $40ish in about 5 sec lol

if this is too far off topic feel free to flag (or msg me, i'll delete it), I just thought if you end up playing around w the custom components because they have inputs also you could try using instead of a module that you might like to know the difference beforehand :beers: