【问题标题】:Will infinite scroll cause browser crashes?无限滚动会导致浏览器崩溃吗?
【发布时间】:2012-04-29 18:17:35
【问题描述】:

我像这样实现了无限滚动:

new_page_value = 1;

$(window).scroll(function() {
    if($(window).scrollTop() >= $(document).height() - $(window).height() - 200) {

        new_page_value = parseInt(new_page_value) + 1;

        get_page(new_page_value);

    }
});

当用户几乎到达页面底部(左200px)时,函数get_page()被调用。这包含一个 ajax 调用,该调用获取新页面的所有内容并将其追加到文档的<body>

现在我刚刚意识到,如果我的网站变得很大,而不是只有 10 个小页面,而是拥有数以亿计的巨型页面,那么如果用户的浏览器足够持久以保持长时间无限滚动,那么用户的浏览器可能会崩溃。

这是解决这个问题的可能方法吗:

我将继续将新页面附加到文档<body> 直到第 10 页,之后我将完全替换 <body> 内容而不是附加内容。所以使用html() 而不是append()

我只是不知道这是否真的可以防止崩溃。 .html() 会清除通过 ajax 引入的先前 html 的“内存”吗?

【问题讨论】:

    标签: javascript jquery browser crash


    【解决方案1】:

    我真的认为这是许多具有 AJAX 列表内容的网站的常见问题。因此,让我们以一些最流行的(想想规模 = 经验)网站及其解决方案为例:

    谷歌图片

    如果您查看 images.google.com 并搜索任何内容,例如“guiness”,您将看到一个充满结果的页面(实际上图像是 ajax 加载的,而不是 html 代码,因此页面具有固定高度)并且当您在底部滚动时有一个按钮 "Show more results"。这可能是您的问题的解决方案之一,但是否真的有必要在底部放置一个按钮,例如第 10 页?我真的认为它通常是页面可用性和内存泄漏的一个很好的解决方案,但它确实不是一个必要的选择,正如我们在中看到的那样:

    脸书

    Facebook Newsfeed 是另一回事。有一个按钮"Show more posts",但我真的不知道它何时显示而不是加载下一页帖子。我曾经发生过一次加载 10-15 页的帖子,只能通过滚动。而且你知道 Facebook 帖子包括视频、照片、AJAX cmets 和许多更多的 Javascript 奇特的东西,它们会占用大量内存。我认为他们经过大量研究后设法做到了这一点,有多少用户滚动到底部。

    YouTube

    Youtube 在每个页面上都有"Load more videos",所以解决方案基本上类似于谷歌,除了谷歌呈现页面的整个 html 并且滚动时只加载图像。

    推特

    Twitter 支持无限滚动。是的,他们这样做可能是因为推文有 140 个字符,他们不需要太担心内存。毕竟谁愿意在一页加载时阅读超过 1000 页的推文。所以他们没有"load more" 的按钮,也不需要。

    所以有两种解决方案:

    1. 使用无限滚动(您应该考虑加载的内容量和内容的丰富程度)
    2. 使用按钮:"Load More"

    最重要的是,您不应该删除列表中已加载的内容。

    现在一切都是 Javascript 并且 Javascript 有 garbage collection,因此很难卸载 DOM(如果它有 Javascript,而不是纯文本)并设法从 Javascript 中删除垃圾。这意味着您不会从浏览器中释放已卸载内容的全部分配内存。

    还要考虑您的请求,为什么您需要再次加载您已经加载的内容。它需要另一个服务器请求,这意味着另一个数据库请求等等。

    【讨论】:

      【解决方案2】:

      我以前曾使用过这个,以下是我的一些想法:

      a) 如果您一次将数据附加到内存页面,那么这不是问题,一些浏览器可能响应不佳,但大多数最新的浏览器将毫无问题地呈现,只要有足够的目标机器上的内存,您可能会看到附加页面时内存使用量如何增加。为此使用 chrome,因为每个页面都是一个单独的进程,并且它有一个内置的任务管理器

      b) 关于html() 的使用,它确实删除了标记,但这样做的成本很高,因为它试图处理特殊条件并且有开销并访问嵌套在您所在容器中的所有控件更换(不确定最后一次拍),但它是有代价的。清除 DOM 的一种更简单的方法是使用 innerHTML 属性并将其设置为空,jquery 会这样做,但它稍后会在 html() api 中使用。打开api看看方法。 使用innerHTML

      $("<selector>")[0].innerHTML=""

      作为用户,删除页面对我来说听起来很奇怪,如果我想回到最初的 cmets 怎么办,请不要考虑让它成为无限滚动器。我已经尝试并在错误数量之后放弃了提出了,但我们有一个真正的用例,我不得不在那里放一个按钮,但这不是当用户滚动离开第一页时,这是用户登陆第三页但现在需要查看结果的时候在它上面。

      希望能回答您的问题,顺便说一句,无限滚动是您的朋友使用它,不要过度设计可能只会由您的 QA 团队测试的案例。最好把精力花在其他地方。

      【讨论】:

      • html() 的行为是这样的,因为在将节点从 DOM 中取出之前未能删除事件处理程序会导致内存泄漏。如果您要规避这一点,请在触摸 innerHTML 之前跟踪您自己的事件处理程序并清除它们。
      • @eyelidlessness 是的,你是对的.. 但是你能引导我到一个资源,我可以通过示例阅读这个资源
      【解决方案3】:

      是的,如果我可以在说 5 页后提出一个想法,只需删除第一页并附加新的,而不是删除所有以前的页面。祝你好运:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-11
        • 1970-01-01
        相关资源
        最近更新 更多