
Here I will show you how I reduced my IoT device pins configuration HTML page from about 90kB down to only 8kB. I will use my OpenBeken project as an example, but the generic idea shown here can easily apply to any other environment creating HTML pages from C (or similiar) code. This topic will assume that user knows the basic of C, HTML and Javascript...
So, in this topic I am referring to OBK configuration page that allows you to set GPIO roles in dropdown lists:


Before, size of this page was above 90 000 bytes:

It was causing slow loading on multiple platforms.
After the change, size is now:

Let's start by checking why the page size is so big in case of this config. We can just view the source of the page in the browser:

Now you can clearly see, that for each of the dropdowns, the list of options is repeated. This is very simple, but also not optimal. This repeats for every GPIO, so if there is 30 available IO pins on a sample platform, then it's repeated 30 times!
A brief look at OBK code confirms that's what is happening:
Code: C / C++
The following is done for every possible pin! We need to optimize that...
In order to optimize it, we will use Javascript. In JS, we will create a single, global pin roles array and then for each dropdown we will insert the items into it with a script. There are, however, two issues to solve:
- we need to also set the active selected element, so people don't lose their settings with each refresh and save
- we need to exclude PWM roles for non-PWM pins.
Let's ignore the PWM issue for now. Let's start with the following draft:
Code: Javascript
Array r is a list of item role names. In my function f, I iterate the pin role names and add them to the dropdown d. There I also check for the selected role, which index must be given when calling f function.
The selected role index can be easily taken from OBK code, but for the reference to the select DOM object I had to modify the code futher. I settled with retrieving it by ID:
Code: Javascript
Now that we have basics done, let's also consider how we can skip PWM roles for non-PWM pins. OBK already knows which pins support PWM, so we can just pass extra argument and then check whether pin role starts with PWM, altough in the future I may just hardcode the index of role (it will be few characters shorter). Note that the 'b' variable is the extra argument I added to the function:
Code: Javascript
So finally I have modified my C code to just print the following Javascript when generating OBK page, of course also replacing the dummy data with the real OBK pin roles:

This works and page size is now reduced 9 times, but is it all that we can do?
A brief glance at HTML code shows that there is still room for the improvement:

The channel index div generation can be also procedural. Here is a beautified version of the new code that also generates div:
Code: Javascript
The div creation could be actually separated into another function, as it's done two times, but I don't think it would give me a substantial numbers of characters.
So, now the page size is down to 8kB:

So, to sum up - generating HTML code from C is very easy, but also not very optimal. In case of the repeating data, like the dropdowns with the same options, it's more efficient to generate a Javascript that will later generate HTML elements. For me, it gave me over one order of magnitude improvement in terms of space used. It also fixed OBK issues, hopefully...
The same principle can be applied also to any other IoT projects, the same problems could occur on ESP and could be also solved in ESP by generating HTML+JS instead of pure HTML, so I hope that everybody learned something.
My sample could be of course improved futher, also with Javascript-compression scripts, but I think the optimization I have managed to get so far is enough for our project.
By the way, if any OBK user is reading it, please check it and let me know. Can you check how your pins page works (especially on Firefox) and then update to test build:
https://github.com/openshwprojects/OpenBK7231T_App/pull/1215
does the page loads faster now? Or better? @divadiow @max4elektroda @DeDaMrAz @miegapele ? Can you test it on multiple OBK platforms?
NOTE: Obk also provides pins setting in the web app, so the following page is not crucial, but it's still good to have it running well.
Cool? Ranking DIY Helpful post? Buy me a coffee.