如何在发布到AWS S3之前压缩/ gzip我的已最小化的.js和.css文件?

8

我运行了Google页面速度测试,建议压缩我的.js和.css文件。

消除在以上折叠内容中阻止呈现的JavaScript和CSS
显示如何修复

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).

在我的发布过程中,有一步使用Windows Powershell将.js和.css压缩包移动到S3并传输到Cloudfront。请问是否可以在PowerShell脚本中添加一步来压缩.js和.css文件?另外,一旦文件被压缩,我需要做些什么来告诉浏览器需要尝试接受gzip文件,除了更改名称之外?

手动压缩?不需要,它可以自动压缩。你试过什么吗?在谷歌上快速搜索,我找到了一个函数可以为你gzip文件,只花了我大约15秒钟的时间,在搜索“powershell gzip”时就找到了它。如果你得到一些代码并遇到错误,请告诉我们,我们可以帮助解决错误 =) - TheMadTechnician
你听说过 gulp 吗?我通常会压缩我的资源文件(js、css 和图片)并自动上传到 S3。只需要运行一个 gulp 命令即可。 - Ary Wibowo
@AryWibowo - 你能给我一个在Powershell中如何使用的例子吗? - user1943020
老实说,我不太了解Powershell。但是gulp是CLI。假设您已经正确安装了gulp。您只需在包含文件gulpfile.js的文件夹中在命令行中输入gulp即可。我找到了一篇不错的文章供您参考:http://enehana.nohea.com/general/learning-gulp-with-visual-studio-the-javascript-task-runner/ - Ary Wibowo
如果您选择这条路,您可能需要考虑不接受gzip内容的浏览器(通过接受标头),因此您可能需要两份内容副本。大多数Web服务器都有模块,在请求到达时会评估此内容并提供正确的内容,大多数甚至可以配置为实时压缩。内容类型由响应内容类型标头确定,而不是所请求文件的扩展名。您可能需要阅读此Amazon文档 - diadical
3个回答

8
你可以在上传脚本中添加所需的代码来对文件进行gzip压缩。
以下是示例代码:
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
    }
}

从这个网站开始:Powershell中的Gzip创建

5

Powershell社区扩展有一个用于gZip文件的脚本,非常容易使用:

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

您不必重命名文件,只需添加一个Content-Encoding头并将其设置为gzip即可。


1
MatteoSp - 你能举个例子说明这个如何使用吗?你能确认这是否与其他答案中的Gzip-FileSimple函数执行相同的操作吗? - user1943020
编辑了我的回答。但我不理解你所说的“确认这是否会执行相同的操作”。你是在问它们是否使用相同的压缩算法还是什么? - MatteoSp

0

由于Amazon S3仅用于提供静态文件,因此它不会压缩文件(资产),这就是为什么您需要自己压缩它们的原因:

  • 使用gzip压缩.js和.css文件:我不知道如何使用PowerShell进行操作,但是我知道如何使用Python,建议编写一个Python部署脚本(最好是fabfile),并将压缩和推送代码集成到其中。

  • "一旦文件被压缩了,我需要做的事情比更改名称还要多吗,以便告诉我的浏览器它需要尝试接受gzip文件?":好问题!不必更改压缩文件的名称,建议不要重命名。但是,你需要:

  • 必须设置头信息 "Content-Encoding:gzip",否则浏览器将无法识别文件。

  • 必须设置头信息 'Content-Type': type(type = 'application/javascript' 或者 'text/css')

  • 必须设置头信息 'x-amz-acl': 'public-read':使其公开可访问。

  • 我还建议设置头信息 "Cache-Control:max-age=TIME"(例如:TIME=31104000,表示360天):以帮助浏览器缓存文件(更好的性能)

无论是从源站还是通过CloudFront提供服务,这都可以正常工作。但请记住,如果您使用CloudFront提供服务,则需要在每次推送后使所有文件失效,否则旧版本将在推送后的24小时内继续存在。希望这可以帮到您,如果需要,我可以提供一个Python解决方案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接