diff --git a/Gemfile.lock b/Gemfile.lock
index ca0385dd9..dc78e8f6d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -82,7 +82,7 @@ GEM
     erubis (2.7.0)
     eventmachine (1.0.3)
     excon (0.39.6)
-    execjs (2.2.1)
+    execjs (2.2.2)
     exifr (1.1.3)
     fabrication (2.9.8)
     fakeweb (1.3.0)
@@ -390,7 +390,7 @@ GEM
     trollop (2.0)
     tzinfo (1.2.2)
       thread_safe (~> 0.1)
-    uglifier (2.5.3)
+    uglifier (2.6.0)
       execjs (>= 0.3.0)
       json (>= 1.8.0)
     unf (0.1.4)
diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake
index 1c0ac999b..968ed95fd 100644
--- a/lib/tasks/assets.rake
+++ b/lib/tasks/assets.rake
@@ -11,6 +11,12 @@ task 'assets:precompile:before' do
   puts "Purging temp files"
   `rm -fr #{Rails.root}/tmp/cache`
 
+  if Rails.configuration.assets.js_compressor == :uglifier
+    ENV["UGLIFY"] = "1"
+  end
+
+  puts "Bundling assets"
+
   # in the past we applied a patch that removed asset postfixes, but it is terrible practice
   # leaving very complicated build issues
   # https://github.com/rails/sprockets-rails/issues/49
@@ -19,46 +25,44 @@ task 'assets:precompile:before' do
   require 'sprockets'
   require 'digest/sha1'
 
-  module ::Sprockets
 
-    def self.redis
-      @redis ||=
-        (
-          redis_url = GlobalSetting.asset_redis_url
-          if redis_url.present?
-            uri = URI.parse(redis_url)
-            options = {}
-            options[:password] = uri.password if uri.password.present?
-            options[:host] = uri.host
-            options[:port] = uri.port || 6379
-            Redis.new(options)
-          else
-            DiscourseRedis.raw_connection
-          end
-        )
-    end
+  # monkey patch asset pipeline not to gzip, compress: false is broken
+  class ::Sprockets::Asset
+    # Save asset to disk.
+    def write_to(filename, options = {})
+      # Gzip contents if filename has '.gz'
+      return if File.extname(filename) == '.gz'
 
-    def self.cache_compiled(type, data)
-      # add cache breaker here if uglifier options change
-      digest = Digest::SHA1.hexdigest(data) << "v1"
-      key = "SPROCKETS_#{type}_#{digest}"
-      if compiled = redis.get(key)
-        redis.expire(key, 1.week)
-      else
-        compiled = yield
-        redis.setex(key, 1.week, compiled)
+      begin
+        FileUtils.mkdir_p File.dirname(filename)
+
+        File.open("#{filename}+", 'wb') do |f|
+          f.write to_s
+        end
+
+        # Atomic write
+        FileUtils.mv("#{filename}+", filename)
+
+        # Set mtime correctly
+        File.utime(mtime, mtime, filename)
+
+        nil
+      ensure
+        # Ensure tmp file gets cleaned up
+        FileUtils.rm("#{filename}+") if File.exist?("#{filename}+")
       end
-      compiled
     end
 
+
+  end
+
+  module ::Sprockets
+
     class UglifierCompressor
 
       def evaluate(context, locals, &block)
-        ::Sprockets.cache_compiled("uglifier", data) do
-           Uglifier.new(:comments => :none,
-                        :screw_ie8 => false,
-                        :output => {max_line_len: 1024}).compile(data)
-        end
+        # monkey patch cause we do this later, no idea how to cleanly disable
+        data
       end
 
     end
@@ -79,7 +83,77 @@ task 'assets:precompile:css' => 'environment' do
   end
 end
 
+def assets_path
+  "#{Rails.root}/public/assets"
+end
+
+def compress_node(from,to)
+  to_path = "#{assets_path}/#{to}"
+
+  source_map_root = (d=File.dirname(from)) == "." ? "/assets" : "/assets/#{d}"
+
+  STDERR.puts `uglifyjs '#{assets_path}/#{from}' -p relative -c -m -o '#{to_path}' --source-map-root '#{source_map_root}' --source-map '#{assets_path}/#{to}.map' --source-map-url '/assets/#{to}.map'`
+end
+
+def compress_ruby(from,to)
+  data = File.read("#{assets_path}/#{from}")
+
+  uglified, map = Uglifier.new(comments: :none,
+                               screw_ie8: false,
+                               source_filename: File.basename(from),
+                               output_filename: File.basename(to)
+                              )
+                          .compile_with_map(data)
+  dest = "#{assets_path}/#{to}"
+
+  File.write(dest, uglified << "\n//# sourceMappingURL=/assets/#{to}.map")
+  File.write(dest + ".map", map)
+end
+
+def gzip(path)
+  STDERR.puts "gzip #{path}"
+  STDERR.puts `gzip -f -k -9 #{path}`
+end
+
+def compress(from,to)
+  if @has_uglifyjs ||= !`which uglifyjs`.empty?
+    compress_node(from,to)
+  else
+    compress_ruby(from,to)
+  end
+end
+
 task 'assets:precompile' => 'assets:precompile:before' do
   # Run after assets:precompile
   Rake::Task["assets:precompile:css"].invoke
+
+  if ENV["UGLIFY"]
+    puts "Compressing Javascript and Generating Source Maps"
+    manifest = Sprockets::Manifest.new(assets_path)
+    manifest.files
+            .select{|k,v| k =~ /\.js$/}
+            .each do |file, info|
+
+        path = "#{assets_path}/#{file}"
+        _file = (d = File.dirname(file)) == "." ? "_#{file}" : "#{d}/_#{File.basename(file)}"
+        _path = "#{assets_path}/#{_file}"
+
+        if File.exists?(_path)
+          STDERR.puts "Skipping: #{file} already compressed"
+        else
+          STDERR.puts "Compressing: #{file}"
+          FileUtils.mv(path, _path)
+          compress(_file,file)
+
+          info["size"] = File.size(path)
+          info["mtime"] = File.mtime(path).iso8601
+          gzip(path)
+        end
+
+    end
+
+    # protected
+    manifest.send :save
+
+  end
 end