People have overcome this problem by manually inspecting the Accept-Encoding request header for a dynamically served page and writing references to either original or compressed files accordingly using a naming convention like myscript.js and myscript.js.gz for regular and compressed files respectively.
If all your pages are statically served from CloudFront, however, there is no opportunity to inspect the request headers. Javascript running on a statically served page has no ability to ask the browser if it supports gzipped content. We found ourselves in this situation and resorted to the following solution to determine if the browser supports gzip:
1) Create a small gzipped file, gzipcheck.js.jgz, and make it available in CloudFront. This file should contain one line of code:
gzipEnabled = true;
2) Use the following code to attempt to load and run this file. You'll probably want to put it in the HTML HEAD section before any other Javascript code.
<script type="text/javascript" src="gzipcheck.js.jgz"> </script>
If the file loads, it sets a flag, gzipEnabled, that indicates whether or not the browser supports gzip.
Use the result to drive a file naming convention for references to other static files. For example, you can upload and reference each compressed Javascript file with an additional .jgz extension. Why .jgz instead of .gz? Because of an annoying limitation of Safari.
When you upload your files to S3/CloudFront, make sure to set the proper HTTP response headers on your files that end in .jgz:
Content-Encoding = gzip Content-Type = application/x-javascript
And if you want browsers to cache your files forever (almost):
Cache-Control = max-age=315360000 Expires = Tue, 31 Dec 2019 20:00:00 GMT
Thanks to Ricardo Rangel who helped design and code this solution.
Update
As of December 20, 2015, Amazon Web Services announced support for Gzipped CloudFront files! See Serving Compressed Files from their developer guide.