Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jesse Andrews 191 posts 716 karma points c-trib
    May 22, 2018 @ 01:49
    Jesse Andrews
    0

    Api call to /umbraco/GetGridConfig very slow to finish when requested a second time

    Umbraco: 7.10.3

    I'm working on creating a custom grid control that uses the grid inside it. I've gotten the grid to load, but for some reason it takes a very long time to load. When /umbraco/GetGridConfig is requested by the outer grid, it loads fairly quickly, but when it's requested from the grid widget I created, it takes around a minute to finish. Does anyone know why it would behave like this?

  • Dave Woestenborghs 3504 posts 12134 karma points MVP 9x admin c-trib
    May 22, 2018 @ 06:23
    Dave Woestenborghs
    0

    Hi Jesse,

    Can you show some code on how you load the grid config ?

    I'm calling it like this in my nexu parser for the grid. This works fast, as I would expect it to be.

    https://github.com/dawoe/umbraco-nexu/blob/develop/Source/Our.Umbraco.Nexu.Parsers/PropertyParsers/Core/GridParser.cs#L35

    Dave

  • Jesse Andrews 191 posts 716 karma points c-trib
    May 22, 2018 @ 08:34
    Jesse Andrews
    0

    The api the grid data type uses collects the grid data the same way your parser does (though it doesn't have the check to make sure HttpContext.Current has a value). It is fairly fast the first time, but really slow when I run the built in grid control from inside my custom grid widget. Not sure why though, as no parameters are passed to this particular api. You can see the main code below (creating an accordion grid widget whose content can be controlled with a grid control; can be done with tools like leblender, but that window doesn't really give enough space for a full grid control; can expand the window, but then that leads to a lot of wasted space in most cases).

    (function () {
        angular.module('umbraco')
            .directive('bmgAccordion', bmgAccordion);
    
        bmgAccordion.$inject = ['dataTypeResource', 'notificationsService'];
        function bmgAccordion(dataTypeResource, notificationsService) {
            var directive = {
                restrict: 'E',
                template: `
                    <umb-control-group label="Theme" description="Theme to use when rendering the accordion.">
                        <api-picker api="/umbraco/backoffice/bmgaccordion/accordion/" ng-model="model.value"></api-picker>
                    </umb-control-group>
                    {{gridConfigs}}
                    <ul class="accordion" ng-if="gridConfigs">
                        <li ng-repeat="item in model.items" ng-class="{active: activeIndex === $index}">
                            <div>
                                <label>Label</label>
                                <input type="text" ng-model="item.label" placeholder="Enter Label" />
                            </div>
                            <div class="grid-container">
                                <umb-editor model="gridConfigs[$index]"></umb-editor>
                                <umb-load-indicator ng-if="busy"></umb-load-indicator>
                            </div>
                        </li>
                    </ul>
                `,
                link: link,
                scope: {
                    model: '=ngModel',
                    gridId: '='
                }
            };
            return directive;
            function link($scope, $element) {
                var cancelListener;
                if (!$scope.model) {
                    $scope.model = {
                        theme: 'Default',
                        items: [{}]
                    }
                    $scope.activeIndex = 0;
                }
                if ($scope.gridId) {
                    $scope.busy = true;
                    dataTypeResource.getById($scope.gridId)
                        .then(function (data) {
                            $scope.gridConfigs = [];
                            for (var i = 0; i < $scope.model.items.length; i++) {
                                $scope.gridConfigs.push({
                                    "config": {
                                        "items": data.preValues[0].value,
                                        "rte": data.preValues[1].value
                                    },
                                    "value": $scope.model.items[i],
                                    "view": "grid",
                                    "label": "Content",
                                    "hideLabel": false,
                                    "readonly": false,
                                    "editor": "Umbraco.Grid"
                                });
                            }
                            if ($scope.activeIndex !== undefined) {
                                cancelListener = $scope.$watch('gridConfigs[' + $scope.activeIndex + '].value', function (newVal) {
                                    console.log(newVal);
                                    $scope.model.items[$scope.activeIndex] = newVal;
                                });
                            }
                        })
                }
                else {
                    notificationsService.error('No grid id has been set.')
                }
    
                $scope.toggle = function (index) {
                    if (cancelListener) {
                        cancelListener();
                        cancelListener = null;
                    }
                    if ($scope.activeIndex === index) {
                        $scope.activeIndex = null;
                    }
                    else {
                        $scope.activeIndex = index;
                        cancelListener = $scope.$watch('gridConfigs[' + index + '].value', function (newVal) {
                            $scope.model.items[$scope.activeIndex] = newVal;
                        });
                    }
                };
    
                $scope.addItem = function () {
                    $scope.model.items.push({});
                    $scope.activeIndex = $scope.model.items.length - 1;
                };
    
                $scope.removeItem = function (index) {
                    if ($scope.activeIndex === index) {
                        $scope.activeIndex = null;
                    }
                    $scope.model.items.splice(index, 1);
                };
    
                $scope.$on('$destroy', function () {
                    if (cancelListener) {
                        cancelListener();
                    }
                });
            }
        }
    })();
    

    It gets the grid configuration from a grid data type (stored in the gridConfigs array) and then passes that to the umb-editor directive. The grid control loads fine eventually, it's just really slow to display because the api call doesn't resolve quickly. The relevant bit, that triggers the api call can be seen here.

  • Jesse Andrews 191 posts 716 karma points c-trib
    May 23, 2018 @ 23:32
    Jesse Andrews
    0

    Found a likely cause after tracing the code. I suspect the problem is that the ReadAllText call in GridEditorsConfig.cs is blocking access to grid.editors.config.js as the connection isn't disposed of. This would explain why a second call is taking so long to finish, as I'm running it in debug mode, so it doesn't load it from cache. For now, the workaround seems to be to just disable debug mode, so that it pulls from the cache instead. This should fix things, but I will give it a couple days before I mark this as the solution to make sure the performance issue doesn't pop up again.

Please Sign in or register to post replies

Write your reply to:

Draft