Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Это настоящий ШОК для чайника! Разница во времени работы в 4-5 раз 
:(
    Опции темы
popov654
  Дата 14.8.2011, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 9.1.2009

Репутация: нет
Всего: нет



Недавно взялся разработать новую версию своего парсера лого в сервера SHOUTcast Прасер написан на PHP, при этом активно использует JavaScript (на простом уровне).
Я вообще в JavaScript новичок честно говоря. И меня это непонятное явление тронуло до глубины души, практически шокировав.   smile  

Профессионалы, подскажите в чём прикол) Или в чём моя ошибка, если я туплю smile 

Чтобы не быть голословным, вот код селектора, написанного на JavaScript (это аналог переключателя страничек в любом поисковике, например в Яндексе, однако аналог скорее всего только лишь по внешнему виду и предназначению, реализовано-то в поисковиках это дело наверняка совсем по-другому smile   )

PHP-код самого парсера приводить не буду, ибо огромный и сложный. Если потом понадобится, опубликую в отдельном посте. Итак, код нижнего фрейма:

Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Shoutcast log parser</title>
<style type="text/css">
<!--
.style10 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: small;}
a:link {
    color: #0000CC;
}
a:visited {
    color: #0000CC;
}
a.current {
    color: #EC7600;
}
-->
</style>
</head>
<body>
<script language="JavaScript" type="text/javascript">

  function changePage(ref) {
      obj = document.frm
      obj.action = ref
      obj.submit.click()
  }
  
  function init() {
  
  }
  
  function check() {
      return (frm.filename.value != '')
  }
  
  function addData(str) {
      if (main_part == '') main_part = document.frm.innerHTML
      document.frm.innerHTML = str + main_part
      //document.getElementById('tracker').innerHTML = str
  }
  
  var main_part = ''
  
  function printPageList(pages, group, cur_page) {
      flag = true;
      var buf = ''


      var from = parent.topframe.getFrom()
      var to = parent.topframe.getTo()

      var grouping = document.getElementById('grouping').checked ? 'true' : 'false';

      buf += '<table border="0"><tr>'
      if (cur_page == 10) {
          cur_page = 0
      }
      if (group > 0) {
          buf += '<td><a href="#" onclick="changePage(\'parser.php?total=' + pages + '&from=' + from + '&to=' + to + '&page=0\'); return false">&lt;&lt;</a>&nbsp;</td>'
          buf += '<td><a href="#" onclick="changePage(\'parser.php?total=' + pages + '&from=' + from + '&to=' + to + '&page=' + ((group - 1) * 10) + '\'); return false">&lt;</a>&nbsp;</td>'
      }
      for (i = group * 10 + 1; i <= (group + 1) * 10; i++) {
           if (i > pages) {
              break;
           }
           style = ''
           if (i % 10 == cur_page) {
              style = ' class="current"'
           }
           buf += '<td><a href="#" onclick="changePage(\'parser.php?total=' + pages + '&from=' + from + '&to=' + to + '&page=' + (i-1) + '\'); return false"' + style + '>' + i + '</a>&nbsp;</td>'
       }
       if (pages>10) {
          if (i <= pages) {
             if ((group + 1) * 10 + 1 <= pages) {
                buf += '<td><a href="#" onclick="changePage(\'parser.php?total=' + pages + '&from=' + from + '&to=' + to + '&page=' + ((group + 1) * 10) + '\'); return false">&gt;</a>&nbsp;</td>'
             }
             buf += '<td><a href="#" onclick="changePage(\'parser.php?total=' + pages + '&from=' + from + '&to=' + to + '&page=' + (pages - 1) + '\'); return false">&gt;&gt;</a></td>'
          }
          buf += '<td>&nbsp;&nbsp;&nbsp;всего ' + pages + '</td>';
       }
       buf += '</tr></table><br>'

       addData(buf)
       
  }
  
  
</script>
<!--<span id="tracker" class="style10"></span>-->
<form action="parser.php" name="frm" id="frm" target="topframe" method="post" enctype="multipart/form-data" class="style10">
<p><input type="checkbox" name="grouping" id="grouping">Группировать смежные сеансы</p>
<input type="file" name="filename" size="38"><br><br>
<input type="submit" name="submit" value="Анализ"><br>
</form>
</body>
</html>


Собственно, дело вот в чём. Во второй версии скрипта при загрузке нового блока PHP-скрипт в верхнем фрейме с помощью JS по событию onload перенаправлял селектор в нижнем фрейме по новому URL, передавая в адресной строке новые параметры, которые использовались селектором для обновления раскладки. Но вот я решил что это не есть хорошо (например, у меня при этом значение поля с именем анализируемого файла очищалось, и почему-то через JS с помощью функции из родительского фрейма не восстанавливалось), и в третьей версии решил сделать механизм, который позволит обновить нужную часть нижнего фрейма без перезагрузки. Для этого я убрал из селектора парсинг URL и вместо этого добавил в функцию вывода раскладки три аргумента.

Сперва я попробовал работать напрямую с document.frm.innerHTML, где frm - имя формы, но, как выяснилось, почему-то данные, добавленные посредством модификации innerHTML из сценария, не читаются, будто их и нет. Поэтому удалить старую раскладку таким способом не получалось. Полностью очистить innerHTML я не мог, потому что там содержался ряд других контролов и надписей. Недолго думая, я нашёл вариант, который уже применял когда-то в другой онлайн-системе с интернет-радио: завести глобальную переменную и хранить в ней исходное состояние innerHTML. Да, наверное это ужасно плохой стиль, но я ничего лучше не придумал. Оно заработало.

Но тут я подумал: а почему мне надо обязательно пихать таблицу с номерами внутрь формы, ведь можно сделать ей отдельный контейнер! И очищать его перед обновлением. Сказано - сделано. Я сделал всё как описано выше, и тут начинается фантастика.

В вышеописанном коде есть оба варианта решения - через глобальную переменную и через отдельный контейнер (второй сейчас закомментирован). Парадокс в том, что второй, более человеческий способ тормозит как не знаю что. Я специально проводил отсчёт времени переключения между страницами данных. В случае помещения трекера в отдельный див, между нажатием на ссылку и осуществлением загрузки верхнего скрипта, который после её завершения вызывал JS функцию селектора, я успевал досчитать до девяти (!). То есть около 9 секунд. В случае же хранения HTML разметки формы в глобальной переменной, при всей нелепости подхода, я едва успевал сосчитать до двух (1,5-2 секунды!)  smile 

Я до сих пор слегка в ауте. PHP-код один и тот же, остальное не менялось, единственное существенное отличие которое я вижу - в первом случае использован метод document.getElementById() (при чём документ мягко говоря не очень большой, пара инпутов, форма, див и обчёлся), во втором же случае происходит обращение упрощённым способом к самой форме: document.frm

Я конечно слышал, что ссылки на формы хранятся браузером как-то особо, для упрощённого вызова. Но getElementById() используется повсюду!.. Ну не верю я чтобы он у всех так тормозил. Он что, ТАК долго обходит дерево? smile Какие тогда возможны альтернативы? smile 

Или я где-то жёстко затупил... Прошу помочь разобраться! smile

Это сообщение отредактировал(а) popov654 - 14.8.2011, 08:15
PM MAIL   Вверх
popov654
Дата 14.8.2011, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 9.1.2009

Репутация: нет
Всего: нет



Всё, я уже кажется понял в чём дело. Я ступил)

Похоже, проблема как раз-таки в том, что в случае с отдельным контейнером поле с файлом не очищается. Хоть я и сделал в PHP логику, чтобы при наличии загруженного файла на сервере и установленной куке в клиенте повторной загрузки не происходило, возможно, данные каким-то образом всё же утекают и передаются на сервер снова через форму. То есть такая огромная задержка вызвана тупо повторной загрузкой 5-мегабайтного файла. Но PHP судя по отладочной печати его не сохраняет. Может ли быть так, что данне передаются "вхолостую"? То есть послали, но не приняли?..

И если это так, то вопрос остаётся только один: как с этим бороться? Каждый раз грузить весь огромный лог - Боже упаси, а очищать поле не хочется, т.к. для пользователя это единственный источник информации о том, какой лог он анализирует. Сделать отдельный "дисплей" с именем файла? Увы, у меня места на него нет, да и пустое поле загрузки смотрится не очень красиво...
Можно ли как-то обойти эту проблему через JS? Например, запретить загрузку на сервер части формы?

Можно конечно вообще форму не сабмитить, а только пренаправлять верхний фрейм с PHP-скриптом. Это так, но что делать, если юзер-таки захочет загрузить новый лог?

Надо вообще разделить процесс загрузки файла с логом и процесс переключения страниц. Но как это сделать органично? Тут ведь в чём была прелесть - нажал "Анализ" - и тут же получил результат, так как скрипт в конце стадии подготовки сам устанавливал текущую страницу в ноль и шёл работать дальше. Для пользователя всё было совершенно прозрачно. Кроме того, в ближайшие 10 минут пользователь мог нажать "Анализ" вообще не выбирая файл. Скрипт сам соображал, что файл уже загружен и брал его с сервера. Если сейчас эти процессы разделять - может выйти неудобно с точки зрения юзабилити. Буду думать  smile 

Это сообщение отредактировал(а) popov654 - 14.8.2011, 22:01
PM MAIL   Вверх
popov654
Дата 15.8.2011, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 9.1.2009

Репутация: нет
Всего: нет



Модераторы, переименуйте пожалуйста ветку. Никакого шока тут в сущности нет, обычная глупость  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1270 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.