Angular 2 RC 5 Internet Explorer 10滚动性能较差 [英] Angular 2 RC 5 Internet Explorer 10 poor scroll performance

查看:115
本文介绍了Angular 2 RC 5 Internet Explorer 10滚动性能较差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用angular 2构建了一个产品目录应用程序,现在我正在调试IE的疣.所以,这就是发生的情况:我有一个CatalogComponent,其中包含一些子类别的组件,这些组件按类别显示产品.我在页面上有50至60个缩略图,因此页面上没有繁重的工作.该应用程序可在其他浏览器上完美运行,性能还可以.

I have built a product catalog app with angular 2 and now I am working on debugging the warts of IE. So, this is what happens: I have a CatalogComponent that contains a few children components that display the products in categories. I have 50-60 thumbnails in page so there is not a heavy load on page. The app works perfectly fine in other browsers, performance is ok.

CatalogComponent中,我有一个功能可以检测当前显示的类别.它监听滚动事件.

In CatalogComponent I have a function that detects what is the current displayed category. It listens to scroll events.

this.listeners.catalogScroll = this._renderer.listen(catalog, 'scroll',
    event => self.selectCategoryByScroll(event)
);

此特定功能不会带来任何繁重的负担.实际上,仅添加一个没有代码的简单scroll事件就足够了,并且目录div中的滚动性能会大跌眼镜.

This particular function does not do some heavy lifting. Actually it's enough to add just a simple scroll event with no code and scroll perfomance in the catalog div goes down the toilet.

catalog.addEventListener('scroll', function () {
    //console.log(1);
});

甚至更有趣的是,如果我调用scrollToCategory(),它会触发easeInQuad动画,该动画播放的画面比手动滚动页面更平滑.我认为这证明我的页面不太沉重,无法快速呈现.

Even funnier is that if I invoke scrollToCategory() it triggers a easeInQuad animation that plays smother than manually scrolling the page. I see this as proof that my page is not too heavy to render fast.

关于如何消除此问题的任何想法?

Any ideas on how to proceed to eliminate this issue?

修改

我刚刚观察到,这仅在通过拖动滚动条进行滚动时才会发生.通过滚轮滚动可以像超级按钮一样工作,不会降低性能.

I just observed that this happens only when scrolling by dragging the scrollbar. Scrolling by scroll wheell works like a charm, no performance dip.

推荐答案

如注释中所述,问题似乎在于IE触发了太多滚动事件.

As noted in the comments, the problem seems to be that IE is firing way too many scroll events.

此类问题的一般解决方案,例如在此问答线程中,将事件限制为某些合理的价格,例如像这样(使用 requestAnimationFrame ):

The general solution to such problems, as described e.g. in this Q&A thread is throttling the events to some reasonable rate, e.g. like this (using requestAnimationFrame):

var scrollEventPending = false;
function handleScrollEvent () {
    scrollEventPending = false;
    // handle the event here
}
function throttleScrollEvents () {
    if (scrollEventPending) return;
    scrollEventPending = true;
    requestAnimationFrame(handleScrollEvent);
});
window.addEventListener('scroll', throttleScrollEvents);

但是,此技术的局限性在于,受限制的事件处理程序仍需要触发才能检查先前触发的事件是否未决.对于您而言,似乎事件发生率可能很高,以至于这种琐碎的检查也足以引起明显的性能问题.

However, a limitation of this technique is that the throttled event handler still needs to fire in order to check whether a previously triggered event is pending. In your case, it seems like the event rate may be so high that even this trivial check can be enough to cause noticeable performance issues.

一种可能的解决方案是仅使用滚动事件处理程序来检测用户何时开始滚动,并暂时将其卸载,直到我们通过其他方式检测到为止(例如,比较页面X和Y的偏移量) ),表明滚动已停止:

One possible solution could be to use the scroll event handler only to detect when the user starts scrolling, and to uninstall it temporarily until we detect by other means (e.g. comparing the page X and Y offsets) that the scrolling has stopped:

var lastX = window.pageXOffset, lastY = window.pageYOffset;
function runWhileScrolling () {
    var currX = window.pageXOffset, currY = window.pageYOffset;
    if (currX == lastX && currY == lastY) {
        window.addEventListener('scroll', startScrolling);
        return;  // the page has stopped scrolling
    }

    // handle scrolling here

    lastX = currX; lastY = currY;
    requestAnimationFrame(runWhileScrolling);
}
function startScrolling () {
    window.removeEventListener('scroll', startScrolling);
    runWhileScrolling();
}
window.addEventListener('scroll', startScrolling);

这是一个演示此技术的简单实时代码段,此处用于模拟CSS固定位置:

Here's a simple live snippet demonstrating this technique, used here to emulate CSS fixed positioning:

var box = document.getElementById('jsfixed');
var lastX = window.pageXOffset, lastY = window.pageYOffset;
function runWhileScrolling () {
    var currX = window.pageXOffset, currY = window.pageYOffset;
    if (currX == lastX && currY == lastY) {
        window.addEventListener('scroll', startScrolling);
        return;  // the page has stopped scrolling
    }

    box.style.top = currY + 80 + 'px';
    box.style.left = currX + 10 + 'px';

    lastX = currX; lastY = currY;
    requestAnimationFrame(runWhileScrolling);
}
function startScrolling () {
    window.removeEventListener('scroll', startScrolling);
    runWhileScrolling();
}
window.addEventListener('scroll', startScrolling);

#cssfixed, #jsfixed {
  box-sizing: border-box;
  width: 250px; height: 50px;
  padding: 15px 5px;
  background: white;
}
#cssfixed {
  position: fixed;
  top: 20px; left: 10px;
  border: 2px solid green;
}
#jsfixed {
  position: absolute;
  top: 80px; left: 10px;
  border: 2px solid red;
}
body {
  width: 3000px;
  height: 3000px;
  background: url(https://i.stack.imgur.com/ybp2X.png);
}

<div id="cssfixed">This box is kept fixed by CSS.</div>
<div id="jsfixed">This box is kept fixed by JS.</div>

理想情况下,滚动页面时,这两个框不应完全相对移动.在Chrome 57,Opera 44和Firefox 49上确实如此.在IE 11上,滚动时红色框确实会移动并明显闪烁,但至少滚动本身是平滑的,滚动后框会正确返回其原始位置.

Ideally, the two boxes shouldn't move at all with respect to each other as the page is scrolled. On Chrome 57, Opera 44 and Firefox 49, this is indeed the case. On IE 11, the red box does move and flicker noticeably while scrolling, but at least the scrolling itself is smooth and the box correctly returns to its original position after scrolling.

请注意,如上所述,使用requestAnimationFrame通常会导致页面滚动时每秒调用滚动处理程序约60次.如果您不需要如此频繁的更新,可以将其替换为例如setTimeout(runWhileScrolling, 200)(每秒更新5次).

Note that using requestAnimationFrame like above typically causes the scroll handler to be called about 60 times per second while the page is scrolling. If you don't need such frequent updates, you could replace it with e.g. setTimeout(runWhileScrolling, 200) (for 5 updates per second).

这篇关于Angular 2 RC 5 Internet Explorer 10滚动性能较差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆