Compactação

Automatizando minificação de CSS e Javascript em ASP.NET 1


Ola galeta, tudo bem?!

Hoje pretendo falar de um assunto que é relacionado a performace de aplicações web, mais precisamente falar sobre a técnica de minificação usada em arquivos *.css e *.js.

A minificação

É um processo onde é removido os caracteres desnecessários do arquivo, espaços em branco e quebras de linha que servem so para indentação do código não são necessárias para o consumo do mesmo em sua aplicação web, no caso do javascript algumas engines de minificação ainda vão mais alem, chegam a trocar nome das variáveis deixando-os mais curtos. Cada espaço, quebra de linha, caracteres em geral são bytes e ocupam espaço, e por que não remover esse espaço desnecessário?

Automatizando a minificação

Para essa demonstração eu vou criar um projeto ASP.NET MVC 3, mas você também pode usar para a versão 1,2 ou até mesmo Web Forms.

File > New > Project > Web > ASP.NET MVC 3 Web Application

selecionando nuget

Selecionando nuget

Selecione o gerenciador de pacotes Nuget, clicando com botão direito em “References”.

Pesquisando no nuget pelo YUI

Pesquisando no nuget pelo YUI

Apos a tela do gerenciador nuget abrir, procure por YUI, e instale o YUICompressor .NET(MsBuild Task) conforme mostra a figura ao lado.

Esse procedimento vai criar uma pasta packages detro da pasta raiz da sua solução, o caminho fica assim:
“DiretorioDaSolução”\packages\YUICompressor.NET-MsBuild-Task.1.6.0.2\lib\NET35

Dentro desse direitorio terá 3 dlls, são elas:

  • EcmaScript.NET.modified.dll
  • Yahoo.Yui.Compressor.dll
  • Yahoo.Yui.Compressor.MsBuildTask.dll

Cria uma pasta no seu projeto chama MSBuild e copie essas dlls para essa pasta.

Dentro da pasta MSBuild crie um arquivo XML com o nome de “MinificationConfiguration.xml”, lembrando que você pode usar qualquer nome, mas em um ponto mais a frente você vai ter que usar o nome do arquivo que você usou.

[xml]<xml? version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/MsBuild/2003">
<UsingTask TaskName="CompressorTask" AssemblyFile="Yahoo.Yui.Compressor.MsBuildTask.dll" />
<PropertyGroup>
<CssOutputFile Condition=" ‘$(CssOutputFile)’==” ">$(ProjectDir)..\Content\CssFinal.css</CssOutputFile>
<JavaScriptOutputFile Condition=" ‘$(JavaScriptOutputFile)’==” ">$(ProjectDir)..\Scripts\JsFinal.js</JavaScriptOutputFile>
</PropertyGroup>
<Target Name="MyTaskTarget">
<ItemGroup>
<CssFiles Include="’$(ProjectDir)’\..\..\Content\Site.css"/>
<JavaScriptFiles Include="’$(ProjectDir)’\..\..\Scripts\jquery-1.5.1.js"/>
</ItemGroup>
<CompressorTask
CssFiles="@(CssFiles)"
DeleteCssFiles="false"
CssOutputFile="$(CssOutputFile)"
CssCompressionType="YuiStockCompression"
JavaScriptFiles="@(JavaScriptFiles)"
ObfuscateJavaScript="True"
PreserveAllSemicolons="False"
DisableOptimizations="Nope"
EncodingType="Default"
DeleteJavaScriptFiles="false"
LineBreakPosition="-1"
JavaScriptOutputFile="$(JavaScriptOutputFile)"
LoggingType="ALittleBit"
ThreadCulture="en-eu"
IsEvalIgnored="false"
/>
</Target>
</Project>[/xml]

Nas linhas 5 e 6 eu defino o arquivo que vai ser gerado com a minificação do css(linha 5) e js(linha 6), vale lembrar que quando esses arquivos forem gerados apos o build, eles não vão aparecer no Visual Studio, você deve clicar no icone “Show all Files” no Solution Explorer achar o arquivo clicar com o botão direito no mesmo e selecionar “Include in Project”

É dentro do grupo ItemGroup que você vai referenciar quais arquivos Css e Js devem ser minificados e unidos, como você pode ver na linha 10 eu so fiz referência a um arquivo css e na 11 a um
arquivo JS.

Você também pode usar o *, por exemplo: <CssFiles Include="'$(ProjectDir)'\..\..\Content\*.css"/>, mas lembrando que mais uma vez você deve respeitar as dependências dos arquivos, so use esse recurso quando a ordem alfabética de seus arquivos for idêntica a ordem de dependência

É de extrema importância que você respeite a ordem dos scripts, dependências e etc, caso contrario terá problemas na aplicação.

Da linha 13 a 28 se encontra a tag CompressorTask que é a configuração de minificação, as opções são bem instintivas, abaixo segue um hint sobre as opções de configuração.

CssFiles/JavaScriptFiles data format: Não mecha.
DeleteCssFiles: [Opcional] True | Yes | Yeah | Yep | True | FoSho | Fo Sho. Padrão é false. Qualquer coisa vai ser false. (Ex: blah = false, xxxx111 = false, etc)
CssCompressionType: YuiStockCompression | MichaelAshsRegexEnhancements | HaveMyCakeAndEatIt or BestOfBothWorlds or Hybrid; Padrão é YuiStockCompression.
ObfuscateJavaScript: [Opcional] mesma regra do DeleteCssFiles.
PreserveAllSemicolons: [Opcional] mesma regra do DeleteCssFiles.
DisableOptimizations: [Opcional] mesma regra do DeleteCssFiles.
EncodingType: [Opcional] ASCII, BigEndianUnicode, Unicode, UTF32, UTF7, UTF8, Default. Padrão é 'Default'.
DeleteJavaScriptFiles: [Opcional] mesma regra do DeleteCssFiles.
LineBreakPosition: [Opcional] a posição onde uma alimentação de linha é appened quando o ponto e vírgula próxima é atingido. Padrão é -1 (nunca adicionar uma quebra de linha).
                    0 (zero) significa adicionar uma quebra de linha depois de cada ponto e vírgula. (Isto pode ajudar com a depuração arquivos problemáticos).
LoggingType: None | ALittleBit | HardcoreBringItOn;  Hardcore também lista os avisos javascript verbose, se houver algum (e normalmente há).
ThreadCulture: [Opcional] a cultura da thread que vai minificar. Padrão é 'en-gb'(eu não mudaria no código que passei :)).
IsEvalIgnored: [Opcional] comprimi qualquer função que tiver 'eval'. Padrão é False, o que significa uma função que contém
                'eval' NÃO será comprimido. É considerado arriscado para comprimir uma função contendo 'eval'. Dito isto,
                se os usos são considerados seguros esta verificação pode ser desativado por definir este valor para True.
PreserveCssComments: [Optional] mesma regra do DeleteCssFiles.

O ultimo passo agora é configura o evento post-build, nas propriedades do Projeto, clique em Build Events e em Post-Build event command line cole esse código:

$(MSBuildBinPath)\msbuild.exe "$(ProjectDir)MSBuild\MinificationConfiguration.xml"

Se você mudou o nome do arquivo xml você deve se lembrar de mudar aqui também. Feito isso a cada vez que você fizer um build os arquivos serão regerados 🙂

Você pode fazer um teste em seu site usando 2 programinhas para auxiliar na melhora da performace, são eles YSlow e PageSpeed
[sourcecode lang=”xml”]xml[/sourcecode]


sobre Alberto Monteiro

Desenvolvedor no Grupo Fortes, cuja principal área de conhecimento são em tecnologias Microsoft, como Windows Forms / Services, WPF, ASP.NET(MVC/WEB API), Windows Phone, EF. Gosta de sopa de letrinhas(SOLID, DDD, TDD, BDD, IoC, SoC, UoW), possui aplicações de Windows Phone publicadas no marketplace, já contribuiu no jQuery UI. Atualmente trabalha com ASP.NET MVC / Web API, Windows Azure, Amazon AWS, jQuery/UI, Knockout, EF, Ninject, AutoMapper, Restfulie, SignalR, KendoUI.

  • Tonbauru

    Parabéns Alberto pelo blog esta muito bom!

    abraços amigo