Why does JsonResponse keep returning a <?php tag at the beginning?
I was having trouble with this same bug.

At the top of my response there was a php short open tag

&lt;?
&lt;aside data-entity-id="392" data-entity-type="node" class="sidenote"&gt;


That was breaking my jQuery ajax call.

It was working locally but broken on the QA server.  Ultimately, after researching the problem, I knew that there was some corrupt PHP file outputting to the page before Drupal explicitly output the page.

After discovering from my php.ini file that short tags were disabled on QA and enabled locally, I was able to grep the codebase for documents in my theme and custom modules that started with a php short tag.  Sure enough, my theme's .theme file was empty with just a php short open tag in it:

&lt;?


Changing this to a regular php open tag and a newline fixed the bug.

&lt;aside data-entity-id="392" data-entity-type="node" class="sidenote"&gt; 


The qa server was outputting this to the page, but only on this one page (that I know about).  I guess because I was calling 

\Drupal::service('renderer')-&gt;renderRoot($data);


If I removed that, the controller could return clean json or output.  But when I got the theme layer involved, the bug crept up.