Hi everyone. I thought it might be useful to start a thread for speed-related tips. What we have found through knowledge or experience that helped our apps run faster and smoother…
I have a question regarding images. Do images load faster from certain components? Someone had previously mentioned that they noticed the images in Title components load instantly.
What should we be mindful of when using images in our apps?
Jeff, Darren and Thinh have written quite a bit about app performance in the forum over the years. You’ll usually find Jeff’s explanations in topics with the keyword “performance”.
I have a tendency to forget the intricacies of what makes an app more performant. A few months ago I wrote up the following, it’s fairly basic and common sense. Unfortunately I don’t go into detail, details that might actually make a difference, precisely because I cannot retain them.
Regardless, the following might be a decent addition to this topic. Thanks for starting it, great idea, app performance is a recurring topic in the forum.
A self relation is a relation that relates a column to itself. Now that I think of it, I’m not sure if it makes a difference if the self relation is “match multiple” or not (what I called “single”).
The self relation used to be used quite a bit, basically you can create a unique list within a table where you otherwise would have duplicates. It was useful to create reports for instance. Now I would use the query column.
My guess is that it cannot hurt to try to optimize images like Wix recommends.
I believe Glide also optimizes images under the hood.
I’ve never done it, but the following experiment could be interesting: upload a non-optimized image, navigate to the web app and then inspect the image on the page or download it. I would not be surprised if the image type, resolution and size were all optimized.
Yes the delivery of images in Glide is optimized using cloudinary. But you can compress images before upload, to further enhance optimization (image size reduction at display)
if (p1) {
function generateHtmlFromCsv(csvString) {
const imageUrls = csvString.split(',');
// Start building the HTML string
let html = `<!DOCTYPE html>
<html>
<head>
<title>Inline CSS Example</title>
</head>
<body>
<div style="display: none; flex-wrap: wrap;">`;
// Create a div with specified style for each image URL
imageUrls.forEach((url, index) => {
html += `
<div style="flex: 20%; padding: 5px;">
<img src="${url.trim()}" alt="Image ${index + 1}" style="width: 100%; height: auto;">
</div>`;
});
// Close the HTML string
html += `
</div>
</body>
</html>`;
return html;
}
// Assuming p1 contains the CSV string of image URLs
const csvString = p1;
// Call the function and return the result
return generateHtmlFromCsv(csvString);
}
I see in the linked thread you mentioned to avoid duplicating collections and then using visibility conditions and filters on those.
Is processing a single table in different ways the cause of the slow down?
Also, does invisible data still have “weight” on a page?
TIPS FOR ENHANCING SPEED AND PERFORMANCE IN GLIDE APPS
Improving the speed of your Glide apps is crucial, especially as they grow and handle larger datasets. Here are five effective tips for boosting the performance of your Glide apps:
Minimize the Use of Queries:
Avoid using Queries as much as possible and opt for Relations instead. Queries require more processing time and can slow down the app, while Relations can provide the same result more efficiently.
Separate Apps for Different User Types:
Creating separate apps for each user type allows you to use Row Owners, which reduces the amount of data loaded onto the user’s device, enhancing the loading speed of pages and components.
Compress Images Before Uploading:
Large images can significantly slow down the app’s loading time. Use image compression tools before uploading to ensure faster page loads for image-heavy content.
Use Glide Tables:
Prefer Glide Tables over external data sources like Google Sheets or Airtable. Glide Tables load faster and reduce the user’s waiting time.
Remove Irrelevant Components and Pages:
Removing components and pages that are not relevant to each user allows for a smoother and faster user experience. Fewer data and components loaded onto the device result in better speed and performance.
These principles, among others, can significantly enhance the user experience of your Glide apps, ensuring fast and efficient performance.
I was wondering about the impact of tabs, collections, page size and screen type on app speed. Do you guys have any thoughts or experiences to share on the following:
Tabs
Let’s say we have 5 collections showing different data based on relation columns… Could app speed increase if these collections are separated into their own tabs, as opposed to being visible on the same tab?
Page size
It’s intuitive that reducing page size would increase page speed but I haven’t seen any noticeable change in speed when I varied this number. Does it make a difference?
Screen type
We can use actions to open a number of screen types and I usually just choose which appeals my design taste but are there implications on memory usage or any other speed factor depending which screen type we select?
Tabs can have a benefit in some cases because some tables may not run computed columns until necessary.
Less content on a page can have a benefit as there is less to render.
I really don’t think this has an effect.
I think the largest speed issues will depend on how your data is structured. Any computed columns that rely on the values of computed columns in multiple other rows will have a large impact. Ask yourself this question…will displaying something on a screen require multiple relations, queries, lookups, etc to process though all rows and computed columns in one or more tables. If you are asking your app to process all computed columns in thousands of rows at once, then it will take a few seconds to process all of that data initially before it can be displayed on the screen.
The best way I can sum it up is with the below post I made in a private moderator thread, so I don’t think it was ever posted publicly.
Just going to drop random thoughts here based on my observations over the years, and possibly edit as I think of more:
First I’ll start with a somewhat quick overview of my app setup and one part of it that’s been a pain point regarding speed, but also helped me learn a lot of optimization techniques.
Part of my app deals with lessons and billing for those lessons. I have 3 tables (Billing Cycle, Lessons, and Billing List)
Billing Cycle - A coach can add a row with start and end dates to determine a particular billing cycle.
Lessons - Each student lesson is recorded along with a date.
Billing List - This is a merge of unique students per billing cycle. A student can have multiple lessons within a particular billing cycle, but I just need one unique row per student/billing cycle, so I can create a student total amount for that billing cycle.
Lessons can be added before a corresponding billing cycle is added, so all of these connections happen on the fly.
The flow for a coach in my app is that they view a list of billing cycles. When they click on a particular billing cycle, they see a list of students that were taught lessons during that billing cycle (sourced from the Billing List table). When they click on a student, they see a list all of the lessons taught to that student in that billing cycle. Previously the Billing List table was built in the google sheet with some ugly logic. Recently I converted the Billing List table into a helper table that only ever shows information for one selected billing cycle instead of all of them, which sped things up. This also allowed me to remove some logic from the lessons table which is my largest table. I try to minimize computed columns in my Lessons table because it can have a large effect on it’s response time.
The above setup has been an ongoing challenge for the last 5 years. Not lighting fast, but considerably better and I’ve learned a lot from it.
Computed columns are only computed when they are needed. Not necessarily when the app loads.
Query can be substantially slower than Relations, but is sometimes necessary. Building a relation that involved a range of dates was a bit of a nightmare and involved a lot of extra computed columns to achieve. Query handles it beautifully with a single column. Query can be better than a Relation…especially if it takes a lot of extra computed columns to accomplish the same thing with a Relation. Depends on the case.
If possible, use Queries in the smaller of two tables. I had a case where I created a query in my Lessons table (large table) just to get a Lookup of a billing cycle ID that I could then use to link the Billing Cycle and the Lesson tables together. This brought my app to it’s knees causing the browser to crash. I instead put the query in the Billing Cycle table because it’s a much smaller table, ending up with a Lookup of Lesson ID’s which I could still use to link the two tables together using a regular Relation, which is much faster.
Most computed columns on their own are not bad as they are typically calculated quickly and only as needed, but if a computed column is used in a Relation or Query, I believe this can cause an entire table or several tables to calculate everything all at once. Not good for large tables with lots of calculations.
Filtering or Sorting on computed columns will cause the entire table to calculate and slow things down.
Rollups, Joined List, Single Value, etc on computed columns could cause the entire table to calculate.
Javascript seems generally slower compared to native computed columns.
Lots of images can increase load time, but I don’t think it necessarily affects the interface, which still load…it just takes a bit to download and cache the images, which can render after the rest of the interface has loaded.
Keep the first tab of an app light with minimal information displayed on the screen. If the first tab depends on a lot of rows of data to process through all of their computed columns just to get results, then the initial load of the app will be slow. If the content on the first tab is kept to a minimum, then there is a better chance of the app loading up quickly. There may be other tabs or screens that take longer to load when computations are ran on demand, but the overall impression of the app may be better.
It’s not always about your internet speed. Your connection speed to a local server in your region may be great for a speed test, but it could be a lot of hops from your computer to the Glide servers. From my computer to Glide servers, it takes about 8 to 9 hops over various local and global networks for data to transfer between Glide and me. It’s not always your end or Glide’s end. Sometimes it’s the various networks in-between that may be experiencing problems.
I think a majority of speed issues are linked the the amount of data and if a computed column depends on the results of other computed columns in every row of one or more tables. If something causes a lot of rows of data to calculate, then it can take several seconds for an app or a particular screen to load.
wow, thanks for this insight @Jeff_Hager ! I have a lot to think about regarding my data structure. Admittedly, i use lots of “simple” computed columns throughout my app (connecting them everywhere via lookups, make arrays, etc.) so I definitely need to rethink my strategy… I had thought that Queries were the main culprits in reducing speed but I could have shot myself in the foot in many other ways.