Startup form takes TWO MINUTES to load, after it's loaded, everything else is super fast

What I’m trying to do:

[on individual-monthly plan]

The startup from of the website I have made takes more than 2 minutes to load the first line of its code.

What I’ve tried and what’s not working:

I tried printing what happens in the code. So I started by adding a print in the first line of the code as well as important sections. It takes more than 2 minutes for the first print() in the first line of the client side to show up in the terminal. Anyone with the similar problem or a solution to it?

I’d really appreciate any help cause my web service is useless right now :roll_eyes:

Here is all the code of my startup form:

Code Sample:

print('[START OF IMPORTS]')

from ._anvil_designer import Form1Template
from anvil import *
import stripe.checkout
import anvil.facebook.auth
import anvil.google.auth, anvil.google.drive
from anvil.google.drive import app_files
import anvil.server
import anvil.users

from .._pack_all_orders.all_orders import all_orders
from .._pack_landings.bifurcation import bifurcation
from .._pack_landings.ground_zero import ground_zero

from .._pack_loginform.login_popup import login_popup

print('[END OF IMPORTS]')

class Form1(Form1Template):

  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    
    
    
    #anvil.users.login_with_form(allow_cancel=True,show_signup_option=True)
    self.show_links()
    self.role = 'secondary-app-bar'

  def show_links(self):
    if anvil.users.get_user():
      
      self.content_pan.add_component(bifurcation(),full_width_row=True)
      
      self.sign_out_link.visible = True
      self.orders_link.visible = True
      self.sign_in_link.visible = False
      self.make_order_link.visible = True
      
    else:
      self.content_pan.add_component(ground_zero(),full_width_row=True)
      
  
  def sign_in_link_click(self, **event_args):
    """This method is called when the link is clicked"""
    
    #WAS THIS: anvil.users.login_with_form(allow_cancel=True)
    # BECMAE THIS>
    
    alert(content=login_popup(), title="",
             large=True, buttons=[])
    
    
    if anvil.users.get_user():
      self.show_links()
      self.content_pan.clear()
      self.content_pan.add_component(bifurcation(),full_width_row=True)
      
      
      

  def make_order_link_click(self, **event_args):
    """This method is called when the link is clicked"""
    self.content_pan.clear()
    self.content_pan.add_component(bifurcation(),full_width_row=True)
    

  def sign_out_link_click(self, **event_args):
    """This method is called when the link is clicked"""
    anvil.users.logout()
    open_form('Form1')

  def orders_link_click(self, **event_args):
    """This method is called when the link is clicked"""
    self.content_pan.clear()
    self.content_pan.add_component(all_orders(),full_width_row=True)```

This problem might be caused due to your Native Libraries or because of too many images. Can you check the following things and reply here

  1. Check what is there in your Native Libraries. You might have added many Javascript Libraries to it.

  2. You can also download your project as a .yaml file. Can you do that and tell me the size of your yaml file?

I just did:

1- the imports you see in the code are just other forms I made to display data (nothing heavy: normal bottoms, cards, text lables)

2- the yaml file is 5.8 MB

No, I’m talking about your Native Library.

Also, do you have images in your anvil project? You may have uploaded them in your assets or to the source property of image.

Because I noticed in my case that these images slowed down the loading time of my website

If you have used images, it is suggested to replace them with direct links. You can upload them to Google Drive or Uploadcare or Imgbb and then paste their direct links to image source property instead of uploading them directly.

Ah, sorry my bad
However, there is no usage of native libraries in my app

On the other hand I have uploaded almost all the images to the asset folder. I’ll move the images to a hosting service and use the url in image_source to see if it helps

Sure. Let me know if it works. My website had this issue once as well. And hosting images elsewhere fixed the problem for me.

1 Like

It appears that you create a lot of components using code and that takes a lot of time. I have in my app a Menu that is dynamically created using code. Each Link() creating takes half second which adds up to make the app startup to be very slow.

how did you go about it?

I don’t know how making Links is taking time for you. Because this loop gets completed in less than a second for me.

for i in range(100):
        L=Link()
        self.add_component(L)
        print('Done')

And besides, the loading time, in this case, happens before the form is even loaded so no Links have generated yet.

That’s true
I’m now moving all the images to external hosts and will report back how it worked for me

Do you know where the images that I directly upload from the property editor end up? They are not in assets.
I’m replacing their source link but will it remove them from Anvil too?

Screenshot 2021-10-19 at 15.14.38

These images do not end up anywhere. They simply get converted into base64 strings which are basically all the data inside an image converted into a very long string.

If images are what is causing your app to slow down, all these base64 strings have an impact on it. So when testing, it is best to remove them with direct links.

Got it! Thanks a lot :ok_hand:t3:

I removed all the images from the assets. It now takes 33 seconds to run the first line of the startup form. The yaml file is now down to 1.5 Mb (from 5Mb). Any thoughts ?

The 33 second time to load varies from run to run , with upper values of around 45 seconds and lower values of around 30 seconds

Glad to know things are working out for you. First you’ll have to make sure that none of your images has source set to a Base64 string but is replaced with direct links.

Once you have ensured that, I don’t think you can do much more. Also, is your app large? How many forms does it have?

Because the more forms you have, the slower your app gets. Also, I’m not very sure about it but since every code you write is stored in your .yaml file, it might have an impact in loading time as well. So you’ll have to make strategies to reduce the code. Although of course it will have very little impact.

1 Like

I have around 30 forms in my app. All are pretty simple .
I checked the timing again and is now around a minute again. This is kinda frustrating

I have over 150 forms. My app starts up in about 12 seconds.

From your first post, it looks like you might be importing some big files unconditionally. You probably don’t need stripe, facebook, and google for every function in module Form1. You may be able to delay importing those files, by importing them in just those few functions that need them. That way, the import is deferred until the function is actually called.

This technique also works for Server-side and Uplink code.

Edit: It’s more important for Server-side code, because that code gets terminated and re-loaded. A lot. In most apps.

importing stripe and google or fb happen after the page is loaded or ?
I mean it takes a minute to get to the first print on the first line of my startup form

In normal python, everything is compiled from top to bottom, so if you have imports at the top they will load first, then your classes or functions will compile etc. (If that is what is next).

Also in normal python, although it is considered bad form, you can do an import at any time in the script, and if you call it multiple times, for instance as if it were in a function, each time it was called.
There is a slight overhead where it checks to see if it has already been imported, but other than that, it skips importing it over and over. (which in your case might save time).

I have not noticed many, lets call them ‘edge cases’ regarding skuplt, so I assume this should still work as expected in the client side of anvil.

I also wonder what happens if you put the import inside a context manager:

with anvil.server.no_loading_indicator:
  import this #  For example

…would it import while still letting the user interact with the page?