Best practice structure for (social media) links

I am building a directory, where every location has several links, like social media profiles. I want to display the icons with the respective link behind on the profile of the locations.
(I will be starting with 1500 location profiles that I take over from the current WordPress-based directory, expecting it to grow to 10’000 and beyond)

Now I am wondering what is the best way to build the structure from a performance / workload perspective?

The possible ways to structure I think of at first sight are:

  1. Add a text field for every social media link to the location datatype, e.g. “facebook URL”, “instagram URL”. On the location profile page, I add every icon with a window.open javascript, and visibility based on whether the field is empty or not.

  2. I create a separate “links” datatype, with fields like URL, link type (an option set I guess, with facebook, instagram etc.), and connected location. On the location page, I do a search for links that are connected to this location and list them using the icons which I have defined in the link type option set.

  3. I create the “links” datatype similar to 2, but I store the list of links also in the location datatype.

So while the first is “simple” in structure it might need power with the conditional display (and is not very elegant when I add other datatypes that need the same set of links), the second is somehow slick but will use power for the search…
Hence I am wondering which is the best solution in terms of performance and workload based on your experience?

Or is it maybe a method #4 of which I haven’t thought of? :sweat_smile:

Thank you for sharing!

This one, and store the List of Links data type as a list on the Location data type.

Have data fields on a data type that you label something like ‘fb_id’, ‘tk_tk_id’ and on those just simply save the URL ID portion since all social media sites are likely building the same base URL and everybody that has a page on that social media site would just be appending to the same base URL an ID value that corresponds to their page.

And since WUs are consumed most by searches due to the number of characters returned per item returned, you can reduce your WU consumption on searches by reducing the number of characters you return per search.

Additionally, since the number of social media sites is not infinite, you will likely have a small set (5-10 tops) that will be in use, so you can simply in the text element you will be showing the links from (or link elements) hardcode (ie: use static text) for the base URL of the social media site followed by the dynamic portion of the link which is the ID which is retrieved via the fields on the data type.

This is best way to do this from a performance / workfload perspective as it reduces the need to download from the server the extra unnecessary characters that exist for the base URLs (and importantly shorthand script the fields too as those count as characters returned) and it thusly reduces the time required to download the data (although not much) and since those fields are on the data type that is likely the data type for the page in your app, you do not need to perform any other lookups, and since you hard code the base URLs into the elements, you do not add to the overall time of app loading by having unnecessary option sets involved (although they do not add a lot).

I assure you, the load time of option sets at this scale is so negligible that it’s not even worth considering at all.

Link data type

  • id
  • Site (Option Set)

Site option set

In a repeating group, to show a list of profiles, show Location’s Links.

You’d be unwise to hardcode fields onto the data type as you’ll have to manually update things everywhere in the app that they’re used every time you want to add/remove a social network.

In addition, having an element in the editor for each possible social network is a pain in the ass for maintainability versus a simple repeating group that will display any socials that the location has.

Option set load negligible,

Each character returned from db also negligible

I would horizontally expand location, creating a links data type attaching, limiting the customers by 4-5-6 links, just because dealing with lists with Bubble is disgusting + a location can have its own website. I would regex check https://x.com/ or https://twitter.com/ for twitter, find & replace https://twitter.com/ with blank while saving to database and in the user facing part I would add that https:/x.com/ part to the saved text to link https:/x.com/‘‘locations’links’twitter’’

and for the owners website just find&replace https:// part add to it later,

@georgecollier @emir.ozgun The question from OP was pretty clear and I think you guys may have misread it

So, @georgecollier

No, this is not an optimized approach for performance and WUs. In fact, it is adding extra overhead to both WUs and performance due to the fact that now, instead of a single data type of ‘location’ you are adding a second and unnecessary data type of ‘link data type’ which makes it so that instead of being able to update the single data type of ‘location’ with all fields (the optimized for WU and performance approach I outlined has the fields of ‘fb_id’ ‘tk_tk_id’ etc as fields on that same location data type) and be able to incur the WU costs of updating just a single data type instead of two. So for every single time every single location needs to have links, if we took the unoptimized approach of using a second data type of ‘link data type’, the app owner would be paying the 1.62 WU for each make changes to thing, and in this unoptimized approach, unfortunately, due to the structure of this unnecessary second data type, there would not need to be just one extra make changes to things workflow, you’d have an equal number of unnecessary make changes to thing or create thing actions (each costs 1.62 WUs) for each link. What that means is if on creation, we assume the user will provide 5 links for one location, there will be 6x1.62 WUs instead of just 1x1.62 WUs.

What this means, is if we do not consider the entirety of an application and what it needs to do, and instead just focus on the retrieval of the data, we can build an application that is not optimized for WUs and performance. Sure, the modularity of the ‘link data type’ might make it easier for the developer, it doesn’t actually cost less WUs, it costs more WUs and it reduces performance.

This is true not just for the creation/modification of the data, but also for the retrieval, because although this secondary link data type will be added as a list field to the main data type of ‘location’ (and if not than that structure of link data type needs an additional related field of location), all fields, inclusive of the created by, created date, modified date and slug will be returned, with the prefixed values Bubble applies to data fields (thusly increasing our WU consumptions for each character returned).

Absolutely no difference between using an option set, since option sets are just hardcoded into the option set, rather than onto an element on a page. And if we are thinking properly about the feature, it is likely a best practice to build it modularly, so a reusable element that is used only for displaying links on the location profile page. So the difference of needing to just hardcode onto an option set and cause it to be loaded on every single page of the app, or onto the reusable element to display links, it is no more or less cumbersome when adding or removing, because I personally couldn’t imagine there being a need to display this information anywhere other than on the profile as the OP has stated.

Ahh but creativity plays a role in coming up with valid solutions for perceived negatives (but also helps to focus our attention on resolving the issue at hand as the OP asked in regards to performance and WU optimization).

Create a repeating group, make the data type text, use arbitrary text, add all of your social links (again likely 5-10 tops) comma separated, and then in data source expression after arbitrary text, use split by comma…so now, we have a repeating group, and no need to have a single element for each possible social network…and again, the ‘pain in the ass’ is not what I believe the OP is concerned about, they are concerned and asked the question about what is the most optimal way in regards to WUs and performance, not maintainability or extendability (both are the same between one reusable element and an option set, but if the OP does intend to use it in more than one place than maybe an option set is a better approach for maintainability and extendability…but who are we kidding here, social media links are not needing to be extendable, there is not even half a dozen social sites that people use regularly on apps for linking…and even if we needed to, going into a reusable element and adding it to the list in the RG arbitrary text versus going into option sets and adding it there is negligible at best)

This is true, it is not by much and could be considered negligible, but as the OP asked for optimized WU and performance, it must be stated as the most optimized approach as it is that. I mean we can consider how negligible things do not really matter much in some cases and in others it is the difference between being right or wrong, 1st or second…in Basketball a score of 101 to 100 the 1 point differential is negligible, as it is only 1% of the team score or 0.5% of the combined number of points scored, but that 1 point is the difference between the winning team and losing team. So every little bit counts when considering what is optimized for WUs and performance and what is not.

Thanks for chiming in @emir.ozgun …it is true that a few characters returned is negligible for a single fetch, but consider how an app is likely going to have more than one location to display and more than one user searching on more than one day in the month, and you’ll begin to grasp the concept of how ‘things add up’ even if those ‘things’ are adding up in small quantities, they can aggregate to a larger number over the course of a month.

Not an optimized approach for all the reasons I point out to @georgecollier why that is not an optimized approach, although yours is slightly different and more performant than Georges since you are suggesting adding all potential links as fields to the extra data type instead of just one field for ID and therefore a need to have as many data entries in the database as there are links for each location. Neither of those approaches is optimal from WU perspective or performance perspective.

Also, why bother to complicate things with regex for each of the potential social links.

@georgecollier @emir.ozgun although, yes, both of you are correct to point out (as I already had) that the differences are negligible, you seem to ignore the OP question. If the OP asked what is an optimized approach for maintainability, flexibility and extendibility, my answer would be different, but the OP asked about optimized for WU and performance.

I personally find it important to answer peoples questions first and if I feel the need to advise them on other issues I find important I can follow it up with caveats and offer other things to consider, since maintainability, flexibility and extendibility are important things to consider, but we must consider these things on a case by case basis. Do I really care if it is easier to maintain and extend something that I plan on not making any changes to, or if I do make changes they are minimal (likely max 10 items), not really since in this use case we are talking specifically about social media sites.

I find it important to explain WU to people and help them understand them more. Not everybody is reading the network tab or running tests to optimize for WUs, but everybody should be more knowledgeable around the subject of WUs and optimization since it comes up all the time.

1 Like

New users underestimate the value of maintainability and overestimate the impact of WU, and I say that as someone that’s made a business out of saving apps that are built with shortcuts like this, and I don’t want to let others fall into the same trap with advice that isn’t in their best interests (even if they think it is).

The most WU efficient way to build an app is to put all data in option sets and when a user wants to modify things, make them send an email to the admin so they can modify it in the editor.

Of course, I say that in jest… but you get the point.

No - what you’ve suggested is essentially like having ‘address1, address2, address3, address4’ as multiple fields on a data type, rather than a list of addresses. That makes it a huge pain in the ass to display in repeating groups.

Thinking linguistically is helpful here. fb_id, tk_id, x_id… what are they all? Social media IDs. There’s your data type. The platform (Facebook, TikTok, X) are a property of the social media ID (option set).

1 Like

Thank you all for the inputs and considerations!

Indeed I am aware that WU is not the only thing to keep in mind, but I want to avoid to unintentionally build a structure that looks nice but is too resource-hungry.

I understand that there is a first WU consumption on the creation and change of the entries. And while I acknowledge that it makes a difference whether a change consumes 1x or 5x 1.62 WUs.
On the other hand, social media handles do not change (or add) that often, I guess that 1 change every 2-3 months per location would be a more than generous estimate.

In comparison, the WU consumption when someone is viewing the location profile will probably have a much bigger impact, as this happens literally all the time. This is where a slick structure probably has a much bigger leverage, I guess?

1 Like

:smiling_face_with_sunglasses:

Btw, no one mentioned this, but one reason you might want to use a data type instead of option sets is analytics/research.

1 Like

Sure - for a page load, doing it the maintainable way will cost you an extra 0.015 WU per page load per social media. So, if the average location has two social media, it’ll be an extra 0.03 WU per page load.

If you want to take the less maintainable workload efficient route, you can. A

And if your locations get a total of 1 million page views, you’ll have saved… $5.

2 Likes

TBH people really miss the forest for the trees with WU every single day and I hate to see it.

2 Likes

Yes, this is the way in which I think about it and thus my reasoning for offering the advice I had. No matter what features/functions you are building in Bubble, there are multiple ways to do something, but to focus on the concern of the developer/app owner in order to make the correct decision on which method to employ is important. And as you rightfully thought through, ‘what happens more often’, you landed on the correct concern.

And if there are 100,000 locations added monthly they will save 100,000 x 3 x 1.62 WUs = 486,000 WUs per month by not creating a separate data type that would result in a need on creation of location to do the following:

Step 1: create location (with no link fields) (1.62 WUs)
Step 2: Create a new Link data type (1.62 WUs)
Step 3: Create a new Link data type (1.62 WUs)
Step 4: Make changes to location from step 1 to add the results of step 2+3 to the field that is the list of link data type (1.62 WUs)

That 4 step process would need to be altered to include a trigger backend workflow in order to loop through the creation of all link data type entries needed to be created if there is ever an expansion of the number of social site links to offer, and because of that there will be an additional 0.70 WUs to trigger that backend workflow…but really who am I kidding here; a WU performant way to create multiple data type entries at once is to just use the bulk create API call so for each data type link you need to create an entry for, you do not really need to incur the 1.62 WUs per entry doing it the ‘legacy’ way, but that is just me focusing on WU consumption and performance concerns.

So let’s just knock of 1.62 from each 100,000 locations and we are saving 324,000 WUs per month, which costs $ ($29/month for 200K WU or $99/month for 750K) and since we are likely needing more than 200K WU per month in this arbitrary example, we would need to pay an additional $99/month to support the additional data type for social media links…but of course, my monthly 100,000 locations per month is just a number to express how an app might be functioning well into their ‘scaling’ phase, but we do not want to have to go back and rebuild things, which will cost even more money in development costs, so mind as well just build it with success in mind from the outset and imagine a very real possibility that the app could in fact scale successfully to 100,000 locations a month, I don’t know.

Need to use Buildprints to visualize the data structures you guys are arguing about, can’t parse it at all from the text.

1 Like

What type of analytics or research would be useful for a separate data type of social media links that you couldn’t get from just having fields on the main data type of ‘location’?

Unfortunately, there seems to be not much math going into figuring WUs and impacts they may have, or maybe just people are believing most apps will never scale and so WUs will never factor in to their business. But I also see ridiculous comments on the forum where people assume business can lose 20% of their revenues to WUs and still be successful.

Every little bit counts, things do add up to aggregates that really matter, especially on apps that are scaling and have large user base or just large amounts of data processing or interactions taking place. I have a personal app that I have never really done much to promote, it has one single search that drives the traffic and it consumes on average 200,000 WUs every month. I couldn’t imagine what type of WU consumption apps that have large user base could be consuming, and how potentially saving 0.5 or 0.1 WUs off each process may add up to a decent savings per year.

From what I see in comments it seems like people focus on just the singularity of an action or feature set and therefore mistakenly believe WUs are not really something to worry about, and are not really looking at things from a perspective of aggregation of WU consumption and how over the period of a year, saving a few WUs here or there, may equate to a savings of $1,200 / year or more.

SPONSORED POST BY THE WAY

Make each social‑media link its own Thing so you can attach metrics to it and run 3rd party analytics.

Basically imagine you just export the .CSV and it’s all there in one thing rather than having to do aggregated/group by searches.

Just create a view in the DB and export for that one field or combination of fields…

The example data type below has two custom fields and the built in fields

Changing what fields are in my app data DB view in the editor to the below, to only include one custom data field

Now from the below screen shot area, if I pressed export, my csv will have only that single field for all entries in the DB available to the view (ie: I can add constraints to narrow my search to only the entries I’d like to export) in the CSV, which is equivalent to exporting a data type that had only that one field on it, so no aggregated/group by searches required…

But if you are referring to analytics for in the app to display via the app, there is no way around aggregated/group by searches no matter the data structure, and in fact, both data structures required the same setup just as in the export from DB.

How would you track clicks of a “social media type”? Like instead of making a new Thing and then having a separate field and then grouping them I’m saying you have the data type, then a second field tracks the total number of clicks.

If you used an option set, you’d make anew Thing with field type option set, then you’d have to group/aggregate.

1 Like

Just have a data type that is created upon a click of an element that is what the user clicks to navigate to the link, and upon click just save to a text field the link…pretty simple, so now you have a data type with one field (analytics tracking data type) that is text that is the link that when used in bubble or any other system can be manipulated and modified, so use of regex or something else to manipulate the text (ie: link) to extract from it what you need (which is in the base url of the link) which is like facebook, linkedin, tiktok because I’m pretty sure all of those social sites use their name in their url and so every single link will have the name of the social media site inside of it already, so why would you bother to duplicate the data by adding an additional field as an option set as it just shows what is already seen in the url when manipulated to remove everything except the domain.

Then when you want to track for analytics, you can rely on the detailed meta data (ie: created date and created by) in your analytics for even more details that give you even greater insight into your analytics, and so can have that new data type for analytics not just have a field for link, but add some more like maybe current url in order to track where the user clicked it from or any other number of field types/values that can help a business make real business decisions to make more real money by having more robust analytics.

Because having a data type that is social media link as a separate data type that tracks clicks by a single field that is a number costs the same amount of WU to make changes to that social media link as creating a new data type as I would, because if it costs the same amount of WU to make changes to a thing as it does to create a thing, but that creation of a thing results in an infinite amount of value more than the make changes to thing (because in that you just see number of clicks - which great, but like, can I not just get some more data to work off of?).

No matter which way you cut it on this use case hypothetical, the extra data type of social media link that stores a field of option set, a field of ID and a field for number of clicks, is a not the best approach when there is an alternative that I just laid out, which would be create an actual data type for analytics and use your WU consumption costs wisely to create those entries to get more real value from it.

1 Like

I never said this btw, what is this ?,

I said step 1 create links data type,
step 2 create location, links = result of step1

BTW 100k locations a month is too much money, 486k WU should be consired as 486k/month that tthose locations will be active, so lets assume your companies wil stay with you for 5 months = 97k WU, just you are paying upfront thats all, That means NOTHING