我有一个很大的javascript / ajax代码,我想看看是否有可能让它更有效率地运行而不需要取出任何功能。
我的问题是我得到一个名为'getlastupdate.php'的页面,它只有14个数字,这些数字是数据库表最后更新的日期和时间。
格式为:
以下是一个示例:20130724082105
我拿出':.-'因为我们不需要它。
我的javascript代码将此与另一个从'getlastupdate.php'重复获取当前日期/时间的ajax GET进行比较。如果它发现两个值不相同,则会触发另一个GET来获取行信息。
它会获取更新的行信息并在浏览器中显示。最后,它获取整个更新的表并将其放回表中(tablesorter)。
一切似乎工作正常但是当脚本添加新表信息并删除旧信息时我注意到了一些LAG?或者至少我认为这是LAG的主要原因。
以下是代码:
<link type="text/css" rel="stylesheet" href="tablesorter/qtip/jquery.qtip.min.css" />
<script type="text/javascript" src="tablesorter/jquery-1.10.2.min.js"></script>
<!-- blue theme stylesheet -->
<link rel="stylesheet" href="tablesorter/final/theme.blue.css">
<!-- tablesorter plugin -->
<script src="tablesorter/final/jquery.tablesorter.js"></script>
<!-- tablesorter widget file - loaded after the plugin -->
<script src="tablesorter/final/jquery.tablesorter.widgets.js"></script>
<!-- START: toastmessage Notify -->
<link type="text/css" href="tablesorter/final/toastmessage/jquery.toastmessage-min.css" rel="stylesheet"/>
<script type="text/javascript" src="tablesorter/final/toastmessage/jquery.toastmessage-min.js"></script>
<!-- END: toastmessage Notify -->
<script type="text/javascript" src="tablesorter/qtip/jquery.qtip.min.js"></script>
<script type="text/javascript">
var comper;
function checkComper() {
var SvInfo;
var onResponse = function(comperNow) { // comperNow is the latest date/time var
//check if comper has been set / first time method is called
if (comper === undefined) {
comper = comperNow;
return;
}
if (comper !== comperNow) {
var Vinfoo;
$.get("getlastupdate2.php", function(primaryAddType){
// alert("Data: " + primaryAddType);
Vinfoo = primaryAddType;
// show a message to the visitor ---->
//alert(Vinfoo);
$().toastmessage('showNoticeToast', Vinfoo);
});
$('#append').trigger('click'); // UPDATE THE TABLE BUT IT TAKES 3-4 SEC. AND I NEED IT TO SPEED UP!
// and update comper to show the date/time from comperNow
comper = comperNow;
}
};
$.get('getlastupdate.php', onResponse);
}
var tid = setInterval(checkComper, 2000); // repeat myself
$(function() {
$('[title!=""]').qtip({}); // A bit better. Grab elements with a title attribute that isn't blank. <-- CUSTOM TOOLTIP
var $table = $("table.tablesorter");
$("#append").click(function(e) {
e.preventDefault();
$.get('updatetable.php', function(data)
{
$table
.find('tbody')
.html('')
.append(data);
$table.trigger("update", [true]);
$('[title!=""]').qtip({}); // A bit better. Grab elements with a title attribute that isn't blank. <-- CUSTOM TOOLTIP
});
});
// call the tablesorter plugin
$("table.tablesorter").tablesorter({
theme: 'blue',
// hidden filter input/selects will resize the columns, so try to minimize the change
widthFixed : true,
//sortList: [[2,0],[1,0]],
// initialize zebra striping and filter widgets
widgets: ["saveSort", "zebra", "filter"],
// headers: { },
widgetOptions : {
// If there are child rows in the table (rows with class name from "cssChildRow" option)
// and this option is true and a match is found anywhere in the child row, then it will make that row
// visible; default is false
filter_childRows : false,
// if true, a filter will be added to the top of each table column;
// disabled by using -> headers: { 1: { filter: false } } OR add class="filter-false"
// if you set this to false, make sure you perform a search using the second method below
filter_columnFilters : true,
// css class applied to the table row containing the filters & the inputs within that row
filter_cssFilter : 'tablesorter-filter',
// class added to filtered rows (rows that are not showing); needed by pager plugin
filter_filteredRow : 'filtered',
// add custom filter elements to the filter row
// see the filter formatter demos for more specifics
filter_formatter : null,
// add custom filter functions using this option
// see the filter widget custom demo for more specifics on how to use this option
filter_functions : null,
// if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately
// below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus
filter_hideFilters : false, // true, (see note in the options section above)
// Set this option to false to make the searches case sensitive
filter_ignoreCase : true,
// if true, search column content while the user types (with a delay)
filter_liveSearch : true,
// jQuery selector string of an element used to reset the filters
filter_reset : 'button.reset',
// Delay in milliseconds before the filter widget starts searching; This option prevents searching for
// every character while typing and should make searching large tables faster.
filter_searchDelay : 300,
// if true, server-side filtering should be performed because client-side filtering will be disabled, but
// the ui and events will still be used.
filter_serversideFiltering: false,
// Set this option to true to use the filter to find text from the start of the column
// So typing in "a" will find "albert" but not "frank", both have a's; default is false
filter_startsWith : false,
// Filter using parsed content for ALL columns
// be careful on using this on date columns as the date is parsed and stored as time in seconds
filter_useParsedData : false
}
});
// External search
// buttons set up like this:
// <button type="button" class="search" data-filter-column="4" data-filter-text="2?%">Saved Search</button>
$('button.search').click(function(){
/*** first method *** data-filter-column="1" data-filter-text="!son"
add search value to Discount column (zero based index) input */
var filters = [],
col = $(this).data('filter-column'), // zero-based index
txt = $(this).data('filter-text'); // text to add to filter
filters[col] = txt;
// using "table.hasFilters" here to make sure we aren't targetting a sticky header
$.tablesorter.setFilters( $('table.hasFilters'), filters, true ); // new v2.9
/** old method (prior to tablsorter v2.9 ***
var filters = $('table.tablesorter').find('input.tablesorter-filter');
filters.val(''); // clear all filters
filters.eq(col).val(txt).trigger('search', false);
******/
/*** second method ***
this method bypasses the filter inputs, so the "filter_columnFilters"
option can be set to false (no column filters showing)
******/
/*
var columns = [];
columns[5] = '2?%'; // or define the array this way [ '', '', '', '', '', '2?%' ]
$('table').trigger('search', [ columns ]);
*/
return false;
});
});
</script>
如果我注释掉这一行,我找到了LAG的来源:
$('#append').trigger('click'); // UPDATE THE TABLE BUT IT TAKES 3-4 SEC. AND I NEED IT TO SPEED UP! it will speed everything up but how do I get it to speed up or even slow down so that it doesn't lock up the current page.
如果我发表评论,还可以加快加载速度:
var $table = $("table.tablesorter");
$("#append").click(function(e) {
e.preventDefault();
$.get('updatetable.php', function(data)
{
$table
.find('tbody')
.html('')
.append(data);
$table.trigger("update", [true]);
// ******** +++++++++++ **************
$('[title!=""]').qtip({}); // <-- CUSTOM TOOLTIP THIS SLOWS DOWN THE LOADING ALSO!!!!!
// ******** +++++++++++ **************
});
});
@Abudoul Sy, 这就是我现在所拥有的:
<script type="text/javascript">
// I should be put at the top of the file (not in an Ajax Loop)
var compileHTML = function (html) {
var div = document.createElement("div");
div.innerHTML = html;
var fragment = document.createDocumentFragment();
while ( div.firstChild ) {
fragment.appendChild( div.firstChild );
}
return fragment
};
var comper;
function checkComper() {
var SvInfo;
var onResponse = function(comperNow) { // comperNow is the latest date/time var
//check if comper has been set / first time method is called
if (comper === undefined) {
comper = comperNow;
return;
}
if (comper !== comperNow) {
var Vinfoo;
$.get("getlastupdate2.php", function(primaryAddType){
// alert("Data: " + primaryAddType);
Vinfoo = primaryAddType;
// show a message to the visitor ---->
//alert(Vinfoo);
$().toastmessage('showNoticeToast', Vinfoo);
});
$('#append').trigger('click'); // UPDATE THE TABLE BUT IT TAKES 3-4 SEC. AND I NEED IT TO SPEED UP!
// and update comper to show the date/time from comperNow
comper = comperNow;
}
};
$.get('getlastupdate.php', onResponse);
}
var tid = setInterval(checkComper, 2000); // repeat myself
$(function() {
$(document).ready(function()
{
$('[title!=""]').qtip({}); // A bit better. Grab elements with a title attribute that isn't blank. <-- CUSTOM TOOLTIP
})
var $table = $("table.tablesorter");
//Keeping a reference variable to
var $tableContents = $table.find('tbody');
$("#append").click(function(e) {
e.preventDefault();
$.get('updatetable.php', function(data)
{
$table
//When ajax is done
var compiledHtml = window.compileHTML(data);
$tableContents.html(compiledHTML);
$table.trigger("update", [true]);
$(document).ready(function()
{
$('[title!=""]').qtip({}); // A bit better. Grab elements with a title attribute that isn't blank. <-- CUSTOM TOOLTIP
})
});
});
// call the tablesorter plugin
$("table.tablesorter").tablesorter({
theme: 'blue',
// hidden filter input/selects will resize the columns, so try to minimize the change
widthFixed : true,
//sortList: [[2,0],[1,0]],
// initialize zebra striping and filter widgets
widgets: ["saveSort", "zebra", "filter"],
headers: { 8: { sorter: false, filter: false } },
widgetOptions : {
// If there are child rows in the table (rows with class name from "cssChildRow" option)
// and this option is true and a match is found anywhere in the child row, then it will make that row
// visible; default is false
filter_childRows : false,
// if true, a filter will be added to the top of each table column;
// disabled by using -> headers: { 1: { filter: false } } OR add class="filter-false"
// if you set this to false, make sure you perform a search using the second method below
filter_columnFilters : true,
// css class applied to the table row containing the filters & the inputs within that row
filter_cssFilter : 'tablesorter-filter',
// class added to filtered rows (rows that are not showing); needed by pager plugin
filter_filteredRow : 'filtered',
// add custom filter elements to the filter row
// see the filter formatter demos for more specifics
filter_formatter : null,
// add custom filter functions using this option
// see the filter widget custom demo for more specifics on how to use this option
filter_functions : null,
// if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately
// below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus
filter_hideFilters : false, // true, (see note in the options section above)
// Set this option to false to make the searches case sensitive
filter_ignoreCase : true,
// if true, search column content while the user types (with a delay)
filter_liveSearch : true,
// jQuery selector string of an element used to reset the filters
filter_reset : 'button.reset',
// Delay in milliseconds before the filter widget starts searching; This option prevents searching for
// every character while typing and should make searching large tables faster.
filter_searchDelay : 300,
// if true, server-side filtering should be performed because client-side filtering will be disabled, but
// the ui and events will still be used.
filter_serversideFiltering: false,
// Set this option to true to use the filter to find text from the start of the column
// So typing in "a" will find "albert" but not "frank", both have a's; default is false
filter_startsWith : false,
// Filter using parsed content for ALL columns
// be careful on using this on date columns as the date is parsed and stored as time in seconds
filter_useParsedData : false
}
});
// External search
// buttons set up like this:
// <button type="button" class="search" data-filter-column="4" data-filter-text="2?%">Saved Search</button>
$('button.search').click(function(){
/*** first method *** data-filter-column="1" data-filter-text="!son"
add search value to Discount column (zero based index) input */
var filters = [],
col = $(this).data('filter-column'), // zero-based index
txt = $(this).data('filter-text'); // text to add to filter
filters[col] = txt;
// using "table.hasFilters" here to make sure we aren't targetting a sticky header
$.tablesorter.setFilters( $('table.hasFilters'), filters, true ); // new v2.9
/** old method (prior to tablsorter v2.9 ***
var filters = $('table.tablesorter').find('input.tablesorter-filter');
filters.val(''); // clear all filters
filters.eq(col).val(txt).trigger('search', false);
******/
/*** second method ***
this method bypasses the filter inputs, so the "filter_columnFilters"
option can be set to false (no column filters showing)
******/
/*
var columns = [];
columns[5] = '2?%'; // or define the array this way [ '', '', '', '', '', '2?%' ]
$('table').trigger('search', [ columns ]);
*/
return false;
});
});
</script>
答案 0 :(得分:4)
查看您的代码:
每次你正在做一个Ajax请求时,你都是这样做的:
$table
.find('tbody')
.html('')
.append(data);
$table.trigger("update", [true]);
解释它的作用:
$.find
(慢)我认为只需更好地处理您的数据,就可以根据表格的大小无数次加快您的流程。 考虑一下:
// I should be put at the top of the file (not in an Ajax Loop)
window.compileHTML = function (html) {
var div = document.createElement("div");
div.innerHTML = html;
var fragment = document.createDocumentFragment();
while ( div.firstChild ) {
fragment.appendChild( div.firstChild );
}
return fragment
};
//Keeping a reference variable to
var $tableContents = $table.find('tbody')
//When ajax is done
var compiledHtml = window.compileHTML(data);
$tableContents.html(compiledHtml);
$table.trigger("update", [true]);
编辑:如果compileHTML
不起作用。
做几乎相同的事情(但没有编译)的好方法是:
//put just after $table declaration
var $tableContents = $table.find('tbody')
//When ajax is done
var $html = $('<tbody/>').html(data);
$tableContents.replaceWith($html)
$table.trigger("update", [true]);
编辑:
我所做的是创建一个文档片段(在DOM之外),让通过compileHTML
进行的html处理在当前页面上没有任何影响。一切都完成了。
仅添加创建到DOM的新dom树的根,仅导致一次重绘:“尽可能多的单元格和行”将使浏览器看起来更稳定。
可选(不完全):
您的代码可能存在更多陷阱,但调查性能很难。
我建议对Chrome/Firebug - &gt;进行时间表检查。打开控制台( F12 或 Alt + shift + i )按“时间轴”选项卡。
按( ctrl / cmd )+ E 并让更新传递,压制 ctrl + E < / kbd>你会看到一些直方图,较大的条形意味着你的应用程序是滞后/ janky,然后你可以点击条形图来查看所有被调用函数的堆栈跟踪,从而进行优化。
希望有所帮助:)
答案 1 :(得分:2)
如果您想要“加载...请稍候”对话,只需添加以下内容:
<div id="loading_overlay" style="z-index:10000;background-color:#000;opacity:0.5;display:none;cursor:wait;">
<div style="z-index:10001;background-color:#FFF;opacity:1;cursor:auto;position:absolute;top:50%;left:50%;height:300px;width:300px;margin-top:-150px;margin-left:-150px;">Please wait, loading...</div>
</div>
(显然,不要在实际文档中使用内联样式,将它们放在外部CSS文件中)
然后在$.get('updatetable.php', function(data)
行之前添加$("#loading_overlay").show();
,然后在$("#loading_overlay").hide();
之后$table.trigger("update", [true]);
(我假设这是您的AJAX请求的最后一行)。
基本上,您在AJAX请求之前显示加载对话框,然后在完成后隐藏它。
这个没有解决滞后问题,但它确实显示了加载对话框,因此用户知道浏览器锁定的原因(正如您所问)。
答案 2 :(得分:1)
我唯一的结论就是让输出尺寸更小,然后是400-500kb。