Skip to main content
Announcements
Have questions about Qlik Connect? Join us live on April 10th, at 11 AM ET: SIGN UP NOW
cancel
Showing results for 
Search instead for 
Did you mean: 
fduchmann
Partner - Contributor III
Partner - Contributor III

Javascript Data Leaks in Extension

Hello Qlik-Community,

I have the following problem with my Qlik Sense Extension:

When I often select and deselect Data, my Extension gets slower and slower over time, until it is not

possible to use Qlik Sense. After refreshing the (CTRL + F5 in Chromium) everything works fine again.

I guess it might be a problem with Data Leaks in Javascript.

My code-structure looks something like this:

paint: function($element, layout) {

  var cube1Def {...}

  var cube2Def {...}

  var app1 = qlik.currApp();

  var app2 = qlik.currApp();

  app1.createCube(cube1Def, function(q1) {

       //do some calculation

       app2.createCube(cube2Def, function(q2) {

            //do some calculation

            //drawing the content here

       }

  }

}

Here are some pictures of the Memory Timeline from Chromium Developer Tools:

  Random Selection --> Just did some random selections

  All and one --> Selecting all Data and only one Entry, alternating

   

     Random Selection

Varius Selection.PNG

     All and One Selection

All and One.PNG

Hope someone can help me, to prevent my Extension from slowing down.

best regards

Frank

1 Solution

Accepted Solutions
Alexander_Thor
Employee
Employee

On the model that is return from the createCube() promise you should be able to unbind the function for model.Validated

Alternatively

define([], function() {

return {

     initialProperties: {

          qHyperCubeDef: {},

          secondcube: {

               qHyperCubeDef: {}

          },

          thirdcube: {

               qHyperCubeDef: {}

          }

     },

     paint: function($element, layout) {

          console.log( layout.qHyperCube, layout.secondcube.qHyperCube, layout.thirdcube.qHyperCube )

     }

  }

})

See this part of the documentation for all the available definitions you can set on a Generic Object, http://help.qlik.com/en-US/sense-developer/3.0/Subsystems/EngineAPI/Content/GenericObject/PropertyLe...

Perhaps a qStringExpression or qValueExpression would be enough if you just need a simple calculation.

View solution in original post

6 Replies
tlorimier
Partner - Contributor III
Partner - Contributor III

Hi,

I have some element about this.

When you create an hypercube via this method createCube you need to destroy it after or before the next paint or the reference will be keep by Qlik Sense.

To do this I use this method : app.destroySessionObject() to release the memory inside the Qlik Engine.

Still you will get some memory leak after because there is a problem in Qlik Sense Desktop (I already report to the dev team and the problem occurs only in desktop it seems).

Regards,

Thibaut

Alexander_Thor
Employee
Employee

Hey,

So what is happening is that you are creating 2 data cubes on every render cycle, so every time someone makes a selection your extension creates 2 calculation cubes on the server so it will eventually slow down.

What you could try is to un-bind the Validated event on the cubes once you have rendered which should force it to not try to update old cubes.

The other option would be to not recreate the cubes all the time but instead stick them onto your extension definition instead.

fduchmann
Partner - Contributor III
Partner - Contributor III
Author

Hey Alexander,

thanks for your reply.

The behaviour I think is correct, because after a selection the content of the cubes needed to be changed. The only thing is that the old cubes should be removed, because they are not needed anymore.

Is there any documentation about un-bind the update event for the old cubes ?

If I would stick the cubes to the extension definition, so they will be created only once, but the content gets updatet after every selection? Or how is the Qlik-Sense Backend behaviour ?

Frank

Alexander_Thor
Employee
Employee

On the model that is return from the createCube() promise you should be able to unbind the function for model.Validated

Alternatively

define([], function() {

return {

     initialProperties: {

          qHyperCubeDef: {},

          secondcube: {

               qHyperCubeDef: {}

          },

          thirdcube: {

               qHyperCubeDef: {}

          }

     },

     paint: function($element, layout) {

          console.log( layout.qHyperCube, layout.secondcube.qHyperCube, layout.thirdcube.qHyperCube )

     }

  }

})

See this part of the documentation for all the available definitions you can set on a Generic Object, http://help.qlik.com/en-US/sense-developer/3.0/Subsystems/EngineAPI/Content/GenericObject/PropertyLe...

Perhaps a qStringExpression or qValueExpression would be enough if you just need a simple calculation.

fduchmann
Partner - Contributor III
Partner - Contributor III
Author

Hey Thibaut,

thanks for your reply.

The manual deleting of the old cubes sounds plausible.

I will try the destroy function. I would like to destroy only the old cubes and keep the latest cube in memory, because it is needed to make selections inside my extension.

My only Question is right now, how can I reference the old hypercube? Because my layout.qInfo.qId stays the same during repainting and even trough reloading the page.

Frank

fduchmann
Partner - Contributor III
Partner - Contributor III
Author

Hey all,

i know it's a longe time ago, but i wanted to show you my progress and how i solved the problem with the help of you, the Community Members. All hypercube destroy and unbind functions did not solve the problem. In the Chrome Developer Tools you could not see any changes.

After all I decided to go the MVC way with AngularJS and this solved the Data Leak Problem.

Instead of using the paint method i defined a controller (like in the standard example from Stefan Walter).

The Controller gets some initialProperties from an external file.

extension.js

definition: properties,

initialProperties: initialProperties,

snapshot: {canTakeSnapshot: true},

template: ngIndex,

controller: ['$scope', function ( $scope) {

    ...

     $scope.component.model.Validated.bind( function () {

       ....

     // In this part all 3 HyperCubes are ready to use

     // If one of the HyperCubes changes its content this part gets executed again like the paint method

        ...

     }

}

In those initialProperties.JS file the three HyperCubes gets defined.

initialProperties.js

cube1 : {

            qHyperCubeDef : {

                qDimensions : [

                    {

                        qDef: {

                            qFieldDefs: ['ActivityID']

                        }

                    }, {

                        qDef: {

                            qFieldDefs: ['ActivityDescription']

                        }

                    }

                ],

                qMeasures: [{

                    qDef: {

                        qDef: '=Sum(Counter)'

                    }

                }],

                qInitialDataFetch : [{

                    qWidth : 3,

                    qHeight : 50

                }]

            }

        },

cube2 : {

  ...

  //the same as above

},

cube3 : {

  ...

  //the same as above

}

Thanks to akl I think that was the solution you provided.

Hope this helps someone.

Best regards

Frank