-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[WebServer] Optimize serving flash strings #3660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebServer] Optimize serving flash strings #3660
Conversation
Make sure all flash strings are served by not copying it.
|
Fixing one funky bug too where pages would not be served full. Not sure if we can make the page serving much faster, as the sysinfo page now can be served over WiFi in < 140 msec. The needed amount of free memory is now even less, so maybe we can lower the "workable" threshold below which the webserver refuses to serve pages. |
No need to wrap a single char into a String object for serving it as we can also append it directly to the buffer.
|
OK, now I will stop and get some sleep. |
|
Hmm that's really strange.. By using less memory allocations for serving pages, the amount of free memory gets less.... |
|
I have also updated one ESP node with the latest custom firmware with PR 3660.
|
|
Yep, testing here too with the "Custom" build using the default pre_custom_esp82xx.py and it also is using quite a lot more memory than before. |
|
Well, the serving the web GUI is a quite fast, unfortunately it's still easy to get an Exception with pushing F5 quickly several times to refresh the web page. I would prefer a slower web page serving but a more rock stability. |
That;s what I'm now doing. |
|
But what in the previous change (#3655) before optimizing for speed took so much memory? One of the major memory reductions was already in that PR... |
That PR was mainly about keeping flash strings as long as possible in that format without converting them to So it does not make sense that this optimization does require extra RAM. I'm now experimenting with calling several flush statements, to make sure data is not pending. Still searching.... |
Large chunks of the template were copied to stream. Now they are directly streamed to the client instead of copied first.
Page serving will be slower when low on memory, but this will improve stability when low on ram.
|
Added a few more optimizations. The most important ones are to serve chunks of the web template instead of copying them first. The other one is about the speed vs stability aspect of the web server. |
| #ifdef USES_P092 | ||
| #undef USES_P092 // DL-Bus | ||
| #endif | ||
| #ifdef USES_P093 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the same issue will apply to P076, P093 and P100, missing from their TESTING sets 🤔
I've been testing this with a wrapper #ifndef PLUGIN_SET_TESTING around those #ifdef/#undef's, though I've not yet been able to build all variations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P076 & P093 are part of the energy build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but P100 is in TESTING set B (and that one was already quite challenging to fit, but maybe the optimizations make it fit now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P100 should get the same treatment, seems to fit now in even the (previously) most cramped builds.
|
Did a quick test with a build up to commit 2bb7ebd which seems to have even less free mem (units 2 & 4) really strange... also could quite easily force an exception by reloading the web interface a number of times.. |
|
Which plugins do those builds with low memory have, that others don't have? |
|
Also... how do you build it? |
|
I buld them with custom.h and ArduinoIDE on Mac OS X. All units have different plugins enabled. the two test units 2&4 are quite different, 2 has a lot of varioous plugins/tasks (incl. display, etc.) nr 2 only has a GPIO and a BME. But I always compare before and after updating on the same node with the same plugiins, as it seems the available memory is somehow related to RSSI of that node (bad RSSI => lower memory), it doesn't really make sense to compare 2 differeent units... I have two "empty" units sitting next to each other, and also they show diffrences in memory allocation.. |
|
Ah, would be nice if it can be compared with the same node moved around to test this hypothesis. |
Sure, I can try this, as I have some battery powered units, they hold around a day if not using deep sleep. |
|
I'm now diving into optimizing memory usage. Another thing to watch for... I have seen some reports of I2C somewhat crashing, not responding etc. |
|
I had the I2C issue some time ago, but I think since a few months this didn't happen anymore. However I'm always using latest esp8266 core commits from GIT, so probably something has been fixed there... Still I'll watch out for any issues around the connected peripherials.. |
|
Just pushed some debug code and also made some small improvements which should give you roughly 500 - 1000 bytes more free memory, depending on the build. I will later have a closer look at the used buffers for logs, as that's something with room for improvement. Some of the (now turned in to debug log level) logs I added are like this: This allows to get some more insight in what amount of RAM some plugins/tasks may require. Will merge this soon, as it is working fine, so I can also focus on the pulse plugin code (will also merge that one) |
|
I'm sorry, I'm off for to days and can only look into it again after tomorrow. I'll test the new commits then... |
|
I tested the latest mega commit and installed it on my units yesterday evening. Interestingly my test-units have are a little lower on free mem, all other units are higher, see charts. The postitive thing is, that I didn't have a single reboot on any unit since installing the new version! So there's definitevely an enhancment / bug fix in it! |
|
Memory usage seems more consistent too. |
|
Still not a single reboot, that's a long time ago since I had a version that stable! Well done!! |
|
On my test node the RAM is still quite low (5000-7000 with IRRX plugin enabled) and I am able to crash the node with quickly refreshing the web pages but overall it looks more stable than previous build which sometimes generated Exception without obvious reason. |
|
Quickly refreshing the web pages is indeed still a good receipe for a crash, especially since I had to "revert" some of the speed improvements when running low on memory. So there is a trade-off to me made between speed and stability. Max. responsiveness is also quite stable when enough memory is available. However as soon as you get below some threshold, it immediately turns into highly unstable. So I have changed it to some compromise level. |
|
Yeah, it's a pity the free RAM fell down with latest updates despite all that improvements you made in this matter but perhaps it will be enough for node to work stable. I'll keep testing with most of plugins enabled and we'll see... Thanks again for your great work! |
|
With the latest commits from yesterday (f93e035) heavier loaded units run into a hardware watchdog every hour or so... others run stable. Acutually the one node in question uses the Counter plugin heavily, so the latest changes around that plugin could be an issue. |
|
Update: I did a new version where I included your "feature/build_core_3_0_0" branch. This seems to make it stable again. So probably an issue between me using the 3.0.0 git core and some changes not yet included in the mega branch for this... |
|
The rename of the IRAM_ATTR I guess. |
|
I already had to change that some weeks ago, as I used the latest build. but it could be that I missed something somewhere.. in any case, the latest version runs rock-stable again... no reboots until now.. |
|
I would like to know how to build the custom rock-stable ESP Easy mega firmware from current sources. My ESP8266 nodes are able to survive only several hours between Exceptions... :-( And one of them sometimes can't reconnect to WiFi.
FirmwareBuild:⋄ | 20114 - Mega The most stable recent firmware in my case is this one, which is running for 18 days from Exception : FirmwareBuild:⋄ | 20113 - Mega
|
|
I built it with ArduinoIDE on a Mac using the latest esp8266 core from GIT and the 3.0.0 branch from ESPeasy (see above). Important is to define Good luck! EDIT: Note: the 0's are deep-sleep units... |




Make sure all flash strings are served by not copying it.
Mainly to deal with the memory issues reported by @ghtester and @clumsy-stefan since #3655
The main change of that PR is to serve flash strings where possible, so low free memory may be related to this change.