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

查看:99
本文介绍了使用$ .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选择器 $(...)

这个。$ 的代理。$ 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的核心功能( $())可能会失败。所以最好总是通过操作。$ 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;
},

为了避免与悬空侦听器发生内存泄漏,调用<$ c非常重要在忘记它之前,在每个视图上删除$ c>删除。

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

我通过将实际调用推迟到删除,这样我们就不会在用户等待时浪费时间。

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天全站免登陆