За последние 24 часа нас посетил 22951 программист и 1724 робота. Сейчас ищут 1832 программиста ...

setInterval + SendRequest, тормаза...

Тема в разделе "JavaScript и AJAX", создана пользователем Sephiroth_Lukaw, 26 апр 2008.

  1. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
    Использую setInterval("SendRequest('GET', 'http://адрессайта/online.php5');", "2000"); на всех страницах сайта, для определения в онлаин ли пользователь или нет(хотя скорее всего уберу и оставлю только для чата, а определение в онлаин ли пользователь просто зделаю по времени последнего запроса, но не в этом дело), функция SendRequest, что собственно видно из её параметров делает пустой запрос каждые 2 секунды на скрипт online.php5(далее считываются данные из кукисов), вот исходник самой функии и той функции которую она вызывает(Функции SendRequest и CreateRequest были написаны не мной)
    [js]
    function CreateRequest()
    {
    var Request = false;

    if (window.XMLHttpRequest)
    {
    //Gecko-совместимые браузеры, Safari, Konqueror
    Request = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
    //Internet explorer
    try
    {
    Request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (CatchException)
    {
    Request = new ActiveXObject("Msxml2.XMLHTTP");
    }
    }

    if (!Request)
    {
    alert("Невозможно создать XMLHttpRequest");
    }

    return Request;
    }

    /*
    Функция посылки запроса к файлу на сервере
    r_method - тип запроса: GET или POST
    r_path - путь к файлу
    r_args - аргументы вида a=1&b=2&c=3...
    r_handler - функция-обработчик ответа от сервера
    */
    function SendRequest(r_method, r_path, r_args, r_handler)
    {
    //Создаём запрос
    var Request = CreateRequest();

    //Проверяем существование запроса еще раз
    if (!Request)
    {
    return;
    }

    //Назначаем пользовательский обработчик
    Request.onreadystatechange = function()
    {
    //Если обмен данными завершен
    if (Request.readyState == 4)
    {
    //Передаем управление обработчику пользователя
    r_handler(Request);
    }
    }

    //Проверяем, если требуется сделать GET-запрос
    if (r_method.toLowerCase() == "get" && r_args.length > 0)
    r_path += "?" + r_args;

    //Инициализируем соединение
    Request.open(r_method, r_path, true);

    if (r_method.toLowerCase() == "post")
    {
    //Если это POST-запрос

    //Устанавливаем заголовок
    Request.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");
    //Посылаем запрос
    Request.send(r_args);
    }
    else
    {
    //Если это GET-запрос

    //Посылаем нуль-запрос
    Request.send(null);
    }
    }
    [/js]
    Так вот...к сожалению мною было замечено что в IE и Опере(да и в других браузер скорее всего тоже самое) довольно таки быстро увеличиваются затраты оперативной памяти и естественно Браузер начинает медленно, но верно подвисать(особенно это заметно на гифах оставляющих за собой "тени"), ппплллииизззз, подскажите, как избавиться от тормозов и если никак, то хотя бы скажите какую технологию мне ещё опробывать?(IFRAME :( ), просто я уже в полном ауте :? ...
     
  2. Ивашка

    Ивашка Активный пользователь

    С нами с:
    29 авг 2007
    Сообщения:
    96
    Симпатии:
    0
    Адрес:
    Щёкино/Тула
    1. Уберите строку из setInterval:
      [js]setInterval(function(){SendRequest('GET', 'http://адрессайта/online.php5')}, "2000")[/js]
    2. Скачайте утилиту Drip (в гугле должна быть) и посмотрите, есть ли у вас утечки памяти - вполне возможно, что память съедается не этими функциями, а последующими обработчиками
    3. На onreadystatechange не следует вешать анонимных функций - в большинстве таких случаев сборщик мусора не сможет корректно уничтожить это замыкание. Т.е. сделать нужно примерно так:
      [js]//Назначаем пользовательский обработчик
      Request.onreadystatechange = RSHandler[/js]
      [js]var RSHandler = function(Request) {
      //Если обмен данными завершен
      if (Request.readyState == 4) {
      //Передаем управление обработчику пользователя
      r_handler(Request);
      }
      }
      [/js]
      а сам метод RSHandler по возможности должен быть описан вне метода SendRequest (чтобы не создавать замыканий). Но в большинстве случаев (и в вашем тоже) это не прокатит, т.к. обработчики ответа, как правило - разные функции (у вас - r_handler). Выход - не передавать разные обработчики, а использовать один метод-коммутатор, вызывающий необходимые обработчики, основываясь например, на параметрах xhr-объекта или полученных от сервера данных.
     
  3. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
    Ивашка спасибо, как я понимаю ваш бы способ тоже сработал, но я уже сделал следующим образом(если честно для теста, но эт не важно):
    [js]
    function CreateRequest() {
    ...
    }
    //Создаём запрос
    var Request = CreateRequest();
    //Функция для Пустых Запросов
    function NullSendRequest(r_path) {
    Request.open("GET", r_path, true);
    Request.send(null);
    }
    [/js]
    [js]
    setInterval(function(){NullSendRequest("/online.php5")}, "2000");
    [/js]
    В IE и FireFox при таком раскладе утечки вроде бы и нет, в Drip'е вообще всё прекрастно :) ...но в Опере ничего не изменилось :?, в чём теперь то проблема?
    Добавил через некоторое время:
    Щас для теста поставил бесплатный чат с использованием Ajax, в IE и FireFox всё нормальн, в Опере замечается утечка
    P.S. У мну по жизни проблемы с Браузерами...но в основном IE глючит, а щас чё та с Оперой, либо я что то не то делаю...
     
  4. Ивашка

    Ивашка Активный пользователь

    С нами с:
    29 авг 2007
    Сообщения:
    96
    Симпатии:
    0
    Адрес:
    Щёкино/Тула
    Хм. Ну вообще очень может быть, что эта утечка специфична только для данной версии оперы. Я делаю такой вывод исходя из того что в девятой ветке поведение js-движка у них совершенно непредсказуемое от версии к версии (поверьте опыту :) ).
    Если есть возможность, попробуйте протестировать скрипт еще на паре версий (напр. 9.01, 9.11, 9.25). Если поведение во всех тестах будет одинаковым то возможно, что все-таки что-то не так в скрипте. Но может быть, что это какой-то очередной недопофиксенный фичебаг :)
    Дело осложняется еще и отсутствием вменяемых отладчиков для оперы.
    Можно также попробовать выложить исходники, посмотрим, что там.

    ЗЫ. Насчет Drip - не обольщайтесь, он показывает только утечки для IE :)
     
  5. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
  6. Sephiroth_Lukaw

    Sephiroth_Lukaw Активный пользователь

    С нами с:
    26 апр 2008
    Сообщения:
    62
    Симпатии:
    0
    Все Проблемы решил, думаю тему можно закрыть...