Помогите с ускорением загрузки Web-страниц с Arduino
- Войдите на сайт для отправки комментариев
Всем привет!
Нужна помощь в ускорении отображения WEB-страниц в браузере пользователя. Уже наверное все испробовал что знал, но скорость загрузки (отображения) одной страницы плавает в диапазоне 8-25сек. Что очень долго... Пробовал загрузку страниц в браузерах: FireFox, Chrome, Yandex. Везде работает одинаково, часто не отображаются некоторые элементы страницы в виде картинок. Картинок немного и весят мало. Субъективно замедление отображения происходит именно на картинках, сама WEB-страница грузится достаточно быстро.
Использую шилд W5100 на платформе Mega2560. ВЕБ-страницы хранятся на SD-карте. Фрагмент кода загрузчика на Ардуино:
void get_command_builder(String page, String param, String count) //вызываем обработчик команды { File webFile; //если текущий клиент не является авторизованным, то просим пройти авторизацию if (client_check()==0) { glb_auth=0; } else { glb_auth=1; //клиент уже авторизован } //если клиент не авторизован if (glb_auth==0) { //отображаем страницу авторизации if ((page.indexOf(".htm",0) != -1) || (page=="/") ) page="/index.htm"; } //в противном случае грузим любую страницу. Но если страница не указана, то грузим страницу по умолчанию. else if (page=="/") page="/switch.htm"; //загрузчик страниц и элементов /////////////////////////////////////////////////// webFile = SD.open(page); if (webFile) { glb_client.println(F("HTTP/1.1 200 OK")); if (page.indexOf(".htm", 0) != -1) glb_client.println(F("Content-Type: text/html")); else if (page.indexOf(".css", 0) != -1) glb_client.println(F("Content-Type: text/css")); else if (page.indexOf(".png", 0) != -1) glb_client.println(F("Content-Type: image/png")); else if (page.indexOf(".jpg", 0) != -1) glb_client.println(F("Content-Type: image/jpeg")); else if (page.indexOf(".gif", 0) != -1) glb_client.println(F("Content-Type: image/gif")); else if (page.indexOf(".js", 0) != -1) glb_client.println(F("Content-Type: application/x-javascript")); //glb_client.println(F("Connnection: close")); glb_client.println(); //загружаем данные блоками (медиа файлы) byte cB[1024]; int cC=0; while (webFile.available()) { cB[cC]=webFile.read(); cC++; if(cC > 1023) { glb_client.write(cB, 1024); cC=0; } } if(cC > 0) glb_client.write(cB,cC); webFile.close(); } //////////////////////////////////////////////////////////////////////////////////// //обработчик команд управления ///////////////////////////////////////////////////// if (page=="/rcpdu") { ...... } }
Результат обработки команд поступивших в Ардуино из браузера отсылается обратно клиенту посредством AJAX запросов. Заменяются данные только содержимого нужного участка WEB-страницы, без ее перезагрузки целиком.
Фрагмент JS обработчика:
function get_information() { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) { if (this.responseText != null) { document.getElementById("inf_block").innerHTML=this.responseText; } } } } request.open("GET", "rcpdu?get_information", true); request.send(null); }
Собственно фрагмент кода нужного участка ВЕБ-страницы для отображения полученных данных, тут все просто:
<div class="inf_block" id="inf_block" align="center"> </div>
Вообщем пока грешу только на скорость отображения содержимого страницы, может чтение с SD-карты медленное, может определение типа контента при загрузке не в том порядке определяю. Не знаю короче... (((((( Прошу помощи.
Да, сама страничка выглядит так (из графики там только кнопки):
Если вкратце, то - стандартная библиотека Ethernet - кривая. Попробуйте помедитировать над вот этим куском кода:
Там даже комментарий об этой кривости есть. Криворукая библиотека не перебирает нормально клиентов, и, хотя есть буфер на 4 клиента, по сути, бОльшую часть времени оно ждёт, когда первый клиент просрётся.
Выход - переписывать.
Спасибо DIYMan, посмотрю библиотеку тоже... :) Еще будут у кого мысли на этот счет?
Кстати, я этих четырех клиентов программно отлавливаю по их IP, использовал такую конструкцию:
В Ethernet библиотеке нужно тоже функцию вставить getRemoteIP(), для получения IP-клиента. )))) Отчасти извращение, но все же...
Проблема (и частичное решение) с библиотекой Ethernet изложены тут https://geektimes.ru/post/259898/
Я использовал такой код для вывода страниц из файла
Спасибо alexvs, попробую! :)
alexvs, ты пробовал вносить изменения в библиотеку по ссылке указанной тобой. Я закоментировал старые ф-ции и начал использовать измененные с префиксом нижнего подчеркивания на конце. Полезла куча ошибок при компиляции...
Например, объявлял раньше сервер и его порт:
Теперь выдает ошибку - cannot declare variable 'glb_server' to be of abstract type 'EthernetServer'. Не хочет объявлять сервер. При этом ф-ция virtual void begin() в обоих файлах EthernetServer опечатана использую только begin_(). Если использовать базовую ф-цию begin(), то все работает, хотя производительности никакой не увидел. Указываю нулевой сокет glb_server.begin_(0) и в теле loop() функцию с сокетом glb_client = glb_server.available_(0), все работает но без видимых изменений. Ты пробовал измененную библиотеку использовать, что я не так делаю?
begin обязана быть определена, т.к. она объявлена как виртуальная в классе Server, от которого наследуется EthernetServer. Т.е. просто так закомментировать её - не выйдет. Выход - оставляйте тело родного begin пустым.
begin обязана быть определена, т.к. она объявлена как виртуальная в классе Server, от которого наследуется EthernetServer. Т.е. просто так закомментировать её - не выйдет. Выход - оставляйте тело родного begin пустым.
Это я уже понял, использую begin_(). :)
Попоробовал в работе новую функцию по загрузке данных с SD-карты. Картинки стали грузиться гораздо быстрее. Причем как ни странно все вполне сносно работает в браузере Firefox, в других браузерах: Chrome и Yandex проблемы с отображением. Страница все равно медленно грузиться... точнее ее области с данными. Такое ощущение что AJAX запросы долго ждут своего выполнения в очереди перед отправкой данных браузеру. Я использую около 8-ми AJAX запросов, для отображения данных на странице. При этом суммарный объем передаваемых данных около 30символов (~30байт). Хотя сама страница "тело" полностью грузится, почти мгновенно и при этом она весит 21Кб. Тут точно AJAX запросы долго обрабатываются, я реально не знаю что с этим делать. :( Я пробовал так же все данные одним AJAX запросом передавать и на стороне клиента с помощью JScript данные распределять по областям страницы (разбор строки данных). Но сути это не меняет, тоже медленно работает.
Firefox как-то не сильно критичен к задержкам пакетов - дожидается, а вот остальные браузеры - ну, раз не пришло, значит потерялось.. больше не жду. )))))
П.С. Использование одного сокета (вместо 4-х) с измененной библиотекой как-то не помогло.. в плане скорости передачи данных.
Во-первых, надо знать, чего вы там в библиотеке наколбасили ;) По-хорошему, там не надо дописывать никаких своих функций, достаточно ввести одну переменную с номером последнего проверенного клиента, и чуть переписать функцию available, чтобы она начинала опрос массива клиентов не с первого клиента каждый раз ;)
По поводу отдачи в браузер: взрослые браузеры открывают кучу соединений, если в странице много включений (рисунки, стили, скрипты, многие сразу запрашивают favicon) - по итогу все четыре клиентских слота забиваются махом. Выход - закрывать клиента сразу, как только он отдал все данные (или не нашёл контента запрошенного) - чтобы не ждать, пока соединение само закроется по таймауту.
Но всё это секс, который для серьёзной вебморды неприемлем так или иначе. Именно по этой причине я не держу вебморду на SD (да и вообще на МК где бы то ни было) - а юзаю или дешёвенький роутер, или, на период разработки - вебморда крутится на взрослом компе. А всё общение с МК идёт простенькими пакетами.
И всё летает аж пиджак заворачивается ;) И графики можно взрослые строить, и с jQuery проблем нету, и вообще - нигде ничего не жмёт :)
Видео про старую версию вебморды (там ещё графиков нету и много чего ещё нету): https://www.youtube.com/watch?v=EwMbdgM9kQc&index=6&list=PLky0v6EmdStCQi3XgBMVkbZeycrIpZnW_
Сам проект: https://github.com/Porokhnya/GreenHouseProject
Видео про старую версию вебморды (там ещё графиков нету и много чего ещё нету): https://www.youtube.com/watch?v=EwMbdgM9kQc&index=6&list=PLky0v6EmdStCQi3XgBMVkbZeycrIpZnW_
Проект конечно хороший, но это решение из другой эпостаси... ;) Умный дом и все такое... Там не нужна веб морда на МК, за все отвечает централизованный узел (в роли ПК). В данном случае о многом можно не думать, все действительно летает, я уже это проходил. ))))
Меня сейчас интересует полностью автономное устройство, для продажи в дальнейшем, поэтому и гемороя столько... ))) Пока буду копаться в сторону оптимизации содержимого JS в html файлах и переделки AJAX запросов, методом проб и ошибок. Где-то там видимо собака зарылась... Вчера добился задержки загрузки страницы до 10..15сек, уже лучше но все равно еще много. ;)