4
votes

I'm using Play Framework 2.1.3 for my site and I've noticed that the built-in web server (Netty) is not serving Gzipped assets, even though the Play documentation says it should be automatically whenever a same-name asset with a .gz prefix is present in the public folder.

I have tried Gzipping assets manually (e.g. bootstrap.min.js -> bootstrap.min.js.gz) and the framework will not serve the .gz version of the file through the Assets controller. I have also tried using the following (hackish) code in Build.scala to implement automatic Gzipping but it still doesn't appear to work at all (and I can't determine where the Gzip files are located, either, even though the log says the assets were in fact Gzipped):

     val gzippableAssets = SettingKey[PathFinder]("gzippable-assets", "Defines the files to gzip")
  val gzipAssets = TaskKey[Seq[File]]("gzip-assets", "gzip all assets")
  lazy val gzipAssetsSetting = gzipAssets <<= gzipAssetsTask dependsOn (copyResources in Compile)
  lazy val gzipAssetsTask = (gzippableAssets, streams) map {
    case (finder: PathFinder, s: TaskStreams) => {
      var count = 0
      var files = finder.get.map { file =>
        val gzTarget = new File(file.getAbsolutePath + ".gz")
        IO.gzip(file, gzTarget)
        count += 1;
        gzTarget
      }
      s.log.info("Compressed " + count + " asset(s)")
      files
    }
  }

  val main = play.Project(appName, appVersion, appDependencies).settings(
    // Add your own project settings here
    resolvers += Resolver.url("sitemapper repository", url("http://blabluble.github.com/modules/releases/"))(Resolver.ivyStylePatterns),
    gzippableAssets <<= (classDirectory in Compile)(dir => (dir ** ("*.js" || "*.css" || "*.html" || "*.jpg" || "*.png" || "*.jpeg" || "*.gif" || "*.eot" || "*.svg" || "*.ttf" || "*.woff"))),
    gzipAssetsSetting,
    playPackageEverything <<= playPackageEverything dependsOn gzipAssets

  )

Why can't Play just include GZIP support natively like every other major web framework out there instead of making people hack it together? Using a front-end web server to do it for me is not an option at this time. Any suggestions or easier ways to do this are greatly appreciated. Play documentation is rather sparse on things like this.

For those that are interested in verifying the lack of GZip assets being served, the site is http://Netizen.us

1

1 Answers

4
votes

I suspect you tested the gzip delivery in dev mode and not in prod mode. In dev mode a lot of optimizations are off.

Play 2.2 will have better gzip support: https://github.com/playframework/playframework/pull/1515


I created a test project (https://github.com/schleichardt/stackoverflow-answers/tree/so18604777) and I can't reproduce in prod mode with

sbt dist && cd dist && unzip so18604777-1.0-SNAPSHOT.zip && cd so18604777-1.0-SNAPSHOT && bash start 

I created manually a main.css.gz for the main.css and got the following Response Headers in Chromium 28:

HTTP/1.1 200 OK
Vary: Accept-Encoding
Last-Modified: Wed, 04 Sep 2013 06:13:32 GMT
Etag: "67253bcb7bacb5bbfe3d445f35ae177b60429d5e"
Content-Encoding: gzip
Content-Length: 49
Cache-Control: max-age=3600
Content-Type: text/css; charset=utf-8
Date: Wed, 04 Sep 2013 06:18:00 GMT

49 Bytes is exactly the size of the gzipped file (original: 20 Bytes) and the displayed content was correct.

For a file with another but the same content that has not a gzipped equivalent:

HTTP/1.1 200 OK
Last-Modified: Wed, 04 Sep 2013 06:13:32 GMT
Etag: "48ccae14d846b77d1a33a1db18f52e0841f0a830"
Content-Length: 20
Cache-Control: max-age=3600
Content-Type: text/css; charset=utf-8
Date: Wed, 04 Sep 2013 06:18:25 GMT