Повышение эффективности в функции jQuery - PullRequest
0 голосов
/ 22 мая 2009

Оператор while в этой функции выполняется слишком медленно (предотвращает загрузку страницы на 4-5 секунд) в IE / firefox, но быстро в safari ...

Он измеряет ширину текста в пикселях на странице и усекается до тех пор, пока текст не достигнет идеальной ширины:

function constrain(text, ideal_width){

    $('.temp_item').html(text);
    var item_width = $('span.temp_item').width();
    var ideal = parseInt(ideal_width);
    var smaller_text = text;
    var original = text.length;

    while (item_width > ideal) {
        smaller_text = smaller_text.substr(0, (smaller_text.length-1));
        $('.temp_item').html(smaller_text);
        item_width = $('span.temp_item').width();
    }

    var final_length = smaller_text.length;
    if (final_length != original) {
        return (smaller_text + '…');
    } else {
       return text;
    }
}

Есть ли способ улучшить производительность? Как бы я преобразовал это в функцию сортировки пузырьков?

Спасибо!

Ответы [ 5 ]

5 голосов
/ 22 мая 2009

перемещает вызовы $ () за пределы цикла и сохраняет его результат во временной переменной. Запуск этой функции будет самым медленным в вашем коде, кроме вызова .html ().

Они очень и очень усердно работают над ускорением работы селекторных движков в библиотеках, но это все еще медлительно по сравнению с обычными операциями JavaScript (такими как поиск переменной в локальной области видимости), потому что она должна взаимодействовать с DOM. Особенно, если вы используете подобный селектор классов, jquery должен циклически проходить по всем элементам документа, просматривая каждый атрибут класса и выполняя для него регулярное выражение. Каждый обойти петлю! Получите как можно больше этой штуки из своих тугих петель. Webkit запускает его быстро, потому что он имеет .getElementsByClassName, а другие браузеры - нет. (Пока).

4 голосов
/ 22 мая 2009

Вместо удаления одного символа за раз, пока вы не найдете идеальную ширину, вы можете использовать двоичный поиск .

2 голосов
/ 22 мая 2009

Кроме предложения Бретона, еще одна возможность ускорить ваш алгоритм - использовать двоичный поиск по длине текста. В настоящее время вы уменьшаете длину на один символ за раз - это O (N) в длине строки. Вместо этого используйте поиск, который будет O (log (N)).

Грубо говоря, примерно так:

function constrain(text, ideal_width){

...

    var temp_item = $('.temp_item');
    var span_temp_item = $('span.temp_item');

    var text_len_lower = 0;
    var text_len_higher = smaller_text.length;

    while (true) {
          if (item_width > ideal)
          {
            // make smaller to the mean of "lower" and this
            text_len_higher = smaller_text.length;
            smaller_text = text.substr(0, 
                ((smaller_text.length + text_len_lower)/2));
          }
          else
          {
            if (smaller_text.length>=text_len_higher) break;

            // make larger to the mean of "higher" and this
            text_len_lower = smaller_text.length;
            smaller_text = text.substr(0, 
                ((smaller_text.length + text_len_higher)/2));
          }
          temp_item.html(smaller_text);
          item_width = span_temp_item.width();
    }

... }

2 голосов
/ 22 мая 2009

Я вижу, что проблема в том, что вы постоянно модифицируете DOM в цикле, устанавливая HTML-код temp_item, а затем перечитываете ширину.

Я не знаю контекста вашей проблемы, но попытка настроить макет путем измерения визуализированных элементов не является хорошей практикой с моей точки зрения.

Возможно, вы могли бы подойти к проблеме под другим углом. Обрезание до фиксированной ширины является обычным явлением.

Другая возможность (хак?), Если у вас нет выбора, может состоять в том, чтобы использовать свойство overflow css элемента контейнера и поставить & hellip; в другом элементе рядом с текстом. Хотя я рекомендую переосмыслить необходимость решения проблемы так, как вы собираетесь.

Hugo

1 голос
/ 22 мая 2009

Следует отметить, что каждый раз, когда вы добавляете что-то в DOM или изменяете html в узле, страница должна сама перерисовываться, что является дорогой операцией. Перемещение любых обновлений HTML за пределы цикла может немного ускорить процесс.

Как уже упоминалось, вы можете переместить вызовы $ () за пределы цикла. Вы можете создать ссылку на элемент, а затем просто вызвать методы в нем в цикле, как указано в 1800 ИНФОРМАЦИЯ.

Если вы используете Firefox с плагином Firebug, есть отличный способ профилировать код, чтобы увидеть, что занимает больше всего времени. Просто нажмите на профиль под первой вкладкой, сделайте свое действие, затем снова нажмите на профиль. Он покажет таблицу со временем, которое потребовалось для каждой части вашего кода. Скорее всего, вы увидите много вещей в списке, которые есть в вашей библиотеке JS Framework; но вы также можете изолировать это с небольшим методом проб и ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...