Предложения по работе с ужасным механизмом доступа к Javascript / Dom в IE - PullRequest
7 голосов
/ 17 января 2011

Я работаю над сайтом, на котором есть страница, которая потенциально может стать очень длинной. Теоретически он может содержать более 1000 строк данных. Тогда эти строки могут иметь подстроки.

В настоящее время я использую структуру списка / подсписка для представления данных, потому что трудно визуализировать подмножества в таблицах. данные подмножества находятся в таблице, хотя.

Проблема заключается в следующем: в IE. мое наведение на стили строк, всплывающие подсказки и другие javascripts занимает до 5 секунд, чтобы выстрелить! Страница висит как сумасшедшая и практически бесполезна. В FF, Chrome и Safari он работает просто отлично.

Мне не нужна целая куча статистики о том, что IE работает медленно. Я знаю, это. что мне нужно, так это некоторые предложения / теории / идеи о том, как бороться с медлительностью!

Некоторые идеи, которые у меня были до сих пор: некоторый вид пейджингового механизма. Но это становится хитрым b / c 1. Это список, а не таблица, и 2. у него есть подсписки и вложенные таблицы для этих подсписков. поэтому нам нужно как-то пролистать страницу, основываясь на верхнем уровне, я думаю. потому что мы не хотим разбивать данные на всех. Я полагаю, это возможно ...

- некоторый вид механизма, который удерживает содержимое в массиве javascript или объекте или soomething и не добавляет его в dom, пока он не будет прокручен. и забирает его, когда вы прокручиваете его. в теории это было бы круто. но я думаю, что это было бы ужасно.

- что-то еще целиком?

Заранее спасибо за любые идеи! Я, вероятно, постараюсь назначить награду за это, как только смогу вдохновить вас;)

EDIT:

О, МОЙ! Я думаю, что, возможно, нашел часть проблемы с помощью трассировки Дина! спасибо Pointy за напоминание об этом инструменте. Я забыл об этом. событие щелчка одной из моих кнопок, кажется, запускает безумную сумму. как 2000 раз и считать. что-то щелкает автоматически или что-то в этом роде. странно то, что у меня нет javascript-кодов, которые бы вызывали нажатие этой кнопки! РЕДАКТИРОВАТЬ: Кажется, это больше не проблема.

EDIT:

Кроме того: я не думаю, что сложность моей разметки влияет на отзывчивость моих скриптов (я знаю, что если бы я мог использовать только селекторы идентификаторов, это было бы лучше, но я оптимизировал свои селекторы и qtips как насколько это возможно (с помощью прошлого). У меня есть кнопка, которая находится на странице, ни в коем случае не вложенная, обработчику щелчков требуется 4 или 5 секунд для регистрации. Дело не в том, что действие щелчка занимает много времени время, просто медленно замечать, что на него нажали.

РЕДАКТИРОВАТЬ: у меня было 5 промежутков, каждый из которых был вложен в промежуток без необходимости, я их вложил, и это, похоже, сократило медлительность примерно на 1/2 !! (эти 5 интервалов повторялись в каждом ряду)

РЕДАКТИРОВАТЬ: Вот некоторые из соответствующих сценариев:

Обработчик главной кнопки:

$('#FilterScheduledShifts').click(function () {
  var categoryId = $('#CategoryId').val();
  var activityId = $('#ActivityId').val();
  var shiftStatusFilters = GetShiftStatusFilterIds();
  var dayOfWeekFilters = GetDayOfWeekFilters();
  var startDateFilter = GetStartDateFilter();
  var endDateFilter = GetStartEndFilter();
  var dataToPost = {
    categoryId: categoryId,
    activityId: activityId,
    statuses: shiftStatusFilters,
    daysOfWeek: dayOfWeekFilters,
    startDate: startDateFilter,
    endDate: endDateFilter
  };
  var url = $('#UrlToFilter').val();
  $('#ListHolder').html("<%=web.loading %>");
  $.ajax({
    url: url,
    data: dataToPost,
    type: 'POST',
    success: function (data) {
      document.getElementById('ScheduledActivityShiftListHolder').innerHTML = data;
    },
    error: function () {
      v2ErrorNotice(v2Text.shared.genericAjaxErrorMessage);
    }
  });
});

Функции Get ... FIlter - это очень простые функции, которые выполняются за несколько миллисекунд ... ничего интересного или примечательного там не происходит.

этот бит придает очень медленное поведение: на других страницах они реагируют хорошо и быстро, на этой странице ... 2-3 секунды.

$('span.infoCard').die();
$('span.infoCard').live("mouseover", function () {

  var $this = $(this);
  if (!$this.data("toolTipAttached")) {

    var title = '';

    if ($this.attr('infoCardTitle') != "") {
      title = $this.attr('infoCardTitle');
    } else {
      title = $this.html();
    }

    $this.qtip({
      content: {
        text: "loading",
        title: title,
        ajax: {
          url: $this.attr('urlToGet')
          // data: data,
        }
      },
      position: {
        at: 'right middle',
        my: 'left top',
        adjust: {
          screen: 'flip'
        }
      },
      hide: {
        fixed: true,
        when: 'mouseout'
      },
      show: {
        solo: true,
        delay: 500,
        ready: true
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true,
        tip: {
          corner: true,
          width: 15,
          height: 15
        }
      }
    });
    $this.data("toolTipAttached", true);
  }
});

Есть 2 разные версии этого для 2 разных классов, один получает одну "смену", другой получает пользователь за кучу смен. как и с другими вещами. если сама функция работает быстро, ajax работает быстро, v2ReLoadScheduledActivitySection выполняется примерно за 50 мс. там ничего интересного. :

$('div.GetShiftUserArrow').die('click');
$('div.GetShiftUserArrow').live('click', function () {
  var listIsVisible = $(this).attr('listIsVisible');
  var holder = $('#' + $(this).attr('listHolder'));
  var activityHolder = $('#TopLevel{0}'.format($(this).attr('activityShiftId')));

  if (listIsVisible == -1) {
    v2ReLoadScheduledActivitySection($(this), 1);
  } else {
    holder.empty().toggle('hide');
    $(this).removeClass('GetShiftUserArrowOpen');
    $(this).attr('listIsVisible', listIsVisible * -1);
  }
});

Вот немного HTML. это

для дня ... в главном списке есть один из них для каждого дня года (или любого диапазона, который они выбирают). В этом списке может быть любое количество сублицензий, но обычно оно составляет от 1 до 10.
<li class="EntityRow" style="font-weight:normal;">
 <div class="TopLevelRow" sectiondate="1/21/2011 12:00:00 AM">
  <div class="ScheduleDayHeader OnlyFloatLeftInIE7" style="width:100%;margin-bottom:0px;font-weight:normal;">
   <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
    <div class="GetDayUserArrow OnlyFloatLeftInIE7" listisvisible="-1" sectiondate="1/21/2011 12:00:00 AM" url="/This/IsNot/TheReal/Url"></div>
   </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:380px;padding-bottom:2px;">Friday, January 21, 2011</span> <span class="TimeHolderSpan">Start</span> <span class="TimeHolderSpan">End</span> <span class="StatusIcons">Status</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Mn</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Mx</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">BU</span> <span class=
   "SkinnyColumn GlossaryMe" tooltip="A Number">Av</span> <span class="SkinnyColumn GlossaryMe" tooltip="Assigned">As</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Co</span>
  </div>

  <div class="ShiftListHolder" sectiondate="1/21/2011 12:00:00 AM">
   <ul class="ScheduledActivitiesForDayList EntityList FancyList SubList">
    <li class="EntityRow" activityshiftid="4645" id="ListItemFor4645">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="4645" url="/Some/Url=4645" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="4645">SomeText</span></span> <span class="TimeHolderSpan">9:00 AM</span> <span class="TimeHolderSpan">12:30 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe ClassToPickTheIcon' tooltip='Min # scheduled' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>

       <div class='TipMe LegendMe OtherClassToPickTheIcon' tooltip='Unlocked' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe AnotherClassToPickTheIcon' tooltip='Do not auto assign' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe ClassToPickTheIconAgain' tooltip='Do not autolock' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">--</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">2</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">0</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder4645" activityshiftid="4645"></div>
    </li>

    <li class="EntityRow" activityshiftid="4129" id="ListItemFor4129">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="4129" url="/Some/Url=4129" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="4129">Blah Bla blah</span></span> <span class="TimeHolderSpan">9:00 AM</span> <span class="TimeHolderSpan">5:00 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe ClassToPickTheIcon' tooltip='Min # scheduled' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>

       <div class='TipMe LegendMe OtherClassToPickTheIcon' tooltip='Unlocked' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe AnotherClassToPickTheIcon' tooltip='Do not auto assign' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe OtherClassForIcon' tooltip='on availabilities' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">0</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder4129" activityshiftid="4129"></div>
    </li>

    <li class="EntityRow" activityshiftid="3534" id="ListItemFor3534">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="3534" url="/Some/Url=3534" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="3534">even more</span></span> <span class="TimeHolderSpan">1:00 PM</span> <span class="TimeHolderSpan">4:30 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe SchedulingFullyA NumberIcon' tooltip='Min # A Number' legendgroupid='5'>
        <span class='NoDisplay'>4</span>
       </div>

       <div class='TipMe LegendMe LockedIcon' tooltip='Locked' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe ClassToPickTheIconAgain' tooltip='Auto assign' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe OtherClassForIcon' tooltip='on assignments' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">7</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">3</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder3534" activityshiftid="3534"></div>
    </li>
   </ul>
  </div>
 </div>
</li>
 ​

что-нибудь с TipMe, или GlossaryMe вызывает всплывающую подсказку qtip.

вот так:

 $(".TipMe").live("mouseover", function () {
  var $this = $(this);
  $this.removeAttr('title');
  $this.removeAttr('alt');

  if (!$this.data("toolTipAttached")) {

    $this.qtip({
      show: {
        ready: true,
        solo: true,
        delay: 500
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true
      },
      content: $this.attr('tooltip'),
      position: {
        at: 'bottomRight',
        my: 'topleft',
        adjust: {
          screen: 'flip',
          x: 0,
          y: 0
        }
      },
      hide: {
        fixed: true,
        inactive: 1000
      }
    });
    $this.data("toolTipAttached", true);
    //    $this.trigger("mouseover");
  }
});

Что-то подсказывает мне, что, возможно, все мои обработчики всплывающих подсказок вызывают проблему ...

Дайте мне знать, если вы, ребята, хотите что-нибудь еще!

Ответы [ 6 ]

7 голосов
/ 22 января 2011

"Я не думаю, что сложность моей разметки влияет на отзывчивость моих сценариев"

Ложные предположения - худшие лидеры ума. Это интересно, потому что вы также сказали:

"этот бит придает очень медленное поведение, на других страницах они реагируют красиво и быстро , на этой странице ... 2-3 секунды."

"у меня было 5 промежутков, каждый из которых был вложен в промежуток излишне , я удалил их, и, кажется, сократил медлительность примерно 1/2 !! (эти 5 интервалов повторялись в каждом ряду) "

Вот, пожалуйста. :)

Можно попробовать изменить live на delegate. Основное различие между ними заключается в том, что live прикрепляет Обработчик к документу, а в случае delegate вы можете указать, куда его прикрепить. Я думаю, что это может быть переломным моментом. Также попробуйте mouseenter, который срабатывает меньше часто.

$('#ROOT').delegate(".infoCard", "mouseenter", function () { ... })

root может быть любым элементом в зависимости от вашего сайта. Вы можете попробовать родительский <ul> например.

Еще одна попытка - использовать собственный обработчик (но вы не можете использовать mouseenter тогда):

$("#ROOT").mouseover(function (e) {
    var $this = $(e.target);
    if ($this.hasClass('TipMe')) {
        // TipMe code...
    } else if ($this.hasClass('infoCard')) {
        // infoCard code...
    }
});

Дайте мне знать, помог ли кто-нибудь из них! :)

5 голосов
/ 17 января 2011

Трудно дать конкретный ответ, не зная, как выглядит ваш код.

Если вы просто вносите небольшое изменение стиля при наведении курсора, тогда я бы предложил вам использовать CSS вместо javascript для его выполнения..

Псевдоселектор :hover не будет работать на <tr> в IE6, но он будет работать в других браузерах.

#myTable tr:hover {
    background: yellow;
}

Для тех элементов, которые требуют JavaScript,нам действительно нужно увидеть код, чтобы понять, почему он медленный.Похоже, вы, возможно, делаете ненужный выбор DOM.

Даже если производительность можно улучшить с помощью нумерации страниц или чего-то подобного для уменьшения размера, возможно, у вас все еще есть неэффективный код, который нужно немного сжать.

1 голос
/ 17 января 2011

Вы можете использовать селекторы jQuery для выполнения любых действий, которые вы делаете. Я бы определенно посмотрел на механизм подкачки. В определенный момент количество HTML, которое вы бросаете в механизм рендеринга, становится проблемой.

0 голосов
/ 21 января 2011

Если ваш JavaScript использует много памяти при работе в IE, это может замедлить работу. Проверьте потребление памяти, посмотрев на процесс iexplore.exe в диспетчере задач Windows. Если окажется, что IE использует много памяти, попробуйте оптимизировать свой код. Особо ищите:

  • Затворы, которые могут не выходить за рамки, особенно вложенные затворы
  • Циркулярные ссылки между dom и вашим сценарием
  • Чрезмерное количество ненужных постоянных ссылок dom в вашем скрипте

Еще одна вещь, которую вы можете попробовать - использовать document.querySelector для поиска элементов без идентификаторов в IE8 / IE9 / chrome / firefox (или element.querySelector). Пользователи IE7 должны будут страдать, но это то, что вы получаете за не обновление! ; -)

0 голосов
/ 17 января 2011

Может помочь некоторая реальная разметка, я предполагаю, что у вас есть что-то вроде (по крайней мере, в виде силуэта структуры).

<div class="list">
  <div id="item1">list html here</div>
  <div id="item2">list html here</div>
  <div id="item3">list html here</div>
  .
  .
  .
  <div id="item999990">list html here</div>
</div>

Проблема в том, что сканирование списка такого количества элементовдовольно медленный.

Есть ли способ разметки списка иерархически в разметке, даже если это не отображается графически.

, поэтому

<div class="list">
  <div id="cat1">
    <div id="item1">list html here</div>
    <div id="item2">list html here</div>
    <div id="item3">list html here</div>
    .
    .
    .
    <div id="item120">list html here</div>
  </div>
  .
  .
  .
  <div id="cat97">
    <div id="item99904">list html here</div>
    <div id="item99905">list html here</div>
    <div id="item99906">list html here</div>
    .
    .
    .
    <div id="item999990">list html here</div>
  </div>
</div>

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

0 голосов
/ 17 января 2011

проверьте бесконечный плагин jquery прокрутки. Это не решит проблемы производительности в IE как таковые, но позволит вам попробовать некоторые методы подкачки без разрывов страниц, чтобы посмотреть, будет ли это работать как решение.

http://plugins.jquery.com/project/endless-scroll

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