{"id":19397,"date":"2014-06-05T14:25:20","date_gmt":"2014-06-05T14:25:20","guid":{"rendered":"https:\/\/blog.jetbrains.com\/phpstorm\/?p=7543"},"modified":"2024-01-09T14:59:54","modified_gmt":"2024-01-09T13:59:54","slug":"tracing-debugging-and-profiling-javascript-code-with-spy-js-in-phpstorm","status":"publish","type":"phpstorm","link":"https:\/\/blog.jetbrains.com\/phpstorm\/2014\/06\/tracing-debugging-and-profiling-javascript-code-with-spy-js-in-phpstorm\/","title":{"rendered":"Tracing, debugging and profiling JavaScript code with spy-js in PhpStorm"},"content":{"rendered":"<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spyjs-logo.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignright size-full wp-image-7544\" alt=\"Spy-JS\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spyjs-logo.png\" width=\"135\" height=\"50\" \/><\/a>Forget about the NSA: PhpStorm 8 EAP comes with spy-js, our own secret service that allows tracing our code without console.log, debugging it without breakpoints and profiling it without any specialized tools. All while running our web app (and even other web apps out there on the Internet, it&#8217;s a secret service after all). Sounds like some serious espionage, right? Let&#8217;s have a quick look at what it can do for us.<\/p>\n<p>A picture is worth a thousand words, and a moving picture is worth ten times that. So here&#8217;s a 7-minute introduction <a href=\"https:\/\/www.youtube.com\/watch?v=vPIbwxzC5cU\" target=\"_blank\" rel=\"noopener\">video<\/a>\u00a0to spy-js:<\/p>\n<p>https:\/\/www.youtube.com\/watch?v=vPIbwxzC5cU<\/p>\n<p dir=\"ltr\">Let&#8217;s order a\u00a0Vodka Martini (shaken, not stirred), and get down to business.<\/p>\n<p dir=\"ltr\"><!--more--><\/p>\n<h2 dir=\"ltr\">Enabling spy-js in PhpStorm<\/h2>\n<p>While PhpStorm includes all features supported in WebStorm, such as spy-js, not all of them are enabled by default. We can enable the spy-js plugin for PhpStorm through\u00a0<em><strong>IDE Settings | Plugins<\/strong><\/em>, clicking the\u00a0<strong>Install JetBrains Plugin&#8230;<\/strong>\u00a0button and adding spy-js to our IDE. Installing of\u00a0NodeJS is also required (<a href=\"http:\/\/nodejs.org\/\" target=\"_blank\" rel=\"noopener\">instructions on their website<\/a>) because spy-js relies heavily on it.<\/p>\n<h2 dir=\"ltr\">Spy-js Run Configuration<\/h2>\n<p>First of all, we will have to create a new\u00a0<strong>Run Configuration<\/strong>. We can specify various options, such as the Node interpreter to use, the trace server port (spy-js will start its proxy server on this port), the tracing configuration and the URL to trace. Note that the URL is not required:\u00a0if we don&#8217;t specify it, our tracing session will capture and display any events from other Internet or local websites (excluding HTTPS) that we visit while the session is still running.<\/p>\n<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spy-js-run-configuration1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-7546\" alt=\"Spy-js Run Configuration\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spy-js-run-configuration1.png\" width=\"627\" height=\"349\" \/><\/a><\/p>\n<p dir=\"ltr\">Spy-js works by sending traffic through a proxy. Checking the\u00a0<em>Automatically configure system proxy<\/em><strong>\u00a0<\/strong>option will\u00a0automatically configure the system proxy on our machine when we start the spy-js Run Configuration, and revert the system proxy settings when we stop it. Mac OS X users may want to follow <a href=\"https:\/\/blog.jetbrains.com\/webstorm\/2014\/04\/spy-js-webstorm-secret-service\/#runconfig\">these instructions<\/a> to avoid having to enter system credentials every time.<\/p>\n<h2 dir=\"ltr\">Spy-js in action<\/h2>\n<p>After launching spy-js, we can open our application in the browser. Spy-js will tell us it&#8217;s active by displaying its logo in the browser. Once that happens, the spy-js tool window in PhpStorm will also contain information about our app execution.<\/p>\n<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spyjs-in-action.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-7547\" alt=\"SpyJS in action\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-spyjs-in-action.png\" width=\"699\" height=\"420\" \/><\/a><\/p>\n<p>Let&#8217;s navigate to <a href=\"http:\/\/www.jetbrains.com\" target=\"_blank\" rel=\"noopener\">www.jetbrains.com<\/a> and see what happens. Because we did not give spy-js a URL to the page to trace, it will simply trace\u00a0<em>all<\/em> web pages we now visit (not for HTTPS). The\u00a0<strong>Events<\/strong> pane will display all DOM events and\u00a0JavaScript code execution roots. Script names have different colors so they can be distinguished more easily.<\/p>\n<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-trace-run.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-7548\" alt=\"Spy-js events\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-trace-run.png\" width=\"490\" height=\"292\" \/><\/a><\/p>\n<p>When we select an individual event, its stack tree is opened in the <strong>Event Stack Pane<\/strong> on the right. Stack tree nodes contain short file and function name, as well as the execution time of the function. We can search the tree for a file or function name by just typing while in the tree.<\/p>\n<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-full-trace.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-7549\" alt=\"Spy-js trace events\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-full-trace.png\" width=\"861\" height=\"255\" \/><\/a><\/p>\n<p>Some nodes may have their execution time rendered in blue. This means that the function is responsible for more than 50% of the execution time of the expanded stack level: a perfect candidate to look into for performance optimization. Nodes rendered in red have had an unhandled exception occur.<\/p>\n<p>After locating and selecting the function we&#8217;re interested in, we can open its trace file with all code execution details. Code is highlighted and we can hover over variables to see their values, or functions to see their return values.<\/p>\n<p><a href=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-inspect-trace.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-7550\" alt=\"Inspect function trace\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2014\/05\/phpstorm-inspect-trace.png\" width=\"479\" height=\"236\" \/><\/a><\/p>\n<p dir=\"ltr\">Much more information can be shown in trace files: we can see executed parts of logical expressions and parts of ternary operators. Imagine the code <code>if (1 == 1 || 2 == 2)<\/code>: spy-js will show us only the first expression has been evaluated to enter the if statement&#8217;s body.<\/p>\n<p dir=\"ltr\">In this blog post, we&#8217;ve highlighted just a few features of spy-js. Head over <a href=\"https:\/\/blog.jetbrains.com\/webstorm\/2014\/04\/spy-js-webstorm-secret-service\/#runconfig\">to the WebStorm blog<\/a> to dive deep into all the available features and what you can do with them.<\/p>\n<p><a href=\"http:\/\/confluence.jetbrains.com\/display\/PhpStorm\/PhpStorm+Early+Access+Program\" target=\"_blank\" rel=\"noopener\">Download the latest PhpStorm 8 EAP<\/a>\u00a0and give spy-js a test drive!\u00a0We would love to hear your thoughts through\u00a0the\u00a0<a href=\"http:\/\/youtrack.jetbrains.com\/issues\/WI\" target=\"_blank\" rel=\"noopener\">issue tracker<\/a>,\u00a0by posting in the comments below, or in our\u00a0<a href=\"http:\/\/devnet.jetbrains.com\/community\/wi?view=discussions\" target=\"_blank\" rel=\"noopener\">forums<\/a>!<\/p>\n<p><em>Develop with pleasure!<\/em><br \/>\n<em>\u2013 JetBrains PhpStorm Team<\/em><\/p>\n","protected":false},"author":118,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[826,808,907],"tags":[263,197,743,365,41,489,399,2279],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/phpstorm\/19397"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/phpstorm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/types\/phpstorm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/users\/118"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/comments?post=19397"}],"version-history":[{"count":1,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/phpstorm\/19397\/revisions"}],"predecessor-version":[{"id":432138,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/phpstorm\/19397\/revisions\/432138"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/media?parent=19397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/categories?post=19397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/tags?post=19397"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ja\/wp-json\/wp\/v2\/cross-post-tag?post=19397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}