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