Javascript 资产。图像慢吗?我如何执行函数,使它们不';不要冻结浏览器?

Javascript 资产。图像慢吗?我如何执行函数,使它们不';不要冻结浏览器?,javascript,mootools,Javascript,Mootools,我最近下载了一个不错的mootools插件,为我的网站上的搜索结果提供了一个评级系统: 它工作得很好,但初始化速度非常慢。以下是我记录的执行时间(用于回调50个搜索结果) 以下是这些日志所指的初始化功能(仅供参考): 因此,函数最慢的部分是: // Preload images try { Asset.images([ this.options.imageEmpty, this.options.imageFull,

我最近下载了一个不错的mootools插件,为我的网站上的搜索结果提供了一个评级系统:

它工作得很好,但初始化速度非常慢。以下是我记录的执行时间(用于回调50个搜索结果)

以下是这些日志所指的
初始化
功能(仅供参考):

因此,函数最慢的部分是:

    // Preload images
    try {
        Asset.images([
        this.options.imageEmpty,
        this.options.imageFull,
        this.options.imageHover
    ]);
    } catch (e) { };
这很奇怪。
Asset.images
做什么?在浏览器加载这些图像之前,脚本是否会阻止?有没有一种方法可以预加载运行更快的图像


如何使页面上的脚本执行得更快?对他们来说,执行800毫秒是个大问题,但200毫秒仍然很糟糕。现在,我的搜索结果一下子就出现了。是否可以使单个搜索结果单独创建,以便它们在创建时不会阻止浏览器?类似地,是否可以对搜索结果的各个组件(如Moostarting插件)执行此操作?

no.Asset.images是非阻塞的,因为每个组件都单独加载,并且在完成所有操作后,将调度单个事件

加载速度将取决于浏览器,但它将是多线程的,可以从同一主机并行下载

它立即返回一个元素集合,并承诺仍在下载的元素。这很好-您可以使用它来注入els、附加事件、类等-您只是无法读取图像属性,如宽度、高度

每个单独的图像都有自己的
onload
触发
onProgress
,完成后,该批次的
onComplete
——我建议您启用该功能,移除try/catch块,并查看哪个图像会造成延迟。您当然不需要等待Asset.images中的任何内容返回

您似乎还将它用作“prime the cache”方法,而不是任何东西,因为您并没有真正将引用保存到类实例中。您的“每个”迭代可能都会得到优化,因此如果对象和函数被缓存,引用也被缓存,那么它将占用一半的时间。如果可以使用事件委派,可能会更多


为了回答由于javascript的单线程特性而没有冻结浏览器的问题,您可以通过setTimeout(或mootools中的Function.delay)延迟代码,并根据浏览器的解释将计时器设置为0或10ms。您还可以编写函数,以便在完成时执行回调,在回调中可以传递函数结果(如果有的话)(想想ajax!)

谢谢你的帮助。我查看了
每个
循环,以对其进行优化-
设置样式
的速度惊人地慢!通过将该函数的3个调用压缩为1,我节省了大量时间。这是一个缓慢的过程,因为它会将每个属性重载到
元素。setStyle
-最好是添加一个CSS类,然后添加任何位置/高度等来更改样式本身。您添加的事件也可以保存到类中,而不是在每个循环等的新函数中创建——如果您事先不委托它们的话。可获得的好处很多:)
initialize: function (options) {

    lstart("starrating");

    // Setup options
    this.setOptions(options);

    // Fix image folder
    if ((this.options.imageFolder.length != 0) && (this.options.imageFolder.substr(-1) != "/"))
        this.options.imageFolder += "/";

    // Hover image as full if none specified
    if (this.options.imageHover == null) this.options.imageHover = this.options.imageFull;

    lrec("init");

    // Preload images
    try {
        Asset.images([
        this.options.imageEmpty,
        this.options.imageFull,
        this.options.imageHover
    ]);
    } catch (e) { };

    lrec("img");

    // Build radio selector
    var formQuery = this.options.form;
    this.options.form = $(formQuery);
    if (!this.options.form) this.options.form = $$('form[name=' + formQuery + "]")[0];
    if (this.options.form) {
        var uniqueId = 'star_' + String.uniqueID();
        this.options.form.addClass(uniqueId);
        this.options.selector += 'form.' + uniqueId + ' ';
    }
    this.options.selector += 'input[type=radio][name=' + this.options.radios + "]";
    // Loop elements
    var i = 0;
    var me = this;
    var lastElement = null;
    var count = $$(this.options.selector).length;
    var width = this.options.width.toInt();
    var widthOdd = width;
    var height = this.options.height.toInt();
    if (this.options.half) {
        width = (width / 2).toInt();
        widthOdd = widthOdd - width;
    }

    lrec("str");

    $$(this.options.selector).each(function (item) {

        // Add item to radio list
        this.radios[i] = item;
        if (item.get('checked')) this.currentIndex = i;

        // If disabled, whole star rating control is disabled
        if (item.get('disabled')) this.options.disabled = true;

        // Hide and replace
        item.setStyle('display', 'none');
        this.stars[i] = new Element('a').addClass(this.options.linksClass);
        this.stars[i].store('ratingIndex', i);
        this.stars[i].setStyles({
            'background-image': 'url("' + this.options.imageEmpty + '")',
            'background-repeat': 'no-repeat',
            'display': 'inline-block',
            'width': ((this.options.half && (i % 2)) ? widthOdd : width),
            'height': height
        });
        if (this.options.half)
            this.stars[i].setStyle('background-position', ((i % 2) ? '-' + width + 'px 0' : '0 0'));
        this.stars[i].addEvents({
            'mouseenter': function () { me.starEnter(this.retrieve('ratingIndex')); },
            'mouseleave': function () { me.starLeave(); }
        });

        // Tip
        if (this.options.tip) {
            var title = this.options.tip;
            title = title.replace('[VALUE]', item.get('value'));
            title = title.replace('[COUNT]', count);
            if (this.options.tipTarget) this.stars[i].store('ratingTip', title);
            else this.stars[i].setProperty('title', title);
        }

        // Click event
        var that = this;
        this.stars[i].addEvent('click', function () {
            if (!that.options.disabled) {
                me.setCurrentIndex(this.retrieve('ratingIndex'));
                me.fireEvent('click', me.getValue());
            }
        });

        // Go on
        lastElement = item;
        i++;

    }, this);

    lrec("each");

    // Inject items
    $$(this.stars).each(function (star, index) {
        star.inject(lastElement, 'after');
        lastElement = star;
    }, this);

    lrec("inject");

    // Enable / disable
    if (this.options.disabled) this.disable(); else this.enable();

    // Fill stars
    this.fillStars();

    lrec("end");

    return this;
},
    // Preload images
    try {
        Asset.images([
        this.options.imageEmpty,
        this.options.imageFull,
        this.options.imageHover
    ]);
    } catch (e) { };