Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 946d9ae

Browse files
dchermanpetebacondarwin
authored andcommitted
perf($compile): avoid needless overhead when wrapping text nodes
This commit positively affects performance in two main ways: 1, When wrapping text nodes in the compile step, we do not need the overhead of the `forEach` function versus a normal for loop since we do not make use of the closure for anything. 2. When actually wrapping the node, we can completely bypass jqLite which avoids several function calls and the overhead of cloning the wrapper node which we already know to be unique. Tests in applications show about an 83% decrease in time spent in this specific loop.
1 parent a84393e commit 946d9ae

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

src/.jshintrc

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
"jqLiteInheritedData": false,
141141
"jqLiteBuildFragment": false,
142142
"jqLiteParseHTML": false,
143+
"jqLiteWrapNode": false,
143144
"getBooleanAttrName": false,
144145
"getAliasedAttrName": false,
145146
"createEventHandler": false,

src/jqLite.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,16 @@ function jqLiteParseHTML(html, context) {
248248
return [];
249249
}
250250

251+
function jqLiteWrapNode(node, wrapper) {
252+
var parent = node.parentNode;
253+
254+
if (parent) {
255+
parent.replaceChild(wrapper, node);
256+
}
257+
258+
wrapper.appendChild(node);
259+
}
260+
251261

252262
// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259.
253263
var jqLiteContains = Node.prototype.contains || function(arg) {
@@ -939,12 +949,7 @@ forEach({
939949
},
940950

941951
wrap: function(element, wrapNode) {
942-
wrapNode = jqLite(wrapNode).eq(0).clone()[0];
943-
var parent = element.parentNode;
944-
if (parent) {
945-
parent.replaceChild(wrapNode, element);
946-
}
947-
wrapNode.appendChild(element);
952+
jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]);
948953
},
949954

950955
remove: jqLiteRemove,

src/ng/compile.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1299,13 +1299,19 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
12991299
// modify it.
13001300
$compileNodes = jqLite($compileNodes);
13011301
}
1302+
1303+
var NOT_EMPTY = /\S+/;
1304+
13021305
// We can not compile top level text elements since text nodes can be merged and we will
13031306
// not be able to attach scope data to them, so we will wrap them in <span>
1304-
forEach($compileNodes, function(node, index) {
1305-
if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */ ) {
1306-
$compileNodes[index] = jqLite(node).wrap('<span></span>').parent()[0];
1307+
for (var i = 0, len = $compileNodes.length; i < len; i++) {
1308+
var domNode = $compileNodes[i];
1309+
1310+
if (domNode.nodeType === NODE_TYPE_TEXT && domNode.nodeValue.match(NOT_EMPTY) /* non-empty */) {
1311+
jqLiteWrapNode(domNode, $compileNodes[i] = document.createElement('span'));
13071312
}
1308-
});
1313+
}
1314+
13091315
var compositeLinkFn =
13101316
compileNodes($compileNodes, transcludeFn, $compileNodes,
13111317
maxPriority, ignoreDirective, previousCompileContext);

0 commit comments

Comments
 (0)