8

I ran Google pagespeed and it suggests compressing my .js and .css

Eliminate render-blocking JavaScript and CSS in above-the-fold content Show how to fix

Enable compression
Compressing resources with gzip or deflate can reduce the number of bytes sent over the network.
Enable compression for the following resources to reduce their transfer size by 210.9KiB (68% reduction).
Compressing http://xx.com/content/bundles/js.min.js could save 157.3KiB (65% reduction).
Compressing http://xx.com/content/bundles/css.min.css could save 35.5KiB (79% reduction).
Compressing http://xx.com/ could save 18.1KiB (79% reduction).

During my publish I have a step that uses Windows Powershell to move a .js and .css mimified bundle to S3 and this goes to cloudfront.

Is there some step I could add in the PowerShell script that would compress the .js and .css files?

Also once the files are compressed then do I have to do anything more than change the name so as to tell my browser that it will need to try and accept a gzip file?

  • Manually compress? No, but it can automatically compress them. Have you tried anything? A quick search on Google netted me a function that will gzip a file for you, took me all of 15 seconds or so to find it searching for "powershell gzip" Let us know if you get some code and run into errors, we can help with errors =) – TheMadTechnician May 19 '15 at 03:49
  • did you've heard about `gulp`? i usually compress my asset files (js, css, and image) and upload to s3 automatically. just need to run 1 gulp command. – Ary Wibowo May 22 '15 at 01:10
  • @AryWibowo - Can you give me an example of how this could be used from Powershell ? –  May 22 '15 at 02:51
  • honestly i don't really know about Powershell. but `gulp` is CLI. assuming you've installed gulp correctly. you just need type `gulp` in command line on folder where file `gulpfile.js` placed. i found good article for it http://enehana.nohea.com/general/learning-gulp-with-visual-studio-the-javascript-task-runner/ – Ary Wibowo May 22 '15 at 04:42
  • If you go down this path you might want to consider browsers that do not accept gzip content (via the accepts header) so you might need two copies of your content. Most web servers have modules that will assess this when a request comes in and serve the right content, most can even be configured to compress on the fly. The type of the content the is determined by the response content-type header and not the extension of the file being requested. You might want to read this [Amazon documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html). – diadical May 28 '15 at 11:29

3 Answers3

8

You can add to your upload script the needed code to gzip compress the files.

Some example code could be this:

function Gzip-FileSimple
{
    param
    (
        [String]$inFile = $(throw "Gzip-File: No filename specified"),
        [String]$outFile = $($inFile + ".gz"),
        [switch]$delete # Delete the original file
    )

    trap
    {
        Write-Host "Received an exception: $_.  Exiting."
        break
    }

    if (! (Test-Path $inFile))
    {
        "Input file $inFile does not exist."
        exit 1
    }

    Write-Host "Compressing $inFile to $outFile."

    $input = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)

    $buffer = New-Object byte[]($input.Length)
    $byteCount = $input.Read($buffer, 0, $input.Length)

    if ($byteCount -ne $input.Length)
    {
        $input.Close()
        Write-Host "Failure reading $inFile."
        exit 2
    }
    $input.Close()

    $output = New-Object System.IO.FileStream $outFile, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
    $gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)

    $gzipStream.Write($buffer, 0, $buffer.Length)
    $gzipStream.Close()

    $output.Close()

    if ($delete)
    {
        Remove-Item $inFile
    }
}

From this site: Gzip creation in Powershell

5

Powershell community extensions has a scriptlet for gZipping files, and it's very easy to use:

Write-Gzip foo.js #will create foo.js.gz
mv foo.js.gz foo.js -Force

You don't have to rename your files, just add a Content-Encoding header and set it to gzip.

MatteoSp
  • 2,940
  • 5
  • 28
  • 36
  • 1
    MatteoSp - Could you give an example of how this is used. Can you confirm if this will do the same thing as the Gzip-FileSimple function in the other answer? –  May 22 '15 at 02:51
  • Edited my answer. But i can't understand what you mean by "confirm if this will do the same thing as". Are you asking if they use the same compression algorithm or what? – MatteoSp May 22 '15 at 08:50
0

Since Amazon S3 is intended to only serve static files, it doesn't compress files (assets), that's why you need to compress them by yourself:

  • Compress your .js and .css with gzip: I don't know about howto with PowerShell, but I do with Python, I suggest to make a python deployment script (even better a fabfile) and integrate the compression and push code on it.

  • "Also once the files are compressed then do I have to do anything more than change the name so as to tell my browser that it will need to try and accept a gzip file?" : Good Questions ! It is not necessary to change the name of the compressed file, I suggest to don't rename. However, you:

  • MUST set also the header "Content-Encoding:gzip" otherwise browsers will not know the file.

  • Must set the headers 'Content-Type': type (type = 'application/javascript' or 'text/css')

  • Must set the header 'x-amz-acl': 'public-read': to make it public accessible.

  • I suggest also to set the header "Cache-Control:max-age=TIME" (example: TIME=31104000, for 360 days): To help browsers caching it (Better performance)

This will work whether served from origin or with cloudfront. But remember, if you serve them with cloudfront, You will need to invalidate all the files after each push, otherwise the old version will live up to 24 hours from the push. Hope this helps, I can provide a python solution if needed.

Yahya Yahyaoui
  • 2,833
  • 23
  • 30