Adds minor speeed optimizations to property & selector optimizers.
authorGoalSmashers <jakub@goalsmashers.com>
Sun, 17 Nov 2013 12:05:00 +0000 (13:05 +0100)
committerGoalSmashers <jakub@goalsmashers.com>
Sun, 17 Nov 2013 22:06:02 +0000 (23:06 +0100)
lib/properties/optimizer.js
lib/selectors/optimizer.js

index 6106f37..527acc7 100644 (file)
@@ -113,6 +113,9 @@ module.exports = function Optimizer() {
     var tokens = body.split(';');
     var keyValues = [];
 
+    if (tokens.length < 2)
+      return;
+
     for (var i = 0, l = tokens.length; i < l; i++) {
       var token = tokens[i];
       if (token === '')
@@ -218,7 +221,7 @@ module.exports = function Optimizer() {
   return {
     process: function(body, allowAdjacent) {
       var tokens = tokenize(body);
-      if (tokens.length < 2)
+      if (!tokens)
         return body;
 
       var optimized = optimize(tokens, allowAdjacent);
index b10ae78..307057a 100644 (file)
@@ -32,17 +32,16 @@ module.exports = function Optimizer(data, options) {
     var forRemoval = [];
 
     for (var i = 0, l = tokens.length; i < l; i++) {
-      if (typeof tokens[i] == 'string' || tokens[i].block)
+      var token = tokens[i];
+      if (typeof token == 'string' || token.block)
         continue;
 
-      var selector = tokens[i].selector;
-      var body = tokens[i].body;
-      var id = body + '@' + selector;
+      var id = token.body + '@' + token.selector;
       var alreadyMatched = matched[id];
 
       if (alreadyMatched) {
-        forRemoval.push(alreadyMatched[alreadyMatched.length - 1]);
-        alreadyMatched.push(i);
+        forRemoval.push(alreadyMatched[0]);
+        alreadyMatched.unshift(i);
       } else {
         matched[id] = [i];
       }
@@ -51,6 +50,7 @@ module.exports = function Optimizer(data, options) {
     forRemoval = forRemoval.sort(function(a, b) {
       return a > b ? 1 : -1;
     });
+
     for (var j = 0, n = forRemoval.length; j < n; j++) {
       tokens.splice(forRemoval[j] - j, 1);
     }
@@ -88,9 +88,6 @@ module.exports = function Optimizer(data, options) {
     var matchedMoreThanOnce = [];
     var partiallyReduced = [];
     var token, selector, selectors;
-    var removeEmpty = function(value) {
-      return value.length > 0 ? value : '';
-    };
 
     for (var i = 0, l = tokens.length; i < l; i++) {
       token = tokens[i];
@@ -99,9 +96,9 @@ module.exports = function Optimizer(data, options) {
       if (typeof token == 'string' || token.block)
         continue;
 
-      selectors = selector.split(',');
-      if (selectors.length > 1)
-        selectors.unshift(selector);
+      selectors = selector.indexOf(',') > 0 ?
+        [selector].concat(selector.split(',')) :
+        [selector];
 
       for (var j = 0, m = selectors.length; j < m; j++) {
         var sel = selectors[j];
@@ -120,7 +117,9 @@ module.exports = function Optimizer(data, options) {
       var matchPositions = matched[selector];
       var bodies = [];
       var joinsAt = [];
-      for (var j = 0, m = matchPositions.length; j < m; j++) {
+      var j;
+
+      for (j = 0, m = matchPositions.length; j < m; j++) {
         var body = tokens[matchPositions[j]].body;
         bodies.push(body);
         joinsAt.push((joinsAt[j - 1] || 0) + body.split(';').length);
@@ -129,27 +128,29 @@ module.exports = function Optimizer(data, options) {
       var optimizedBody = propertyOptimizer.process(bodies.join(';'), joinsAt);
       var optimizedTokens = optimizedBody.split(';');
 
-      var k = optimizedTokens.length - 1;
+      j = optimizedTokens.length - 1;
       var currentMatch = matchPositions.length - 1;
 
       while (currentMatch >= 0) {
-        if (bodies[currentMatch].indexOf(optimizedTokens[k]) > -1 && k > -1) {
-          k -= 1;
+        if (bodies[currentMatch].indexOf(optimizedTokens[j]) > -1 && j > -1) {
+          j -= 1;
           continue;
         }
 
         var tokenIndex = matchPositions[currentMatch];
         var token = tokens[tokenIndex];
-        var reducedBody = optimizedTokens
-          .splice(k + 1)
-          .filter(removeEmpty)
-          .join(';');
+        var newBody = optimizedTokens.splice(j + 1);
+        var reducedBody = [];
+        for (var k = 0, n = newBody.length; k < n; k++) {
+          if (newBody[k].length > 0)
+            reducedBody.push(newBody[k]);
+        }
 
         if (token.selector == selector) {
-          token.body = reducedBody;
+          token.body = reducedBody.join(';');
         } else {
           token._partials = token._partials || [];
-          token._partials.push(reducedBody);
+          token._partials.push(reducedBody.join(';'));
 
           if (partiallyReduced.indexOf(tokenIndex) == -1)
             partiallyReduced.push(tokenIndex);
@@ -164,9 +165,8 @@ module.exports = function Optimizer(data, options) {
     // if all selectors were reduced to same value we can override it
     for (i = 0, l = partiallyReduced.length; i < l; i++) {
       token = tokens[partiallyReduced[i]];
-      selectors = token.selector.split(',');
 
-      if (token._partials.length == selectors.length && token.body != token._partials[0]) {
+      if (token.body != token._partials[0] && token._partials.length == token.selector.split(',').length) {
         var newBody = token._partials[0];
         for (var k = 1, n = token._partials.length; k < n; k++) {
           if (token._partials[k] != newBody)