App with many pages but not all loaded at once

I want to create an app with many pages but not have them all loaded at once.

I have already tried one based on Material Design, where I had ten items on a vertical menu on the left hand side and each menu item loads a new page.
However by examining the data downloaded to the client browser, all ten pages are downloaded immediately when the browser loads the app, but only the currently selected menu item is visible.

How do I create an app that only downloads the page that the user selects on the menu?
I know how to do this on a plain html website - but how to do it in Anvil?

Anvil apps are single page apps. There is one page only. The app is downloaded (otherwise it couldn’t start), then the app generates the HTML dynamically either for the form defined in the IDE or by dynamically adding components at runtime.

What do you mean by “examining the data downloaded to the client browser”?

1 Like

Stefano,
Thanks for your response.
I am using Python requests (see below) to open the url and download the html, then I examine the html and find that all ten pages have been downloaded, even though none of the menu items have been clicked yet.
Chris

import requests

def getWebPage(url):
headers = {‘User-Agent’: user_agent}
response = requests.get(url,headers=headers)
html = response.content
return html.decode()

url = ‘https://my-anvil-appliaction.anvil.app/
user_agent = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0’

html = getWebPage(url)

As I mentioned earlier, Anvil apps are Single Page Apps, just like Gmail.

In Gmail I can click on the “Compose” button and a form pops up where I can write a new email. Is that a page? Is that downloaded?

In any Anvil app I can click on any button and a form pops up where I can… you get the gist.

Would you say Gmail downloads all the pages at once?


So, going back to your original question:

There is no page to download. Anvil builds the HTML whenever it needs to build it.

Just like in Gmail, some code is executed when the user clicks a button, and often that code removes some HTML elements and adds other HTML elements. Whether it does it by using HTML templates that you created or generating the HTML out of a form that you created in the IDE or by executing a bunch of add_component() to add components to a container, the HTML is generated by the code, it is not downloaded.

Stefano,
So if I am understanding you correctly, if I do not want to see all my content downloaded in the initial call to the app, (as seen by my call using requests, above) I need to create an empty container and dynamically create the content for the container at run-time - I cannot use the Anivil Editor to create the content?
Chris

Well… I guess that is the answer to your question.

But… why do you care about what’s downloaded when?

1 Like

When I plan to have more than 10 menu items, more like 20 which trigger pages each with images, it takes far too long to download when the app is initially called.
Is there any way to use the Anivil Editor to create content that can be dynamically inserted into containers at run-time ?
Chris

I have apps with 100+ forms and they load in 1 second.

The number of forms is usually not a problem, unless they have images.

I try not to add bitmaps in the IDE. If the app needs many images, I put them in a table and load them dynamically.

Also calls to server functions during the startup often slow down the app at startup. The solution is usually creating one single function that returns all the info required packed inside a dictionary instead of calling many smaller server functions.

4 Likes

Stefano,
Thanks for the speed-up tips, I will look into the work-around of storing images in tables and populating them at run-time.
Chris

To add to @stefano.menci’s comments, you can also choose when to import forms which will save you a small amount of time - but its quite small like mentioned above.

You are probably finding that you are getting unwanted server round trips with out knowing it.

Is it that your app is taking too long to load? if so, how long and what does the code look like.

Or is it that you don’t want to have the menu options in the side bar?

If you can give us a bit more information like the reason you don’t want to download all the forms or code snippets or a clone link that would be helpful.

If you can’t then I guess your best option is to try to clarify what the intended goal is first.

Either way, with a bit more information I am sure the community can help you get your intended result.

@rickhurlbatt,
Thanks for your input.
I have made a mockup of what I am planning to build - https://testmd.anvil.app/
When the app is first browsed, 3,716,052 bytes are downloaded, before the user clicks on any menu items. This takes a few seconds, long enough for the little blue dots to start chasing around in a circle in the middle.
Although there are over 10 menu items, I have only populated 4 items in the mock-up. When the site goes live it will have over 10 and will probably grow a new page every month or two.
I have not started on server-side code yet as I do not want to slow anything down until I get the basic structure right.
This is not a sustainable model and I am probably going about it in all the wrong ways.

So what I am asking is, how should I go about creating such a site?

I realise the images are responsible for much of the download time, so can they be stored in a different folder and linked to like normal <img src= tags instead of embedding them as base64 ?
My logo appears on each page, so having just one copy and linking to it would at least save some time?

Maybe Anvil is not the right platform for such a website?

I would be greatful for some pointers and/or some examples.

Many Thanks
Chris.

I took a look at your App’s source and can confirm that Images are the sole reason for the slow loading time of your apps.

There doesn’t appear to be anything in your app that Anvil can’t handle. As for the image issues, I will suggest you to upload them in your Assets file and set the source property of your image to the URL of that image. For example, if you upload image.jpg in your assets, you will have to set the source property of your Image Component to _/theme/image.jpg.

1 Like

I think you can achieve what you want by using the server and loading the content dynamically. This also helps make it easy to add content down the track.
I will try give a but more detail when I am back at the computer.

1 Like

+1 to everything @rickhurlbatt said, I would also say if your use case is “Adding new content every week” it is very possible what you really want is only three forms:

  1. A “Landing page” form that is what you see when you first get to your web address. (A “home page”)
  2. A single form that is a template for all of the content that you would like to display. The content would come completely from information inserted into cells of data table rows.
  3. An admin form that is disconnected from the main app and protected by a login that allows you to upload and add more content (publish new data table rows for #2). This could even pop open a display of what your final content form would look like before you publish.
2 Likes

Have you been through the News Aggregator tutorial? Anvil | Build Database-Backed Apps That shows a sustainable model for building an app whose content changes dynamically, and where the content is not loaded until it’s needed.

1 Like

@ianbuywise Exactly!

@chrisbonnert the best place to start is this tutorial:

The power of what @ianbuywise and this tutorial is alluding to is that content is loaded dynamically.

From looking at your app, you are trying to load all of the code and images before the app even loads. The problem here is no user is going to see all of this straight away so you are loading content unnecessarily.

I think the right way to go about this is to store all the information for the pages in a data table and only load what you need.

For example: you could use the New Beta: Accelerated Tables and the q.fetch_only() query to search your data table and only return a search iterator with the page numbers. This would be very fast.

Then you can dynamically create the menu using this and when you want to view a page, you load the rest of the data on request.

Our app has data tables with thousands of rows but we only care about loading the ones the user is going to use immediately. The rest get loaded dynamically when they are needed.

I am sure if you go through the News Aggregator tutorial you will see that it will do what you need it to.

@jshaffstall you beat me to it :rofl:

Anvil does this all day every day!!

1 Like

@divyeshlakhotia, Thanks, I will experiment with this technique.

@jshaffstall, @rickhurlbatt, @ianbuywise - Thanks guys - I will take a look at “Build Database-Backed Apps”.
Chris

1 Like