javaScriptBottleYLT.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /**
  2. * Reports the use of functions known to be serious performance bottlenecks in JS
  3. *
  4. * @see http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
  5. * @see http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html
  6. * @see http://www.stevesouders.com/blog/2012/04/10/dont-docwrite-scripts/
  7. *
  8. * Run phantomas with --spy-eval to count eval() calls (see issue #467)
  9. */
  10. /* global document: true, window: true */
  11. exports.version = '0.2';
  12. exports.module = function(phantomas) {
  13. 'use strict';
  14. phantomas.setMetric('documentWriteCalls'); //@desc number of calls to either document.write or document.writeln @offenders
  15. phantomas.setMetric('evalCalls'); // @desc number of calls to eval (either direct or via setTimeout / setInterval) @offenders
  16. // spy calls to eval only when requested (issue #467)
  17. var spyEval = phantomas.getParam('spy-eval') === true;
  18. if (!spyEval) {
  19. phantomas.log('javaScriptBottlenecks: to spy calls to eval() run phantomas with --spy-eval option');
  20. }
  21. phantomas.on('init', function() {
  22. phantomas.evaluate(function(spyEval) {
  23. (function(phantomas) {
  24. function report(msg, caller, backtrace, metric) {
  25. phantomas.log(msg + ': from ' + caller + '!');
  26. phantomas.log('Backtrace: ' + backtrace);
  27. phantomas.incrMetric(metric);
  28. phantomas.addOffender(metric, "%s from %s", msg, caller);
  29. }
  30. // spy calls to eval()
  31. if (spyEval) {
  32. phantomas.spy(window, 'eval', function(code) {
  33. report('eval() called directly', phantomas.getCaller(), phantomas.getBacktrace(), 'evalCalls');
  34. phantomas.log('eval\'ed code: ' + (code || '').substring(0, 150) + '(...)');
  35. });
  36. }
  37. // spy calls to setTimeout / setInterval with string passed instead of a function
  38. phantomas.spy(window, 'setTimeout', function(fn, interval) {
  39. if (typeof fn !== 'string') return;
  40. report('eval() called via setTimeout("' + fn + '")', phantomas.getCaller(), phantomas.getBacktrace(), 'evalCalls');
  41. });
  42. phantomas.spy(window, 'setInterval', function(fn, interval) {
  43. if (typeof fn !== 'string') return;
  44. report('eval() called via setInterval("' + fn + '")', phantomas.getCaller(), phantomas.getBacktrace(), 'evalCalls');
  45. });
  46. // spy document.write(ln)
  47. phantomas.spy(document, 'write', function(arg) {
  48. report('document.write() used', phantomas.getCaller(), phantomas.getBacktrace(), 'documentWriteCalls');
  49. });
  50. phantomas.spy(document, 'writeln', function(arg) {
  51. report('document.writeln() used', phantomas.getCaller(), phantomas.getBacktrace(), 'documentWriteCalls');
  52. });
  53. })(window.__phantomas);
  54. }, spyEval);
  55. });
  56. };