[extensions-web] diff.js: optimized for performance.
- From: Yuri Konotopov <ykonotopov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [extensions-web] diff.js: optimized for performance.
- Date: Fri, 25 Aug 2017 21:48:15 +0000 (UTC)
commit c05512af2053a79541a759afa68830be0f3a1e38
Author: Yuri Konotopov <ykonotopov gnome org>
Date: Sat Aug 26 01:43:41 2017 +0400
diff.js: optimized for performance.
Rewritten most slowest things:
1. Removed flatten() array -> jQuery object conversion function.
It's completely useless for now. Maybe it was usefull some time ago...
2. Expanded all $.each() calls to native "for" loops.
3. Changed all jQuery objects to native js arrays.
4. Collapsed multiple $.click() events in equals chunks to single
$.on('click') event.
5. Changed dynamic ($.append() + $.text()) DOM construction in
buildEqualChunk() to static Mustache template, so we can win about 200 ms.
Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=786610
sweettooth/static/js/diff.js | 109 +++++++++-----------
.../js/templates/diff/equals_chunk_row.mustache | 5 +
sweettooth/static/js/templates/templatedata.js | 1 +
3 files changed, 53 insertions(+), 62 deletions(-)
---
diff --git a/sweettooth/static/js/diff.js b/sweettooth/static/js/diff.js
index e4c7ca9..913b25b 100644
--- a/sweettooth/static/js/diff.js
+++ b/sweettooth/static/js/diff.js
@@ -9,7 +9,7 @@
(at your option) any later version.
*/
-define(['jquery'], function ($) {
+define(['jquery', 'templates'], function ($, templates) {
"use strict";
var exports = {};
@@ -20,71 +20,41 @@ define(['jquery'], function ($) {
//
// Each "buildChunk" function below should build full row(s).
- // For some reason it's hard to turn an array of jQuery objects into
- // one jQuery object.
- function flatten(list) {
- var $elems = $();
- $.each(list, function () {
- $elems = $elems.add(this);
- });
- return $elems;
- }
-
function buildEqualChunk(chunk, oldContents, newContents) {
- function triggerCollapse() {
- // show() and hide() don't work on table-rows - jQuery
- // will set the row back to 'display: block'. Unsure if it's
- // a jQuery or browser bug.
- if (collapsed)
- {
- $triggerRow.removeClass('collapsed');
- $collapsable.css('display', 'table-row');
- $triggers.text('-');
- }
- else
- {
- $triggerRow.addClass('collapsed');
- $collapsable.css('display', 'none');
- $triggers.text('+');
- }
+ let $elems = [];
- collapsed = !collapsed;
- }
-
- var $triggerRow;
- var $triggers = $();
- var $collapsable = $();
- var collapsed = false;
+ for (let i in chunk.lines)
+ {
+ let line = chunk.lines[i];
- var $elems = $.map(chunk.lines, function (line, i) {
var contents = oldContents[line.oldindex];
- var $row = $('<tr>', {'class': 'diff-line equal'}).append($('<td>', {'class': 'old
linum'}).text(line.oldlinenum)).append($('<td>', {'class': 'new
linum'}).text(line.newlinenum)).append($('<td>', {'class': 'new contents'}).text(contents));
+ var $row = $(templates.get('diff/equals_chunk_row')({
+ oldlinenum: line.oldlinenum,
+ newlinenum: line.newlinenum,
+ contents: contents
+ }));
+
+ if (i == 0)
+ {
+ $row.addClass('equals-chunk-first-row')
+ }
if (chunk.collapsable)
{
if (i == 0)
{
- $triggerRow = $row;
-
$row.addClass('collapsable-trigger-row').find('.contents').each(function () {
- var $trigger = $('<a>', {'class':
'collapsable-trigger'}).click(triggerCollapse);
- $triggers = $triggers.add($trigger);
- $(this).append($trigger);
- });
+ $row.find('.contents').append(
+ $('<a>', {'class': 'collapsable-trigger'}).text('+')
+ );
}
else
{
- $row.addClass('collapsable-collapsed-row');
- $collapsable = $collapsable.add($row);
+ $row.addClass('collapsable-collapsed-row').hide();
}
}
- return $row;
- });
-
- if (chunk.collapsable)
- {
- triggerCollapse($collapsable);
+ $elems.push($row);
}
return $elems;
@@ -127,8 +97,9 @@ define(['jquery'], function ($) {
var regionElems = [];
var lastEnd = 0;
- $.each(regions, function () {
- var start = this[0], end = this[1];
+ for (let region of regions)
+ {
+ let start = region[0], end = region[1];
// The indexes in the 'regions' are the changed regions. We
// can expect that the regions in between the indexes are
@@ -138,7 +109,7 @@ define(['jquery'], function ($) {
regionElems.push(changed(contents.slice(start, end)));
lastEnd = end;
- });
+ }
// We may have an unchanged region left over at the end of a row.
if (contents.slice(lastEnd))
@@ -150,7 +121,7 @@ define(['jquery'], function ($) {
}
function buildInsertLine(line, contents) {
- return $('<tr>', {'class': 'diff-line inserted'}).append($('<td>', {'class':
'linum'})).append($('<td>', {'class': 'new linum'}).text(line.newlinenum)).append($('<td>', {'class': 'new
contents'}).append(flatten(buildReplaceRegions(line.newregion, contents[line.newindex]))));
+ return $('<tr>', {'class': 'diff-line inserted'}).append($('<td>', {'class':
'linum'})).append($('<td>', {'class': 'new linum'}).text(line.newlinenum)).append($('<td>', {'class': 'new
contents'}).append(buildReplaceRegions(line.newregion, contents[line.newindex])));
}
function buildInsertChunk(chunk, oldContents, newContents) {
@@ -160,7 +131,7 @@ define(['jquery'], function ($) {
}
function buildDeleteLine(line, contents) {
- return $('<tr>', {'class': 'diff-line deleted'}).append($('<td>', {'class': 'old
linum'}).text(line.oldlinenum)).append($('<td>', {'class': 'linum'})).append($('<td>', {'class': 'old
contents'}).append(flatten(buildReplaceRegions(line.oldregion, contents[line.oldindex]))));
+ return $('<tr>', {'class': 'diff-line deleted'}).append($('<td>', {'class': 'old
linum'}).text(line.oldlinenum)).append($('<td>', {'class': 'linum'})).append($('<td>', {'class': 'old
contents'}).append(buildReplaceRegions(line.oldregion, contents[line.oldindex])));
}
function buildDeleteChunk(chunk, oldContents, newContents) {
@@ -176,14 +147,13 @@ define(['jquery'], function ($) {
var deleteChunk = [], insertChunk = [];
- $.each(chunk.lines, function () {
- var line = this;
-
+ for (let line of chunk.lines)
+ {
deleteChunk.push(buildDeleteLine(line, oldContents));
insertChunk.push(buildInsertLine(line, newContents));
- });
+ }
- return [flatten(deleteChunk), flatten(insertChunk)];
+ return deleteChunk.concat(insertChunk);
}
var operations = {
@@ -196,8 +166,23 @@ define(['jquery'], function ($) {
exports.buildDiffTable = function (chunks, oldContents, newContents) {
var $table = $('<table>', {'class': 'code'});
- $.each(chunks, function () {
- $table.append(flatten(operations[this.change](this, oldContents, newContents)));
+ for (let chunk of chunks)
+ {
+ $table.append(operations[chunk.change](chunk, oldContents, newContents));
+ }
+
+ $table.on('click', 'a.collapsable-trigger', function (event) {
+ let triggerRow = $(this).closest('tr.equals-chunk-first-row');
+ triggerRow.toggleClass('collapsed');
+ triggerRow.nextUntil('tr.equals-chunk-first-row').toggle();
+ if ($(this).text() == '-')
+ {
+ $(this).text('+');
+ }
+ else
+ {
+ $(this).text('-');
+ }
});
return $table;
diff --git a/sweettooth/static/js/templates/diff/equals_chunk_row.mustache
b/sweettooth/static/js/templates/diff/equals_chunk_row.mustache
new file mode 100644
index 0000000..5f710b7
--- /dev/null
+++ b/sweettooth/static/js/templates/diff/equals_chunk_row.mustache
@@ -0,0 +1,5 @@
+<tr class="diff-line equal">
+ <td class="old linum">{{oldlinenum}}</td>
+ <td class="new linum">{{newlinenum}}</td>
+ <td class="new contents">{{contents}}</td>
+</tr>
diff --git a/sweettooth/static/js/templates/templatedata.js b/sweettooth/static/js/templates/templatedata.js
index fbdb079..9420127 100644
--- a/sweettooth/static/js/templates/templatedata.js
+++ b/sweettooth/static/js/templates/templatedata.js
@@ -2,6 +2,7 @@
"use strict";
define({
+ "diff/equals_chunk_row": "<tr class=\"diff-line equal\">\n <td class=\"old
linum\">{{oldlinenum}}</td>\n <td class=\"new linum\">{{newlinenum}}</td>\n <td class=\"new
contents\">{{contents}}</td>\n</tr>",
"extensions/comment": "<div class=\"comment\">\n {{#is_extension_creator}}\n <div
class=\"extension-creator-badge\">Author</div>\n {{/is_extension_creator}}\n <img src=\"{{gravatar}}\"
class=\"gravatar\">\n <div class=\"rating-author\">\n {{#rating}}\n <div class=\"rating\"
data-rating-value=\"{{rating}}\"></div> by\n {{/rating}}\n <a class=\"comment-author\"
href=\"{{author.url}}\">{{author.username}}</a>\n <p>{{comment}}</p>\n <time
datetime=\"{{date.timestamp}}Z\">{{date.standard}}</time>\n </div>\n</div>",
"extensions/comments_list": "{{#comments}}\n {{>extensions/comment}}\n
<hr>\n{{/comments}}\n{{^show_all}}\n<p class=\"show-all\">Show more
reviews</p>\n{{/show_all}}\n\n{{^comments}}\n <p>There are no comments. Be the first!</p>\n{{/comments}}",
"extensions/error_report_template": "What's wrong?\n\n\n\nWhat have you tried?\n\n\n\nAutomatically
detected errors:\n\n{{#errors}}\n {{.}}\n\n================\n{{/errors}}\n{{^errors}}\nGNOME Shell
Extensions did not detect any errors with this extension.\n{{/errors}}\n\nVersion information:\n\n Shell
version: {{sv}}\n Extension version: {{#ev}}{{ev}}{{/ev}}{{^ev}}Unknown{{/ev}}",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]