【问题标题】:Custom Lazy Load - IE9 Memory Leak自定义延迟加载 - IE9 内存泄漏
【发布时间】:2014-05-13 12:22:23
【问题描述】:

我目前正在开发一个基本图片库,它可以按以下顺序动态加载新图片(在 document.ready 上):

  1. 使用 ajax 调用获取 JSON,其中包含动态呈现图像所需的所有信息。

  2. 遍历 JSON 对象以创建适当的 divs/img 元素,然后将其附加到页面。

                $.ajax({
                url: '/wp-content/themes/base/library/ajax/posts-json.php',
                type: 'get',
                //dataType: 'json',
                success: function(data) {
                    // turn string response to JSON array
                    window.responseArray = JSON.parse(data);
    
                    window.lastPhotoIndex = 0;
    
                    // make sure there is a response
                    if (responseArray.length > 0) {
                        // get container
                        var container = document.getElementById("photos-container");
                        var ulElement = document.createElement('ul');
                        ulElement.className = "rig columns-3";
                        ulElement.setAttribute("id", "photo-list");
    
                        // iterate over each response
                        window.photoCount = 0;
                        for (var i = 0; i < responseArray.length; i += 1) {
                            // Only load first 10 images
                            if (responseArray[i]["post-type"] == "photo" && photoCount < 20) {
                                // Set the last photo index to this photo
                                lastPhotoIndex = i;
                                // create the li
                                var liElement = document.createElement("li");
    
                                liElement.className = liElement.className + responseArray[i]["day"];
    
                                //create class name string from WP tags
                                if (responseArray[i].tags.length > 0) {
                                    for (var ii = 0; ii < responseArray[i].tags.length; ii += 1) {
                                        nospaceTagName = responseArray[i].tags[ii].split(' ').join('');
                                        liElement.className += " " + nospaceTagName;
                                    }
                                }
    
                                //create image element and append to div
                                var imgTag = document.createElement("img");
                                imgTag.src = responseArray[i]["thumb-url"];
                                liElement.appendChild(imgTag);
    
                                //Add modal class info to outer div
                                liElement.className += " md-trigger";
                                //Add data-modal attribute to outer div
                                liElement.setAttribute("data-modal", "photo-modal");
    
                                ulElement.appendChild(liElement);
    
                                //next slide
                                photoCount++;
                            }
                        }
                        //append ul to container
                        container.appendChild(ulElement);
                    }
                },
                error: function(xhr, desc, err) {
                    console.log(xhr);
                    console.log("Details: " + desc + "\nError:" + err);
                }
    
            });// end ajax call
    
  3. 在 ajax 调用之后,我添加了一个窗口滚动事件,当 JSON 对象中还有更多照片时将调用该事件。

                // Window scroll event
            $(window).scroll(function () {
                var trigger = $(document).height() - 300;
                if (trigger <= $(window).scrollTop() + $(window).height()) {
                    //Call function to load next 10
                    loadNextPhotos();
    
                }
            });
    
  4. 滚动调用的函数甚至只是从先前停止的索引处开始(在 ajax 调用开始时设置的 lastPhotoIndex 变量 - 'window.lastPhotoIndex')。函数如下所示:

    function loadNextPhotos() {
    if (photoCount < getPhotoCount()) {
        var photosOutput = 0;
        var startingIndex = lastPhotoIndex + 1;
        var photoList = $('#photo-list');
        for (var i = startingIndex; i < responseArray.length; i += 1) {
            if (responseArray[i]["post-type"] == "photo" && photosOutput < 10) {
                lastPhotoIndex = i;
                photosOutput++;
                // create the li needed
                var element = document.createElement("li");
    
                element.className = responseArray[i]["day"];
    
                //create class name string from tags
                if (responseArray[i].tags.length > 0) {
                    for (var ii = 0; ii < responseArray[i].tags.length; ii += 1) {
                        nospaceTagName = responseArray[i].tags[ii].split(' ').join('');
                        element.className = element.className + " " + nospaceTagName;
                    }
                }
    
                //create image element and append to li
                var imgTag = document.createElement("img");
                imgTag.src = responseArray[i]["thumb-url"];
    
    
                element.appendChild(imgTag);
    
                //Add modal class info to li
                element.className = element.className + " md-trigger";
                //Add data-modal attribute to outer div
                element.setAttribute("data-modal", "photo-modal");
    
                photoList.append(element);
    
                // Keep track of photo numbers so modal works for appropriate slide number
                photoCount++;
            }
        }
    }
    

    }

请记住,这段代码从完整的应用程序中删除了很多。它在 Chrome、Safari、Firefox、IE10+ 中运行良好。

在 IE9 中加载时,我遇到了疯狂的内存泄漏,因为我点击了滚动事件并将更多项目附加到 UL。

我的猜测是,在创建要附加的新项目时,我没有遵循最佳实践,并且它们在内存中的停留时间超过了应有的时间。唯一的问题是我不确定如何解决它/调试它,因为页面在 IE9 中崩溃得非常快。

任何帮助都会很棒。谢谢!

编辑:

我尝试实施 Darmesh 的解决方案,但没有真正的运气。正如我在他的评论中所说,它只会延迟内存泄漏的速度。我还在滚动事件的顶部添加了jquery.visible.js,所以它看起来像这样:

$(window).scroll(function () {
if($('#lazy-load-trigger').visible() && window.isLoadingPhotos != true) {
    console.log("VISIBLE!");
    loadNextPhotos();
}

});

但它也只会延迟内存泄漏。我仍然认为 IE9 中的垃圾收集存在问题,但不知道如何解决。

【问题讨论】:

    标签: javascript jquery ajax performance internet-explorer


    【解决方案1】:

    我认为这是由于每次滚动时浏览器同时多次调用loadNextPhotos 函数。这可能有效,试一试,

    function loadNextPhotos() {
        // Add flag to indicate new photos adding started
        window.isLoadingPhotos = true;
        ....
        ....
        ....
        ....
        // Indicate new photos adding completed
        window.isLoadingPhotos = false;
    }
    

    还有,

    $(window).scroll(function () {
        var trigger = $(document).height() - 300;
        if (trigger <= $(window).scrollTop() + $(window).height()) {
            if(!window.isLoadingPhotos) {
                //Call function to load next 10
                loadNextPhotos();
            }
        }
    });
    

    【讨论】:

    • 谢谢,我试试看!
    • 虽然这会延迟页面冻结的速度,但我似乎仍然有内存泄漏。我尝试添加 jquery.visible.js 来帮助防止泄漏,但它仍然只会延迟它发生的速度。在编辑中查看我的更新。
    • photoList.append(element); 之后将element 设置为null,似乎IE9 不会垃圾收集DOM 对象,因为DOM 对象不在JScript 的标记和清除垃圾收集方案中。
    猜你喜欢
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 2023-02-11
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    相关资源
    最近更新 更多