使用 $.html() 时如何提高渲染性能 [英] How to improve rendering performance when using $.html()

查看:18
本文介绍了使用 $.html() 时如何提高渲染性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个显示推文列表的 Backbone 演示应用.当我用不同的数据替换所有推文"时,我使用 $.html()

I am working on a Backbone demo app that shows a list of tweets. As I am replacing all the "tweets" with different data I clear the list using $.html()

render: function() {
    $("#item-table").html('');
    this.collection.each(this.addItem);
}

我想知道是否有人可以给我一个提示,我可以替换这个 $.html() 以获得更好的性能,因为通过使用 $.html()我导致回流,这给了糟糕的布局过程时间.

I was wondering if anyone could give me a hint with what can I replace this $.html() for better performance, because by using $.html() I am causing reflows and which gives bad layout process times.

我在代码中还有另外两个地方使用了 $.html(),如果有人能就如何更改这些地方提供建议的话,那就太好了可能.

There are two other places in the code where I use $.html() and it would be really great if someone could give me advice on how to change those too if those other places are even possible.

推荐答案

创建一个新的DocumentFragment预渲染所有项目,然后更新一次 DOM.

Create a new DocumentFragment to pre-render all the items, then update the DOM once.

另外,支持 this.$(...)通过全局 jQuery 选择器 $(...).

this.$this.$el.find(...) 的代理,它更高效,并且更不容易选择视图之外的内容.

this.$ is a proxy to this.$el.find(...) which is more efficient, and less prone to select something outside of the view.

如果视图尚未呈现,则在视图中使用 jQuery 的核心函数 ($()) 可能会失败.因此,最好始终通过 this.$el 进行操作,这样您甚至可以在将视图实际放入 DOM 之前进行更改.

Using jQuery's core function ($()) inside a view can fail if the view wasn't rendered yet. So it's better to always manipulate through this.$el so you can make changes even before the view is actually put in the DOM.

将所有创建的子视图保留在一个数组中,以便以后干净地删除它们.

Keep all the sub views created in an array to cleanly remove them later.

initialize: function() {
    this.childViews = [];
},
render: function() {
    // cache the list jQuery object
    this.$list = this.$("#item-table");

    // Make sure to destroy every child view explicitely 
    // to avoid memory leaks
    this.cleanup();

    this.renderCollection();
    return this;
},

真正的优化从这里开始,使用一个临时容器.

The real optimization starts here, with a temporary container.

renderCollection: function() {
    var container = document.createDocumentFragment();

    this.collection.each(function(model) {
        // this appends to a in memory document
        container.appendChild(this.renderItem(model, false).el);
    }, this);

    // Update the DOM only once every child view was rendered.
    this.$list.html(container);
    return this;
},

我们的 renderItem 函数仍可用于渲染单个项目视图并立即将其放入 DOM.但它也提供了一个选项来推迟 DOM 操作,它只是返回视图.

Our renderItem function can still be used to render a single item view and immediatly put it in the DOM. But it also provides an option to postpone the DOM manipulation and it just returns the view.

renderItem: function(model, render) {
    var view = new Item({ model: model });

    this.childViews.push(view);
    view.render();
    if (render !== false) this.$list.append(view.el);
    return view;
},

为了避免悬空侦听器的内存泄漏,重要的是在忘记之前对每个视图调用 remove.

To avoid memory leaks with dangling listeners, it's important to call remove on each view before forgetting about it.

我通过延迟对 remove 的实际调用来使用额外的优化,这样我们就不会在用户等待时浪费时间.

I use an additional optimization by deferring the actual call to remove so we don't waste time now while the user waits.

cleanup: function() {
    var _childViewsDump = [].concat(this.childViews);
    this.childViews = [];

    while (_childViewsDump.length > 0) {
        var currentView = _childViewsDump.shift();
        // defer the removal as it's less important for now than rendering.
        _.defer(currentView.remove.bind(currentView), options);
    }
}

这篇关于使用 $.html() 时如何提高渲染性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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