Skip to content

10X performance improvement by re-using iframe #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Special files #
#################
settings-production.json

# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql
*.sqlite
npm-debug.log.*

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# File Folders #
################
/node_modules
/packages

65 changes: 37 additions & 28 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
var indexOf = require('indexof');

// cached iFrame instance, re-use for each runInContext Call.
var iFrame = null;

var Object_keys = function (obj) {
if (Object.keys) return Object.keys(obj)
else {
@@ -45,37 +48,43 @@ Context.prototype = {};

var Script = exports.Script = function NodeScript (code) {
if (!(this instanceof Script)) return new Script(code);
if(!iFrame) {
iFrame = document.createElement('iframe');
if (!iFrame.style) iFrame.style = {};
iFrame.style.display = 'none';

document.body.appendChild(iFrame);
}
this.code = code;
this.iFrame = iFrame;
};

Script.prototype.runInContext = function (context) {
if (!(context instanceof Context)) {
throw new TypeError("needs a 'context' argument.");
}

var iframe = document.createElement('iframe');
if (!iframe.style) iframe.style = {};
iframe.style.display = 'none';

document.body.appendChild(iframe);

var win = iframe.contentWindow;
var win = this.iFrame.contentWindow;
var winOriginal = Object_keys(win);
let originalToRestore = [];
var wEval = win.eval, wExecScript = win.execScript;

if (!wEval && wExecScript) {
// win.eval() magically appears when this is called in IE:
wExecScript.call(win, 'null');
wEval = win.eval;
}

forEach(Object_keys(context), function (key) {
win[key] = context[key];
});
forEach(globals, function (key) {
if (context[key]) {
win[key] = context[key];
}
if(win[key] !== undefined) {
let restore = {
'key': key,
'value': win[key]
};
originalToRestore.push(restore);
}
win[key] = context[key];
});

if (!wEval && wExecScript) {
// win.eval() magically appears when this is called in IE:
wExecScript.call(win, 'null');
wEval = win.eval;
}


var winKeys = Object_keys(win);

@@ -86,18 +95,18 @@ Script.prototype.runInContext = function (context) {
// updating existing context properties or new properties in the `win`
// that was only introduced after the eval.
if (key in context || indexOf(winKeys, key) === -1) {
context[key] = win[key];
if (indexOf(globals, key) === -1) context[key] = win[key];
else defineProp(context, key, win[key]);
}
// delete win context of extra fields
if (indexOf(winOriginal, key) === -1) delete win[key];
});

forEach(globals, function (key) {
if (!(key in context)) {
defineProp(context, key, win[key]);
}
// restore context to original field values
forEach(originalToRestore, function (orig) {
win[orig.key] = orig.value;
});

document.body.removeChild(iframe);


return res;
};