Plugin loads all files in the browser

Hello,

I was wondering if there is a way to not download all the plugin files and resources every time a page is loaded.

Here is an example: we’ve developed a JavaScript code to validate the VAT and if we use via Toolbox plugin for example, the Chrome developer tools says it only get the JavaScript code when using it in a workflow.

But if we develop a plugin and put the JavaScript in the plugin, every time the page is loaded, it loads all the plugin JavaScript and files.

We’re looking for performance here so I was wondering how we can tell the plugin to only load the resources when it’s been actually used and not to have the files loaded on standby mode till they’re used.

We’re actually thinking what’s the best performance wise, have the code in the database and call it when needed or doing it via plugin since plugin is easier later to maintain.

Thanks a lot to all.

To understand your problem, you have to first understand the difference between client-side actions / element actions / element code and server side actions.

If you are running code in the element section or a client-side action, then you are creating frontend (client-side) code. In this case, your javascript resources will be loaded on page load. This is just how javascript works (this is true for every website). In other words, if you are creating an element or client-side action you cannot (and in my opinion, shouldn’t be able to anyways) avoid loading the resources beforehand.

If you are running code from a server side action, then you won’t load everything on the client-side because we are talking about running code from the server. This is not run on the browser, you you don’t need to load all the resources.

By the way, in my experience, running code from the client-side is way more performant than server-side (especially in Bubble). But that’s just my two cents.

Regards
Jonah

1 Like

Vue.JS developer here (also).
It depends.

All ressources are loaded on page load if static JavaScript ressources imports methods are used.

Modern JS frameworks allows dynamic imports, hence loading the required JavaScript resources on request (however one should take into account the latency to load the said ressource).

When it comes to Bubble, all resources are loaded upfront.

2 Likes

Thanks for the correction! I don’t have so much experience in frameworks, so I guess that explains that.

But alas, the result is the same. You can’t dynamically import Javascript files in Bubble.

1 Like

I wouldn’t even worry about this. I’ve seen very few Bubble plugins that are more than a few lines of code (my more complex plugins are one of the rare exceptions, but even those are just a few 10K bytes). If your plugin is reliant on external scripts, load those with the defer tag so they don’t render block, but practically speaking that’s all you should really worry about.

Also, don’t misunderstand how actions work. If you have a Run JS action, the text that you typed for the code in the editor IS downloaded to the page as one of that action’s properties. Where else would it come from?

Putting a Search as the value of that field would just be madness as why would you add database interaction time?

Unless you’re doing something really extraordinary (like is your code hundreds of Kbytes?) there’s just not much issue here. And, if so, you can always make that code bundle an external script and load it with defer like any other external script.

4 Likes

The above being said: When building (not one’s own project-specific code) a generally useful Bubble plugin (e.g.,Floppy, List Shifter, CG Pro) that supports a wide variety of use cases and options, there’s always going to be a lot of unused code, because of the dumb Element plugin architecture.

(And this is something I think about a lot. “Is this feature useful enough that it’s worth loading in every instance, or should it be built as a separate element plugin?” For example, in Floppy, Floppy Expression Watcher is a very minimal version of List Shifter that implements just one of LS’s many functions.)

For the millionth time, if @bubble gave us a client-side action API that let us return values to the workflow, much of this sort of Element plugin-related bloat could be eliminated and pages could be built that include only the code for features that are actually used within the page.

4 Likes

Wow thanks for the replies @jonah.deleseleuc, @redvivi and @keith,

That really helps a lot.

I was wondering, for example if you use the Toolbox plugin you don´t load the resources on page load but when asking for it (I guess it is like that) since we´ve a workflow with an action that loads the resources and the next action that does JavaScript code.

Is it really not possible to do that when creating a plugin?

What´s best for performance wise, use a plugin or Toolbox?

Also, nice recommendation @keith ↓:

Thanks a lot to all of you and have a great day.

1 Like

Again, as I explained, it is not like that. Not at all:

1 Like

Hey @keith,

I´ve just read it again and noted (I was about to edit my post). Sorry about that, I´m not so technical and takes me a bit to understand it.

Thanks a lot for the clarification.

1 Like

So the best option here is the one you pointed, deferring the scripts.

Toolbox will almost always lose. Toolbox isn’t even as performant as it could be. All “Run JavaScript” does is eval() the text of the code you enter into the script box.

Eval is slower than other solutions like function(), which does the same-ish thing (parses a string into “compiled” JavaScript) but browser implementations of function() are faster.

1 Like

Oh ok, did not know that.

This is quite interesting @keith.

Thank you so much for the information and for translating code to not code human-readable :pray:.

Note that the way Bubble loads plugin code is that it eval()'s the text of the plugin’s code when the page loads. But then it doesn’t need to do that again. Every time you hit “Run JavaScript”, the code is re-eval()'ed.

But in practical application, we’re just splitting hairs here. You only notice these differences in stress-testing in iterative contexts. (And Bubble isn’t designed to do iterative things, so you’d basically just never notice this.)

1 Like

Oh that makes sense.

So I guess we came to the conclusion that is better to build a plugin rather than using Run JavaScript from Toolbox.

Thanks a lot @keith

Well, yes, but practically speaking you won’t notice much of any difference in real-world applications… which is why I say that you shouldn’t even worry about this except in certain cases (you can likely speed up a given page by much more by looking at other issues). But if you’re down to “we want to save 2 more ms”… And if you’re a “it’s the principle” sort of person then, you know…

https://www.tiktok.com/@mattstorerhere/video/7109025996065492225

1 Like

Hey @keith,

That was hilarious :laughing:.

It just came into my mind that we´re using a Run JavaScript code like:

  1. First action: Run JavaScript to call the resources.
  2. Second action: Run JavaScript that makes a “do a search for …” and searches the code that we´ve inserted in the database called “our_custom_codes” and gets the code desired which is a piece of text in the database field.

So if we don´t do the first action and try to go for the second one, the code throws an error that says it does not have the resources to execute the JavaScript.

So in this particular case, I guess there is no on page load of the resources, right?

Why can that be?

The problem we´re facing (I don´t know if it´s actually a problem) is that we´re building about 4 plugins with hundreds of lines and don´t know if that could be a problem in the real world.

Thanks a lot.

1 Like

So, I’m not really sure what you mean by this:

Do you mean loading certain external scripts? (If so, you can just do that by including them in the page header, but an element plugin would make this easier.)

And I’m really unclear about what you mean by this:

I’m assuming what you’re doing here is what I advised that you shouldn’t do:

But in any case, yeah you should just build a plugin that does what you need to do.

Note that “hundreds of lines of code” isn’t a big deal as minified and uncommented this will boil down to a couple of kilobytes. For reference, List Shifter is about 2000 lines of code before minification, and Floppy is nearing that because I keep adding little features. Leaving out any issues like loading a list, they initialize in single digits of milliseconds. So, again, you’re basically looking for performance optimizations where you aren’t going to find any (writing a plugin to do what you need will (1) make things simpler (2) remove any need to check for when script dependencies are loaded and (3) speed things up, even if just by a tiny bit).

Also, that video is quite possibly the funniest thing I’ve ever seen on the Interwebs, but then, I’m from the 80’s (which is to say, my incept date is in the 60’s and I love me some Kate Bush).

2 Likes

Hey @keith,

You´re totally right about this one :man_facepalming:.

Noted all the recommendations and gonna follow them from now.

Me too from the 80´s and also Kate Bush fan of some of the songs.

Thank you so much for all the explanations man and have a great day.

1 Like

That’s hilarious :joy:

1 Like

Hey @keith @redvivi - is it possible to block plugin scripts from loading on certain pages?

I’ve tried your loader plugin to async - however this does affect scripts loaded through plugins.

Use case: It’s great to use plugins on certain pages (without having to build from scratch or create subapps), however more basic pages (like login) are slowed down. For example, the stripe plugin does not need to loaded on all pages and significantly slows down our app. The only current option seems to be to create a sub-app with these plugins + pages or rebuild from scratch.

Happy holidays and thanks for your help!