客户端模板引擎中的性能渲染缓慢 (Rivets.js)

Slow performance rendering in client templating engine (Rivets.js)

我正在渲染大约 1000 个对象的数组。 html 绑定非常重(见下文)。 rivets.bind().

大约需要 5 秒

有什么改进性能的建议吗?我不认为我可以负担得起块绑定,因为我正在使用 pagination/sorting 库结合,需要整个数组才能 sort/paginate.

这是我的每个对象(轨道)的 HTML:

<div rv-each-track="tracks" class="track-row row has-hover" rv-download-url="track.direct_path.download_path" rv-api-key="track.track.apikey" rv-media-url="track.direct_path.audio" rv-track-title="track.track.name" rv-wave-data="track.direct_path.wave_default" rv-wave-progress-data="track.direct_path.wave_progress">
<div class="mobile-margin">
    <div class="track-hover desktop-only">
        <div class="hover-play icon-play inline-play"></div>
        <div class="hover-title"><a href="#" class="track-link">{track.track.name}</a><span rv-class="track.track.staff_pick | staffPickClass" data-toggle="tooltip" data-original-title="Staff Pick"></span></div>
        <div class="hover-links">
            <div class="item hamburger holds-tooltip main-hover-item icon-hamburger" data-toggle="tooltip" data-original-title="Alternate Versions"></div>
            <div class="item share main-hover-item popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
            <div class="item playlist icon-playlist-add popover-button holds-tooltip main-hover-item" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist"></div>
            <div class="item download icon-download holds-tooltip main-hover-item" data-toggle="tooltip" data-original-title="Download Track"></div>
            <div class="item cart last icon-cart-plus holds-tooltip main-hover-item popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
            <div class="item remove last icon-x holds-tooltip main-hover-item" data-toggle="tooltip" data-original-title="Remove Track" rv-data-delete-track-id="track.track.apikey"></div>
            <div class="clearfix"></div>
        </div>
        <div class="clearfix"></div>
        <div class="track-variations">
            <div rv-each-variation="track.variations.tracks" class="row variation-row" rv-data-track-id="track.track.apikey" rv-api-key="variation.track.apikey" rv-media-url="variation.direct_path.audio" rv-track-title="variation.track.name" rv-wave-data="variation.direct_path.wave_default" rv-wave-progress-data="variation.direct_path.wave_progress">
                <div class="col-md-8 variation-title">{variation.track.name}</div>
                <div class="col-md-2 variation-length">{variation.track.tracklength}</div>
                <div class="track-hover variation">
                    <div class="hover-play icon-play inline-play"></div>
                    <div class="hover-title"><a class="track-link">{variation.track.name}</a></div>
                    <div class="hover-links">
                        <div class="item share popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
                        <div class="item playlist popover-button icon-playlist-add" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist" data-placement="left"></div>
                        <div class="item download icon-download" rv-data-media-url="track.direct_path.download_path" data-toggle="tooltip" data-original-title="Download Track" data-placement="left"></div>
                        <div class="item cart last icon-cart-plus holds-tooltip popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
                        <div class="item last remove main-hover-item icon-x"></div>
                        <div class="clearfix"></div>
                    </div>
                    <div class="clearfix"></div>
                </div>
            </div>
            <div class="no-variations" rv-hide="track.variations.tracks | shouldHideNoVariations">There are no alternate versions of this track.</div>
        </div>
    </div>
    <div class="col-md-4 first-title desktop-only"><a class="offset-left track-title-link track-link" href="">{track.track.name}</a><span rv-class="track.track.staff_pick | staffPickClass" data-toggle="tooltip" data-original-title="Staff Pick"></span></span></div>
    <div class="col-md-3 genre desktop-only"><span class="offset-left">{track.genre}</span></div>
    <div class="col-md-2 mood desktop-only"><span class="offset-left">{track.mood}</span></div>
    <div class="col-md-2 canvas desktop-only"><div class="mini-wave offset-left" rv-style-background-image="track.direct_path.wave_canvas"></div></div>
    <div class="col-md-1 last-title duration desktop-only"><span>{track.track.tracklength}</span></div>
    <div class="col-md-1 last-title last-played pull-right desktop-only">{track.lastPlayed}</div>

    <div class="mobile-play icon-play pull-left mobile-only inline-play"></div>
    <div class="mobile-track-title mobile-only track-row-item-margin"><div class="track-title-link">{track.track.name}</div><span rv-class="track.track.staff_pick | staffPickClass"></span></div>
    <div class="mobile-track-buttons pull-right">
        <div class="pull-right mobile-only mobile-button mobile-track-menu-button left-margin icon-plus"></div>
        <div class="pull-right mobile-only mobile-button mobile-variations-button icon-hamburger"></div>
    </div>

    <div class="is-staff-pick hidden">{track.track.staff_pick | staffPickValue}</div>
    <div class="instrument hidden">{track.instrument}</div>
    <div class="industry hidden">{track.industry}</div>
    <div class="tempo hidden">{track.tempo}</div>
    <div class="aggregated-terms hidden">{track.tag_list} {track.track.name}</div>
    <div class="date-last-played hidden">{track.dateLastPlayed}</div>
    <div class="clearfix"></div>
</div>
<div class="track-variations mobile-only">
    <div rv-each-variation="track.variations.tracks" class="row variation-row" rv-api-key="track.track.apikey" rv-media-url="variation.direct_path.audio" rv-track-title="variation.track.name">
        <div class="mobile-margin">
            <div class="col-md-8 variation-title desktop-only">{variation.track.name}</div>
            <div class="col-md-2 variation-length desktop-only">{variation.track.tracklength}</div>
            <div class="track-hover variation">
                <div class="hover-play icon-play inline-play"></div>
                <div class="hover-title"><a href="" class="track-link">{variation.track.name}</a></div>
                <div class="hover-links">
                    <div class="item share popover-button icon-share" data-target="#not-ready-popover"><div class="tooltip-holder holds-tooltip" data-toggle="tooltip" data-original-title="Share Track"></div></div>
                    <div class="item playlist popover-button icon-playlist-add" data-target="#playlist-popover" data-toggle="tooltip" data-original-title="Add to Playlist" data-placement="left"></div>
                    <div class="item download icon-download" data-toggle="tooltip" data-original-title="Download Track" data-placement="left"></div>
                    <div class="item cart last icon-cart-plus holds-tooltip popover-button" data-target="#not-ready-popover" data-toggle="tooltip" data-original-title="Add to Cart"></div>
                    <div class="item last remove main-hover-item icon-x"></div>
                    <div class="clearfix"></div>
                </div>
                <div class="clearfix"></div>
            </div>

            <div class="mobile-play icon-play pull-left mobile-only inline-play"></div>
            <div class="mobile-track-title mobile-only track-row-item-margin"><div class="track-title-link">{variation.track.name}</div></div>
            <div class="mobile-track-buttons pull-right">
                <div class="pull-right mobile-only mobile-button mobile-track-menu-button left-margin icon-plus"></div>
            </div>

        </div>
    </div>
    <div class="no-variations" rv-hide="track.variations.tracks | shouldHideNoVariations">There are no alternate versions of this track.</div>
</div>

  • 不要执行铆钉事件示例:rv-click 这会降低您的性能,因为您将为回调方法传递整个视图。
  • 不要将整个视图传递给 rivets.bind()
  • 只传递必要的模型并执行。
  • 如果可能,首先绑定 100 个元素,然后如果用户滚动了一半页面,则再次绑定 100 个元素,这肯定会提高您的性能。
  • 我对活页夹进行了以下更改,以使其 运行 即使在低端移动设备上也更快。

    rivets.binders.text = function(el, value) {
     if (el.textContent != null) { 
         return el.textContent;
     }
     else {
       return el.innerText;
     }
     }; 
    
    
    

我得出的结论是,是的,对于使用铆钉将 1000 多个(大型 html)对象绑定到 DOM,我可能会实现较小的性能改进。然而,根本问题是我试图一次将 1000 多个铆钉绑定到 DOM 中,并且使用任何技术都会很慢(我已经用 React 测试过,jQuery, 铆钉等...).

这个问题的解决办法就是另辟蹊径。我选择在服务器上预呈现 html 并通过 API 响应提供它。这将页面加载时间从约 5 秒减少到约 1 秒。