views:

195

answers:

4

I have many different regex patterns automatically loaded everytime my greasemonkey script starts. 95% of this loaded memory isn't needed at any stage, so I would like to find a way to not even put that data into memory to begin with if I know it won't be used.

Take this a basic example:

 var patterns = [
   {
     name    : 'p1',
     url     : 'http://www.someurl.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   },
   {
     name    : 'p2',
     url     : 'http://www.someurl2.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   },
   {
     name    : 'p3',
     url     : 'http://www.someurl3.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   },

 ];

....and many more patterns.

I don't need to load any of the data if the url does not match the current url (location.href).

A: 

Use a document.write() to include the data from a separate javascript file if and only if it's needed.

dave mankoff
I think you misunderstood the question...
Gary Green
A: 

Since this is a GreaseMonkey script, I assume it's resident on the user's machine, not generated from an external site. If that's not the case, you might want to consider generating the JavaScript on the fly based on the URL.

Otherwise, you could store the pattern assignment JavaScript in separate files, retrieve only one of the files based on the URL of the site loaded, and run its contents through eval() as if it were a JSON request.

Jekke
I thought about doing this but would I not have to have thousands of javascript files and lots of duplicating data? It could get very messy. Ideally, I would like a function built into javascript that only load whats in the var when accessed.
Gary Green
+2  A: 

The best way is if you could load data on demand via GM_getResourceText+eval. The resource data defined in the metadata block will be downloaded on the userscript's first install.

Documentation: http://wiki.greasespot.net/Metadata_block#.40resource

You need to think how to store the data - maybe a resource per site (nasty I know) ?

Another simpler solution to alleviate performance problems is to store the regular expressions as simple strings and create RegExp objects only when needed. Eg: patterns : [".", ".", "."] and new RegExp(the_pattern) when the expression is actually needed.

ionelmc
Thats a very good way of doing it, especially regarding only initiating the patterns when needed. That could be implemented right away.
Gary Green
+1  A: 

You could stick with your current definition of patterns and remove all the patterns you don't need:

var patterns = [
   //patterns array as defined in question
];
var newpatterns = [];
var count = 0;

for (var i = 0 ; i < patterns.length ; i++ ){
  if (href.indexOf(patterns[i].url) == -1) {
     newpatterns[count++] = patterns[i];
     console.log("remove " + patterns[i].name);
  }
}
patterns = newpatterns;

Although this way you're still loading it all into memory initially, but not keeping objects you don't need for the whole lifetime of the page.

A better way would be to test each object one at a time, before it's added to the patterns array, and only adds objects relevant to the current url.

var patterns = [];
var count = 0;

var href = window.location.href;

function addPattern(p){
    if (href.indexOf(p.url) != -1) patterns[count++] = p;
}

addPattern({
     name    : 'p1', 
     url     : 'http://www.someurl.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   })

addPattern({
     name    : 'p2',
     url     : 'http://www.someurl2.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   })

addPattern({
     name    : 'p3',
     url     : 'http://www.someurl3.com',
     pattern1 : /./,
     pattern2 : /./,
     pattern3 : /./,
   })
Sam Hasler
Thats a good idea but it doesn't really work because you are still loading the object to memory, passing the object to a function and then loading the object to another part of memory. Looks like more work than before! ;-)
Gary Green
this only loads one pattern at a time, and it will only keep in memory the ones that are relevant to the page.
Sam Hasler