angular-translate directive compiling buit-in

Benchmark created by PascalPrecht on


Preparation HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
    <script src="https://rawgithub.com/PascalPrecht/angular-translate/canary/src/translate.js"></script>
    <script src="https://rawgithub.com/PascalPrecht/angular-translate/canary/src/service/storage-key.js"></script> 
    <script src="https://rawgithub.com/PascalPrecht/angular-translate/canary/src/service/default-interpolation.js"></script>    
    <script src="https://rawgithub.com/PascalPrecht/angular-translate/canary/src/service/translate.js"></script>    
    <script src="https://rawgithub.com/PascalPrecht/angular-translate/canary/src/filter/translate.js"></script>

<script>
var app = angular.module('plunker', ['pascalprecht.translate']);

//Translations
app.config([
  '$translateProvider',
  function ($translateProvider) {
  
  $translateProvider.translations({
    'FOO': 'hello this is some text'
  });
  
}]);

app.filter('range', function() {
  return function(input, total) {
    total = parseInt(total);
    for (var i=0; i<total; i++)
      input.push(i);
    return input;
  };
});
app.controller('AppController', function ($scope, $translate) {

});
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Without default compiling
<script>
angular.module('pascalprecht.translate').directive('translate', ['$filter', '$q', '$interpolate', '$parse', '$rootScope', function ($filter, $q, $interpolate, $parse, $rootScope) {

  var translate = $filter('translate');

  return {
    restrict: 'AE',
    scope: true,
    compile: function (tElement, tAttr) {

      var translateValuesExist = (tAttr.translateValues && !angular.equals(tAttr.translateValues, ''));
      var translateInterpolation = (tAttr.translateInterpolation) ? tAttr.translateInterpolation : undefined;

      return function linkFn(scope, iElement, iAttr) {

        // Ensures any change of the attribute "translate" containing the id will
        // be re-stored to the scope's "translationId".
        // If the attribute has no content, the element's text value (white spaces trimmed off) will be used.
        iAttr.$observe('translate', function (translationId) {
          if (angular.equals(translationId , '') || !angular.isDefined(translationId)) {
            scope.translationId = $interpolate(iElement.text().replace(/^\s+|\s+$/g,''))(scope.$parent);
          } else {
            scope.translationId = translationId;
          }
        });

        if (translateValuesExist) {
          iAttr.$observe('translateValues', function (interpolateParams) {
            if (interpolateParams) {
              scope.$parent.$watch(function () {
                scope.interpolateParams = $parse(interpolateParams)(scope.$parent);
              });
            }
          });
        }

        var updateTranslationFn = (function () {
          if (!translateValuesExist) {
            return function () {
              var unwatch = scope.$watch('translationId', function (value) {
                if (value) {
                  iElement.html(translate(value,  {}, translateInterpolation));
                  unwatch();
                }
              }, true);
            };
          } else {
            return function () {
              scope.$watch('interpolateParams', function (value) {
                if (value) {
                  iElement.html(translate(scope.translationId,  value, translateInterpolation));
                }
              }, true);
            };
          }
        }());

        // Ensures the text will be refreshed after the current language was changed
        // w/ $translate.uses(...)
        var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslationFn);

        updateTranslationFn();
        scope.$on('$destroy', unbind);
      };
    }
  };
}]);
</script>

 <div ng-app="plunker" ng-controller="AppController">
    <ul>
      <li ng-repeat="n in [] | range:1000">
        <span translate="FOO">hhh</span>
      </li>
    </ul>
  </div>
ready
with compiling
<script>
angular.module('pascalprecht.translate').directive('translate', ['$filter', '$q', '$interpolate', '$parse', '$rootScope', '$compile', function ($filter, $q, $interpolate, $parse, $rootScope, $compile) {

  var translate = $filter('translate');

  return {
    restrict: 'AE',
    scope: true,
    compile: function (tElement, tAttr) {

      var translateValuesExist = (tAttr.translateValues && !angular.equals(tAttr.translateValues, ''));
      var translateInterpolation = (tAttr.translateInterpolation) ? tAttr.translateInterpolation : undefined;

      return function linkFn(scope, iElement, iAttr) {

        // Ensures any change of the attribute "translate" containing the id will
        // be re-stored to the scope's "translationId".
        // If the attribute has no content, the element's text value (white spaces trimmed off) will be used.
        iAttr.$observe('translate', function (translationId) {
          if (angular.equals(translationId , '') || !angular.isDefined(translationId)) {
            scope.translationId = $interpolate(iElement.text().replace(/^\s+|\s+$/g,''))(scope.$parent);
          } else {
            scope.translationId = translationId;
          }
        });

        if (translateValuesExist) {
          iAttr.$observe('translateValues', function (interpolateParams) {
            if (interpolateParams) {
              scope.$parent.$watch(function () {
                scope.interpolateParams = $parse(interpolateParams)(scope.$parent);
              });
            }
          });
        }

        var updateTranslationFn = (function () {
          if (!translateValuesExist) {
            return function () {
              var unwatch = scope.$watch('translationId', function (value) {
                if (value) {
                  iElement.html($compile(translate(value,  {}, translateInterpolation))(scope));
                  unwatch();
                }
              }, true);
            };
          } else {
            return function () {
              scope.$watch('interpolateParams', function (value) {
                if (value) {
                  iElement.html($compile(translate(scope.translationId,  value, translateInterpolation))(scope));
                }
              }, true);
            };
          }
        }());

        // Ensures the text will be refreshed after the current language was changed
        // w/ $translate.uses(...)
        var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslationFn);

        updateTranslationFn();
        scope.$on('$destroy', unbind);
      };
    }
  };
}]);
</script>

 <div ng-app="plunker" ng-controller="AppController">
    <ul>
      <li ng-repeat="n in [] | range:1000">
        <span translate="FOO">hhh</span>
      </li>
    </ul>
  </div>
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by PascalPrecht on