Optimisations for the file list and filtering (added a debounce function, streamlined some jquery, updates to jsx to facilitate).

This commit is contained in:
Andrew Collington 2016-02-23 15:46:34 +00:00
parent 853aa7e446
commit 367388fbe3
3 changed files with 56 additions and 31 deletions

View file

@ -6,6 +6,8 @@ A clean and responsive interface for Zend OPcache information, showing statistic
## What's new
Version 2.2.2 brings in optimisations for the file listing when filtering
Version 2.2.1 has the gauges now updating with the real-time pulse and a couple rounding issues fixed
Version 2.2.0 provides the ability to turn on/off the file list (default is on)

View file

@ -6,7 +6,7 @@
* A simple but effective single-file GUI for the OPcache PHP extension.
*
* @author Andrew Collington, andy@amnuts.com
* @version 2.2.1
* @version 2.2.2
* @link https://github.com/amnuts/opcache-gui
* @license MIT, http://acollington.mit-license.org/
*/
@ -248,6 +248,8 @@ $opcache = OpCacheService::init($options);
table td { padding: 4px 6px; line-height: 1.4em; vertical-align: top; border-color: #fff; }
table tr:nth-child(odd) { background-color: #EFFEFF; }
table tr:nth-child(even) { background-color: #E0ECEF; }
#filelist table tr { background-color: #EFFEFF; }
#filelist table tr.alternate { background-color: #E0ECEF; }
td.pathname { width: 70%; }
footer { border-top: 1px solid #ccc; padding: 1em 2em; }
footer a { padding: 2em; text-decoration: none; opacity: 0.7; }
@ -371,6 +373,36 @@ $opcache = OpCacheService::init($options);
var canInvalidate = <?php echo json_encode($opcache->canInvalidate()); ?>;
var useCharts = <?php echo json_encode($opcache->getOption('charts')); ?>;
var allowFiles = <?php echo json_encode($opcache->getOption('allow_filelist')); ?>;
var debounce = function(func, wait, immediate) {
var timeout;
wait = wait || 250;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
};
function keyUp(event){
var compare = $('#frmFilter').val().toLowerCase();
$('#filelist').find('table tbody tr').each(function(index){
if ($(this).data('path').indexOf(compare) == -1) {
$(this).addClass('hide');
} else {
$(this).removeClass('hide');
}
});
$('#filelist table tbody').trigger('paint');
};
<?php if ($opcache->getOption('charts')): ?>
var Gauge = function(el, colour) {
@ -449,7 +481,7 @@ $opcache = OpCacheService::init($options);
count_formatted : opstate.overview.readable.num_cached_scripts,
count : opstate.overview.num_cached_scripts
});
$('#frmFilter').trigger('keyup');
keyUp();
}
});
}
@ -472,24 +504,15 @@ $opcache = OpCacheService::init($options);
return false;
});
$(document).on('paint', '#filelist table tbody', function(event, params) {
var trs = $('tr', $(this)).not('.hide');
trs.filter(':odd').css({backgroundColor:'#E0ECEF'})
.end().filter(':even').css({backgroundColor:'#EFFEFF'});
filesObj.setState({showing: trs.length});
});
$('#frmFilter').bind('keyup', function(event){
$('span.pathname').each(function(index){
if ($(this).text().toLowerCase().indexOf($('#frmFilter').val().toLowerCase()) == -1) {
$(this).closest('tr').addClass('hide');
} else {
$(this).closest('tr').removeClass('hide');
}
});
$('#filelist table tbody').trigger('paint');
var trs = $('#filelist').find('tbody tr');
trs.removeClass('alternate');
trs.filter(':not(.hide):odd').addClass('alternate');
filesObj.setState({showing: trs.filter(':not(.hide)').length});
});
$('#frmFilter').bind('keyup', debounce(keyUp));
});
var MemoryUsage = React.createClass({displayName: 'MemoryUsage',
var MemoryUsage = React.createClass({displayName: "MemoryUsage",
getInitialState: function() {
return {
memoryUsageGauge : null
@ -508,13 +531,13 @@ $opcache = OpCacheService::init($options);
},
render: function() {
if (this.props.chart == true) {
return(React.createElement("canvas", {id: "memoryUsageCanvas", width: "250", height: "250", 'data-value': this.props.value}));
return(React.createElement("canvas", {id: "memoryUsageCanvas", width: "250", height: "250", "data-value": this.props.value}));
}
return(React.createElement("p", null, React.createElement("span", {className: "large"}, this.props.value), React.createElement("span", null, "%")));
}
});
var HitRate = React.createClass({displayName: 'HitRate',
var HitRate = React.createClass({displayName: "HitRate",
getInitialState: function() {
return {
hitRateGauge : null
@ -533,13 +556,13 @@ $opcache = OpCacheService::init($options);
},
render: function() {
if (this.props.chart == true) {
return(React.createElement("canvas", {id: "hitRateCanvas", width: "250", height: "250", 'data-value': this.props.value}));
return(React.createElement("canvas", {id: "hitRateCanvas", width: "250", height: "250", "data-value": this.props.value}));
}
return(React.createElement("p", null, React.createElement("span", {className: "large"}, this.props.value), React.createElement("span", null, "%")));
}
});
var OverviewCounts = React.createClass({displayName: 'OverviewCounts',
var OverviewCounts = React.createClass({displayName: "OverviewCounts",
getInitialState: function() {
return {
data : opstate.overview,
@ -574,7 +597,7 @@ $opcache = OpCacheService::init($options);
}
});
var GeneralInfo = React.createClass({displayName: 'GeneralInfo',
var GeneralInfo = React.createClass({displayName: "GeneralInfo",
getInitialState: function() {
return {
version : opstate.version,
@ -601,7 +624,7 @@ $opcache = OpCacheService::init($options);
}
});
var Directives = React.createClass({displayName: 'Directives',
var Directives = React.createClass({displayName: "Directives",
getInitialState: function() {
return { data : opstate.directives };
},
@ -638,7 +661,7 @@ $opcache = OpCacheService::init($options);
}
});
var Files = React.createClass({displayName: 'Files',
var Files = React.createClass({displayName: "Files",
getInitialState: function() {
return {
data : opstate.files,
@ -658,17 +681,17 @@ $opcache = OpCacheService::init($options);
},
render: function() {
if (this.state.allowFiles) {
var fileNodes = this.state.data.map(function(file) {
var fileNodes = this.state.data.map(function(file, i) {
var invalidate, invalidated;
if (file.timestamp == 0) {
invalidated = React.createElement("span", null, React.createElement("i", {className: "invalid metainfo"}, " - has been invalidated"));
}
if (canInvalidate) {
invalidate = React.createElement("span", null, ", ", React.createElement("a", {className: "metainfo", href: '?invalidate='
+ file.full_path, 'data-file': file.full_path, onClick: this.handleInvalidate}, "force file invalidation"));
+ file.full_path, "data-file": file.full_path, onClick: this.handleInvalidate}, "force file invalidation"));
}
return (
React.createElement("tr", {key: file.full_path},
React.createElement("tr", {key: file.full_path, "data-path": file.full_path.toLowerCase(), className: i%2?'alternate':''},
React.createElement("td", null,
React.createElement("div", null,
React.createElement("span", {className: "pathname"}, file.full_path), React.createElement("br", null),
@ -699,7 +722,7 @@ $opcache = OpCacheService::init($options);
}
});
var FilesMeta = React.createClass({displayName: 'FilesMeta',
var FilesMeta = React.createClass({displayName: "FilesMeta",
render: function() {
return (
React.createElement("span", {className: "metainfo"},
@ -711,7 +734,7 @@ $opcache = OpCacheService::init($options);
}
});
var FilesListed = React.createClass({displayName: 'FilesListed',
var FilesListed = React.createClass({displayName: "FilesListed",
getInitialState: function() {
return {
formatted : opstate.overview.readable.num_cached_scripts,

View file

@ -167,7 +167,7 @@ var Files = React.createClass({
},
render: function() {
if (this.state.allowFiles) {
var fileNodes = this.state.data.map(function(file) {
var fileNodes = this.state.data.map(function(file, i) {
var invalidate, invalidated;
if (file.timestamp == 0) {
invalidated = <span><i className="invalid metainfo"> - has been invalidated</i></span>;
@ -177,7 +177,7 @@ var Files = React.createClass({
+ file.full_path} data-file={file.full_path} onClick={this.handleInvalidate}>force file invalidation</a></span>;
}
return (
<tr key={file.full_path}>
<tr key={file.full_path} data-path={file.full_path.toLowerCase()} className={i%2?'alternate':''}>
<td>
<div>
<span className="pathname">{file.full_path}</span><br/>