处理IE的可怕的Javascript/Dom访问引擎的建议

Pat*_*cia 7 javascript performance jquery internet-explorer

我正在开发一个页面可能会变得很长的网站.理论上它可以包含1000多行数据.然后这些行可以各有子行.

我目前正在使用列表/子列表结构来表示数据,因为很难在表中可视化子集.但子集数据在表格中.

问题是这样的:在IE中.我徘徊在行样式,工具提示和其他javascripts上需要花费5秒钟才能开火!这个页面像疯了一样挂起,几乎无法使用.在FF,Chrome和Safari中它运行得很好.

我不需要一大堆统计数据,说IE很慢.我知道它是.我需要的是关于如何对抗缓慢的一些建议/理论/想法!

到目前为止我有过一些想法: - 某种分页机制.但这很棘手b/c 1.这是一个列表而不是表,2.它有子子列表和子列表的子表.所以我们需要以某种方式基于我认为的顶级页面.因为我们根本不想分割数据.我想这可能是可行的......

- 一种将内容保存在javascript数组或对象或soomething中的机制,并且在滚动到dom之前不会将其添加到dom中.当你滚过它时把它带走.理论上这很酷.但我认为恭维是可怕的.

还有其他什么吗?

在此先感谢任何想法!一旦我能够帮助激励你,我可能会尝试为此付出一笔赏金;)

编辑:

天啊!我想我可能已经使用动态追踪找到了部分问题!感谢Pointy提醒我这个工具.我忘记了.我的一个按钮的点击事件似乎是疯狂的金额.像2000次和数.有些东西是自动点击它或类似的东西.奇怪的是,我没有任何触发按钮点击的javascripts!编辑:这似乎不再是一个问题.

编辑:

另外:我不认为我的标记的复杂性会影响我的脚本的响应性(我知道如果我可以使用id选择器,那将是最好的,但我已经尽可能地优化了我的选择器和qtips (在过去的帮助下).我有一个只在页面上的按钮,而不是嵌套在任何东西中,点击处理程序需要4或5秒才能注册.这不是点击动作需要很长时间,而是只是很慢地注意到它被点击了.

编辑:我有5个跨度,每个跨越不必要地嵌套在一个跨度,我un-nested那些,似乎已经减少约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);
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

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);
  }
});
Run Code Online (Sandbox Code Playgroud)

对于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);
  }
});
Run Code Online (Sandbox Code Playgroud)

这里有一些HTML.这是

  • 一天......主要列表中有一个是一年中的每一天(或者他们选择的任何范围).该列表中可以有任意数量的子li,但它往往在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>
     ?
    
    Run Code Online (Sandbox Code Playgroud)

    使用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");
      }
    });
    
    Run Code Online (Sandbox Code Playgroud)

    有些东西告诉我可能是我的所有工具提示处理程序导致问题......

    如果你们想要别的什么,请告诉我!

  • gbl*_*zex 7

    "我不认为我的标记复杂性会影响我脚本的响应能力"

    错误的假设是头脑中最糟糕的领导者.这很有趣,因为你也说过:

    "这一点附加了一些非常缓慢的行为,在其他页面中,他们反应良好而快速,在这个页面上...... 2-3秒."

    "我有5个跨度,每个跨度不必要地嵌套在一个跨度中,我没有嵌套那些,它似乎已经减少了大约1/2 的速度 !!(这些5个跨度在每一行重复)"

    你去吧 :)

    您可以尝试将live处理程序更改为delegate.它们之间的主要区别在于将Handlerlive附加到文档,而如果您可以指定附加它的位置.我认为这可能是引爆点.也可以尝试的时候触发较少频繁.delegatemouseenter

    $('#ROOT').delegate(".infoCard", "mouseenter", function () { ... })
    
    Run Code Online (Sandbox Code Playgroud)

    root可以是任何元素,取决于您的网站.<ul>例如,您可以尝试使用父级.

    要尝试的另一件事是使用自己的处理程序(但你不能使用mouseenter):

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

    让我知道他们是否有任何帮助!:)

    • 好的,我明白你的意思了.很好的一点.+1当你说mouseenter不经常发射时,我更专注于选择器对路径中的元素的触发.使用`mouseover`会更频繁地触发处理程序本身的功能,这是完全正确的. (2认同)

    use*_*716 5

    在不知道你的代码是什么样的情况下很难给出具体的答案.

    如果您只是在悬停时进行一些样式更改,那么我建议您使用CSS而不是javascript来完成它.

    :hover伪选择器将无法在工作<tr>中的IE6,但它会在其他浏览器.

    #myTable tr:hover {
        background: yellow;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    对于那些需要javascript的项目,我们真的需要查看代码才能知道它为什么慢.听起来你可能正在做不必要的DOM选择.

    即使性能可以通过分页或类似的东西来减少大小,也可能是你仍然有一些低效的代码应该收紧一点.