编辑:jqueryval是罪魁祸首(不引人注意吧?)。不知道为什么它会影响任何东西,因为我们在设置中的复选框上禁用了它。但是,对引用进行注释会使加载时间变得不可察觉。我已经尝试了几个没有运气的修复。
这是导致减速的函数,jquery.validate.js中的第532行
elements: function() {
*snip*
return $( this.currentForm )
.find( "input, select, textarea" )
.not( ":submit, :reset, :image, [disabled], [readonly]" )
.not( this.settings.ignore ) //performance murderer
*snip*
},
*注意 - 我在此之后剪切了过滤器功能,因为在测试中我没有使用它并仍然减速,所以它并不真正相关。
我也从验证中删除了复选框:
$.validator.setDefaults({
ignore: ":hidden, input[type=checkbox]" //do not validate checkboxes
});
我有一个mvc应用程序,它将在2000+以上的复选框中发回服务器。这通常不是问题,通过jquery选择器与站点的交互运行完全正常,加载时间很快。但是,提交会导致某种重排问题,其中每个文本框及其标签offsetHeight和offsetWidth都会被检查。在创建和保存编辑时,这会加剧超过5秒的加载时间。
...开始
...完
(我很确定它刚刚在那里放弃了,但是有2000多个事件你可以滚动它几分钟)
初始负载会受到影响,但随着用户更多地使用该网站,其中许多复选框将被“禁用”,我理解这意味着他们将不再发布回复。不幸的是,禁用这些文本框并不会导致元素的数量回发丢弃。我觉得这与MVC有关,但这里是代码:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<fieldset>
<legend><input type="submit" value="Create"/> | @Html.ActionLink("Back to List", "Index", "CatManager")</legend>
@if (Model.CategoryViewModel.ChildCategoryNodes.Any())
{
for (int i = 0; i < Model.CategoryViewModel.ChildCategoryNodes.Count(); i++)
{
@Html.HiddenFor(model => model.CategoryViewModel.ChildCategoryNodes[i].Id)
@Html.HiddenFor(model => model.CategoryViewModel.ChildCategoryNodes[i].Description)
<label @(Model.CategoryViewModel.ChildCategoryNodes[i].CategoryId != null ? "disabled" : "")>
@if (!Model.CategoryViewModel.ChildCategoryNodes[i].AlreadyTaken)
{
@Html.CheckBoxFor(model => model.CategoryViewModel.ChildCategoryNodes[i].Selected, new Dictionary<string, object> {{"data-id", Model.CategoryViewModel.ChildCategoryNodes[i].Id}, {"data-description", Model.CategoryViewModel.ChildCategoryNodes[i].Description}})
}
else
{
@Html.CheckBoxFor(model => model.CategoryViewModel.ChildCategoryNodes[i].Selected, new Dictionary<string, object>{{"data-id", Model.CategoryViewModel.ChildCategoryNodes[i].Id}, {"data-description", Model.CategoryViewModel.ChildCategoryNodes[i].Description}, {"disabled","disabled"}})
}
@Model.CategoryViewModel.ChildCategoryNodes[i].Id - @Model.CategoryViewModel.ChildCategoryNodes[i].Description
</label>
}
}
</fieldset>
}
任何人都知道如何减少被回收的垃圾量,或者如何避免这种超慢速偏移回流?
编辑:像往常一样,我受到那些认为他们知道这里发生了什么的人的骚扰,但他们显然没有,所以这里有一些示例代码在不到一秒的时间内运行,每次运行在我的dom上字符被输入到文本框中。
$("#filter").on("keyup", function() {
ValidateTextBoxes();
});
function ValidateTextBoxes() {
$("input[type=checkbox]").each(function() {
var val = $("#filter").val();
var id = $(this).data("id");
var description = $(this).data("description");
if (val != null && id != null && description != null) {
if (id.toString().indexOf(val.toString()) > -1 || description.toString().toLowerCase().indexOf(val.toString().toLowerCase()) > -1){
$(this).parent().show();
} else {
$(this).parent().hide();
}
}
});
}
所以,感谢,不再有关于元素数量的评论。
答案 0 :(得分:3)
即使OP不想听到这个问题,我也会冒险尝试为这个问题提供有用的答案。我回复了the last question you posted regarding these same 2k checkboxes,我仍然坚信你正试图解决错误的问题。也许这就是为什么这么多人给你的答案,你似乎不想听到。
在您的上一个问题中,您表示漫长的等待时间使您调试和开发非常令人沮丧。我建议你重新考虑一下你的用户界面,我接受了#34的效果声明;如果我想帮助写一个更好的用户界面,我会要求它#34;。您还表示您计划重写UI,但与此同时,这些浏览器性能问题使您无法完成中间工作。
您可以做的一件事是临时更改您的测试数据或控制器操作,以便它只返回20个复选框而不是2000.这样的事情可以帮助您更快地工作,直到您可以重新设计用户体验。如果您计划在生产中为用户呈现2000个复选框,那么期望他们的用户体验很差。
我不知道关于jqueryval的问题的答案,所以请随意关注这个答案。但是我确实知道浏览器javascript引擎(尤其是IE)会在尝试扫描并使用它们时阻塞非常大的DOM。技术只会带你到目前为止,你必须愿意妥协并在中间的某个地方遇见浏览器。
如果您还没有完成,我建议的另一件事是阅读jqueryval源代码。
<强>更新强>
this.settings.ignore
的默认值似乎是':hidden'
,如下所示:
$.extend($.validator, {
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
validClass: "valid",
errorElement: "label",
focusInvalid: true,
errorContainer: $([]),
errorLabelContainer: $([]),
onsubmit: true,
ignore: ":hidden", // HERE
ignoreTitle: false,
onfocusin: function( element, event ) {
而不是分支jqueryval,看看这样做是否会提高性能:
$.validator.setDefaults({ ignore: '' });
参考文献是:
asp.net mvc: why is Html.CheckBox generating an additional hidden input
jQuery Validate - Enable validation for hidden fields
如果忽略设置确实是性能凶手,那么我希望将它设置为空字符串应该使过滤选择器短路并让你回到&#34;正常&#34; 2k +复选框的性能(加上2k +隐藏输入,总共需要4k +元素来渲染所有类别)。
答案 1 :(得分:0)
好吧,所以...
问题是jqueryval,我们的答案是在提交按钮上添加cancel类以专门阻止此页面上的jqueryval,然后使用ValidatorContext在进入控制器时验证模型。
我们为无法回发的属性(例如,下拉列表的内容)重新水化,并将其发回给用户,由普通的mvc validationsummary处理。
[HttpPost]
public ActionResult Create(EditFirstChildCategoryViewModel editFirstChildCategoryViewModel)
{
if (!ModelState.IsValid)
{
var categories = _categoryDataService.GetRootCategoryModels();
editFirstChildCategoryViewModel.ExistingCategoryDropDown =
_selectListFactory.CreateSelectList(categories, RootCategoryValueExpression,
RootCategoryTextExpression);
return View(editFirstChildCategoryViewModel);
}
//etc...
}
用户可以解决任何问题,我们会让我们糟糕的可怕的2000复选框设计表现出来。