Autor: Rob Howard Tradução: Peixes tropicais
Este artigo discute:
· Segredos gerais de desempenho do ASP.NET
· Dicas e truques úteis para melhorar o desempenho do ASP.NET
· Recomendações para usar bancos de dados em ASP.NET
· Armazenamento em cache e processamento em segundo plano no ASP.NET
Escrever uma aplicação web usando ASP.NET é incrivelmente simples. É tão simples que muitos desenvolvedores não dedicam tempo para criar seus aplicativos para que tenham um bom desempenho. Neste artigo, recomendo 10 dicas para escrever aplicações web de alto desempenho. Não limitarei minha discussão aos aplicativos ASP.NET, porque os aplicativos ASP.NET são apenas um subconjunto de aplicativos Web. Este artigo não pretende ser um guia definitivo para otimizar o desempenho de aplicações web - um livro completo poderia facilmente fazer isso. Em vez disso, devemos considerar este artigo um bom ponto de partida.
Antes de me tornar um workaholic, eu praticava muito escalada. Antes de fazer qualquer escalada, prefiro consultar os percursos num guia de viagem e ler as recomendações de quem já esteve no cume. Mas não importa quão bem escrito seja um guia, você precisa de experiência real em escalada antes de tentar um objetivo desafiador. Da mesma forma, você só aprenderá a escrever aplicativos Web de alto desempenho quando tiver que resolver problemas de desempenho ou executar um site de alto rendimento.
Minha experiência pessoal vem de trabalhar como Gerente de Programa Básico na equipe ASP.NET da Microsoft, mantendo e gerenciando www.asp.net e ajudando a arquitetar o Community Server, um dos vários aplicativos ASP.NET conhecidos (Fóruns ASP.NET , .Text e nGallery conectados a uma plataforma). Tenho certeza que algumas dessas dicas que me ajudaram serão úteis para você também.
Você deve considerar separar seu aplicativo em diversas camadas lógicas. Você deve ter ouvido falar da arquitetura de 3 camadas (ou n camadas). Geralmente são padrões estruturais prescritos que dividem fisicamente o negócio e/ou hardware em divisões funcionais. Se o sistema exigir maior escala, mais hardware poderá ser facilmente adicionado. No entanto, isso produzirá uma degradação de desempenho associada a saltos nos negócios e nas máquinas, por isso devemos evitá-lo. Portanto, sempre que possível, tente executar a página ASP.NET e os componentes relacionados à página no mesmo aplicativo.
Devido à separação de código e aos limites entre as camadas, o uso de serviços Web ou a comunicação remota pode reduzir o desempenho em 20% ou mais.
A camada de dados é um pouco diferente porque normalmente é melhor ter hardware dedicado ao banco de dados. No entanto, o custo do salto do processo para o banco de dados ainda é alto, portanto, o desempenho na camada de dados deve ser sua primeira consideração ao otimizar seu código.
Antes de investir na correção dos problemas de desempenho do seu aplicativo, analise-o para descobrir a causa raiz do problema. Os principais contadores de desempenho (como aquele que indica a porcentagem de tempo gasto na coleta de lixo) também são muito úteis para descobrir onde o aplicativo passa a maior parte do tempo. Embora os locais onde o tempo é gasto sejam muitas vezes menos intuitivos.
Neste artigo discuto duas maneiras de melhorar o desempenho: otimizações em grande escala, como o uso de cache do ASP.NET, e otimizações em pequena escala, que são frequentemente repetidas. Essas pequenas peças de otimização às vezes são as mais interessantes. Uma pequena alteração feita em seu código será chamada milhares de vezes. Otimize grandes partes e você poderá encontrar um grande salto no desempenho geral. Ao otimizar em pequenos pedaços, você pode economizar alguns microssegundos de uma determinada solicitação, mas cumulativamente em todas as solicitações por dia, obterá uma melhoria inesperada no desempenho.
Desempenho na camada de dados
Quando você começa a otimizar o desempenho de uma aplicação, há um teste decisivo que você pode priorizar: o código precisa acessar um banco de dados? Se sim, com que frequência você visita? Observe que esse teste também pode ser aplicado a códigos que usam serviços da Web ou controle remoto, mas não abordarei isso neste artigo.
Se uma solicitação de banco de dados for necessária em um determinado caminho de código e você encontrar outros locais onde deseja priorizar otimizações, como manipulação de string, pare e execute os testes críticos primeiro. A menos que você tenha um problema de desempenho muito ruim para resolver, seu tempo será melhor gasto otimizando o tempo necessário para se conectar ao banco de dados, a quantidade de dados retornados e as operações que você realiza no banco de dados.
Agora que cobri as informações em geral, vamos dar uma olhada em 10 dicas para ajudar seu aplicativo a ter um melhor desempenho. Começarei com aqueles que têm o impacto mais óbvio na melhoria do desempenho.
Dica 1 – Retorne vários conjuntos de resultados
Dê uma olhada no código do seu banco de dados para ver se você possui caminhos de solicitação que acessam o banco de dados mais de uma vez. Cada viagem de ida e volta reduz o número de solicitações que seu aplicativo pode atender por segundo. Ao retornar vários conjuntos de resultados em uma única solicitação de banco de dados, você pode reduzir o tempo total consumido pela comunicação do banco de dados. Depois de reduzir o número de solicitações que seu servidor de banco de dados precisa gerenciar, você também torna seu sistema mais escalável.
Geralmente você pode usar instruções SQL dinâmicas para retornar vários conjuntos de resultados. Prefiro usar procedimentos armazenados. É discutível se você deve colocar lógica de negócios em um procedimento armazenado, mas acho que se a lógica em um procedimento armazenado pode limitar os dados retornados (reduz o tamanho do conjunto de dados, o tempo gasto na conexão de rede e elimina a necessidade de filtrar dados da camada lógica), então é uma coisa boa.
Usando uma instância SqlCommand e seu método ExecuteReader para gerar uma classe de negócios fortemente tipada, você pode mover o ponteiro do conjunto de resultados para frente chamando NextResult. A Figura 1 mostra um exemplo de sessão que usa uma classe definida para gerar vários ArrayLists. Retornar apenas os dados necessários do banco de dados reduzirá significativamente as solicitações de memória em seu servidor.
1 // leia o primeiro conjunto de resultados
2leitor = comando.ExecuteReader();
3
4 // lê os dados desse conjunto de resultados
5while (leitor.Read()) {
6 fornecedores.Add(PopulateSupplierFromIDataReader(leitor));
7}
8
9 // leia o próximo conjunto de resultados
10leitor.NextResult();
11
12 // lê os dados desse segundo conjunto de resultados
13while (leitor.Read()) {
14 produtos.Add(PopulateProductFromIDataReader(leitor));
15}
16
17
Dica 2 – Acesso a dados paginados
O DataGrid do ASP.NET oferece um grande recurso: suporte para paginação de dados. Quando a paginação é configurada no DataGrid, um número específico de resultados será exibido por vez. Além disso, uma UI de paginação para navegar entre os resultados é exibida na parte inferior do DataGrid. A IU paginada permite navegar para frente ou para trás nos dados exibidos, exibindo um número específico de resultados por página.
Mas há um pequeno problema. Ao usar o DataGrid para paginação, todos os dados precisam estar vinculados à tabela. Por exemplo, sua camada de dados precisará retornar todos os dados e, em seguida, o DataGrid precisará preencher todos os registros para serem exibidos com base na página atual. Se 100.000 registros forem retornados quando você usar a paginação do DataGrid, 99.975 registros serão descartados por solicitação (assumindo que a capacidade de cada página seja de 25 registros). Quando o número de registros aumenta, o desempenho da aplicação é bastante afetado porque cada vez mais dados devem ser retornados a cada solicitação.
Uma maneira de escrever um código de paginação melhor é usar procedimentos armazenados. A Figura 2 mostra um exemplo de procedimento armazenado que pagina a tabela de dados Orders no banco de dados Nothwind. Basicamente, tudo que você precisa fazer aqui é passar o índice da página e a capacidade da página. O banco de dados calcula os conjuntos de resultados apropriados e os retorna.
1CRIAR PROCEDIMENTO northwind_OrdersPaged
2(
3@PageIndexint,
4@PageSizeint
5)
6AS
7 COMEÇAR
8DECLARE @PageLowerBoundint
9DECLARE @PageUpperBound int
10DECLARE @RowsToReturnint
11
12-- Primeiro defina o número de linhas
13SET @RowsToReturn = @PageSize * (@PageIndex + 1)
14SET ROWCOUNT @RowsToReturn
15
16--Defina os limites da página
17SET @PageLowerBound = @PageSize * @PageIndex
18SET @PageUpperBound = @PageLowerBound + @PageSize + 1
19
20-- Crie uma tabela temporária para armazenar os resultados selecionados
21CRIAR TABELA #PageIndex
vinte e dois(
23 IndexId int IDENTIDADE (1, 1) NÃO NULO,
24 ID do pedido interno
25)
26
27--Inserir na tabela temporária
28INSERT EM #PageIndex (OrderID)
29SELECIONE
30 ID do pedido
31DE
32 pedidos
33ENCOMENDAR POR
34 ID do pedido DESC
35
36--Retornar contagem total
37SELECIONE COUNT(OrderID) FROM Pedidos
38
39-- Retornar resultados paginados
40SELECIONAR
41 O.*
42DE
43 Ordens Ó,
44 #PageIndex PáginaIndex
45 ONDE
46 O.OrderID = PageIndex.OrderID E
47 PageIndex.IndexID > @PageLowerBound E
48 PageIndex.IndexID <@PageUpperBound
49ENCOMENDAR POR
50 PageIndex.IndexID
51
52 FIM
53
54
Durante o período de serviço comunitário, escrevemos um controle de servidor de paginação para fazer essa paginação de dados. Você notará que usei a ideia discutida na Dica 1 para retornar dois conjuntos de resultados de um procedimento armazenado: o número total de registros e os dados solicitados.
O número total de registros retornados pode variar dependendo da solicitação realizada. Por exemplo, uma cláusula WHERE pode ser usada para restringir os dados retornados. Devemos saber o número total de registros a serem retornados para calcular o número total de páginas a serem exibidas na IU paginada. Por exemplo, se houver um total de 1.000.000 registros e uma cláusula WHERE for usada para filtrar esses registros para 1.000 registros, a lógica de paginação precisará saber o número total de registros para enviar a UI de paginação adequadamente.
Dica 3 – Pool de conexões
Estabelecer uma conexão TCP entre seu aplicativo Web e o SQL Server pode ser uma operação cara. Os desenvolvedores da Microsoft já utilizam o pool de conexões há algum tempo, permitindo-lhes reutilizar conexões com bancos de dados. Em vez de estabelecer uma nova conexão TCP para cada solicitação, uma nova conexão será estabelecida somente quando não houver nenhuma conexão disponível no pool de conexões. Quando a conexão é fechada, ela retorna ao pool de conexões - ela ainda mantém a conexão com o banco de dados, em vez de destruir completamente a conexão TCP.
Claro que você precisa ter cuidado com conexões vazadas. Sempre feche suas conexões quando terminar de usá-las. Repito: não importa o que alguém diga sobre o mecanismo de coleta de lixo do Microsoft .NET Framework, você deve sempre chamar explicitamente o método Close ou Dispose em sua conexão quando terminar de usá-lo. Não confie no Common Language Runtime (CLR) para limpar e fechar sua conexão em um horário predeterminado. O CLR eventualmente destruirá a classe e forçará o fechamento da conexão, mas você não tem garantia de quando o mecanismo de coleta de lixo no objeto será realmente executado.
Para obter os melhores resultados usando o pool de conexões, você precisa seguir algumas regras. Primeiro, abra uma conexão, faça o trabalho e depois feche a conexão. Não tem problema se você tiver que (de preferência aplicando a dica 1) abrir e fechar a conexão diversas vezes por requisição, é muito melhor do que deixar a conexão aberta e passá-la para vários métodos diferentes. Segundo, use a mesma cadeia de conexão (e, claro, o mesmo ID de thread se estiver usando autenticação integrada). Se você não usar a mesma cadeia de conexão, por exemplo, cadeias de conexão personalizadas diferentes com base no usuário conectado, você não obterá o mesmo valor ideal que o pool de conexões fornece. E se você usar autenticação integrada ao representar um grande número de usuários, seu pool de conexões também será muito menos eficiente. Os contadores de desempenho de dados .NET CLR podem ser úteis ao tentar rastrear quaisquer problemas de desempenho relacionados ao pool de conexões.
Sempre que seu aplicativo se conectar a um recurso, como um banco de dados, ou for executado em outro processo, você deverá fazer isso concentrando-se no tempo que leva para se conectar ao recurso, no tempo que leva para enviar e receber dados e no tempo que leva para se conectar ao recurso. leva para enviar e receber dados Há uma série de viagens de ida e volta ao banco de dados para otimizar. Otimizar qualquer tipo de salto de processo em seu aplicativo é o primeiro passo para começar a obter melhor desempenho.
A camada de aplicação contém a lógica que se conecta à sua camada de dados e transforma os dados em instâncias de classe e processos lógicos significativos. Por exemplo, em um servidor de comunidade, é aqui que você gera um fórum ou uma coleção de threads e aplica regras de negócios, como permissões. Mais importante ainda, é aqui que a lógica de cache é executada;
Dica 4 – API de buffer ASP.NET
A primeira coisa a considerar antes de começar a escrever a primeira linha de código em seu aplicativo é arquitetar a camada do aplicativo para maximizar e aproveitar os recursos de cache do ASP.NET.
Se o seu componente for executado em um aplicativo ASP.NET, basta fazer referência a System.Web.dll no projeto do seu aplicativo. Quando precisar acessar o cache, utilize a propriedade HttpRuntime.Cache (este objeto também pode ser acessado através de Page.Cache e HttpContext.Cache).
Existem várias diretrizes para usar dados armazenados em cache. Primeiro, se os dados puderem ser usados várias vezes, armazená-los em cache é uma boa escolha. Em segundo lugar, se os dados forem gerais e não específicos de uma solicitação ou usuário específico, armazená-los em cache é uma ótima opção. Se os dados forem específicos do usuário ou da solicitação, mas tiverem uma vida útil longa, eles poderão ser armazenados em cache, mas não poderão ser usados com frequência. Terceiro, um princípio frequentemente esquecido é que às vezes você pode armazenar muito em cache. Normalmente, em uma máquina x86, para reduzir a probabilidade de erros de falta de memória, você desejará executar um processo que não use mais do que 800 MB de bytes privados. Portanto, o cache deve ser limitado. Em outras palavras, talvez seja necessário reutilizar o resultado de um cálculo, mas se esse cálculo exigir dez parâmetros, talvez seja necessário tentar armazenar em cache 10 permutações, e isso poderá causar problemas. Erros de falta de memória devido ao overcaching são os mais comuns no ASP.NET, especialmente com grandes conjuntos de dados.
O cache tem vários recursos excelentes que você precisa conhecer. Primeiro, o cache implementa um algoritmo usado menos recentemente, permitindo que o ASP.NET force a liberação do cache — removendo automaticamente itens não utilizados do cache — quando a memória está sendo executada com menos eficiência. Segundo, o cache suporta dependências expiradas que podem ser forçadas a expirar. Essas dependências incluem tempo, chaves e arquivos. O tempo é frequentemente usado, mas com o ASP.NET 2.0, um novo e mais poderoso tipo de invalidação é introduzido: invalidação de cache de banco de dados. Refere-se à exclusão automática de itens do cache quando os dados do banco de dados são alterados. Para obter mais informações sobre invalidação de cache de banco de dados, consulte a coluna Dino Esposito Cutting Edge na edição de julho de 2004 da MSDN Magazine. Para entender a arquitetura do cache, consulte a Figura 3.
Dica 5 – Cache por solicitação
Anteriormente neste artigo, mencionei que pequenas melhorias em caminhos de código percorridos com frequência podem levar a grandes ganhos gerais de desempenho. Dessas pequenas melhorias, uma é definitivamente a minha favorita e eu a chamo de cache por solicitação.
As APIs de armazenamento em cache são projetadas para armazenar dados em cache por um longo período de tempo ou até que determinadas condições sejam atendidas, mas o armazenamento em cache por solicitação significa armazenar dados em cache apenas durante a solicitação. Para cada solicitação, um caminho de código específico é acessado frequentemente, mas os dados são extraídos, aplicados, modificados ou atualizados apenas uma vez. Isso parece um pouco teórico, então vamos dar um exemplo concreto.
Em um aplicativo de fórum de servidor comunitário, cada controle de servidor usado na página requer dados de personalização para determinar qual aparência usar, qual tabela de estilo usar e outros dados de personalização. Alguns desses dados podem ser armazenados em cache a longo prazo, mas alguns dados são buscados apenas uma vez por solicitação e reutilizados diversas vezes durante essa solicitação, como para a aparência de um controle.
Para obter cache por solicitação, use ASP.NET HttpContext. Para cada solicitação, uma instância HttpContext é criada e pode ser acessada de qualquer lugar dentro da propriedade HttpContext.Current durante a solicitação. A classe HttpContext possui uma propriedade especial da coleção Items e os dados adicionados a essa coleção Items são armazenados em cache apenas durante a solicitação. Assim como você pode usar o cache para armazenar dados acessados com frequência, você também pode usar HttpContext.Items para armazenar dados que são usados apenas por solicitação. A lógica por trás disso é muito simples: os dados são adicionados à coleção HttpContext.Items quando ela não existe e, em pesquisas subsequentes, apenas os dados em HttpContext.Items são retornados.
Dica 6 – Processamento em segundo plano
O caminho para o código deve ser o mais rápido possível, certo? Pode haver momentos em que você descobrirá que está executando uma tarefa que consome muitos recursos e que é executada em cada solicitação ou em cada n solicitações. Enviar e-mails ou analisar e validar dados recebidos são alguns exemplos.
Ao dissecar os Fóruns ASP.NET 1.0 e reprojetar o conteúdo que compõe o servidor da comunidade, descobrimos que o caminho do código para publicação de novas postagens era extremamente lento. Cada vez que uma nova postagem é publicada, o aplicativo primeiro precisa garantir que não há postagens duplicadas, depois deve analisar a postagem usando um filtro de "palavrões", analisar os emoticons dos personagens da postagem, marcar e indexar a postagem e adicionar o poste na solicitação quando solicitado. Adicione à fila apropriada, valide o anexo e, finalmente, envie uma notificação por e-mail a todos os assinantes imediatamente após a publicação da postagem. Claramente, há muita coisa envolvida.
Após pesquisa, constatou-se que a maior parte do tempo era gasto na indexação da lógica e no envio de e-mails. A indexação de postagens é uma operação muito demorada e foi descoberto que a funcionalidade System.Web.Mail integrada se conecta a um servidor SMTP e envia e-mails continuamente. À medida que o número de assinantes de uma determinada postagem ou área de tópico aumenta, a função AddPost leva cada vez mais tempo para ser executada.
A indexação de email não é necessária para todas as solicitações. Idealmente, gostaríamos de agrupar essa operação, indexando 25 postagens por vez ou enviando todos os e-mails a cada cinco minutos. Decidimos usar o código que eu usei para criar o protótipo da invalidação do cache de dados que acabou sendo incluída no Visual Studio 2005.
A classe Timer no namespace System.Threading é muito útil, mas não muito conhecida no .NET Framework, pelo menos entre os desenvolvedores da Web. Uma vez criada, esta classe Timer chamará o retorno de chamada especificado em um intervalo configurável para um thread no ThreadPool. Isso significa que você pode configurar seu código para ser executado sem solicitações recebidas no aplicativo ASP.NET, o que é ideal para processamento em segundo plano. Você também pode realizar operações como indexação ou envio de e-mails neste processo em segundo plano.
No entanto, existem vários problemas com esta tecnologia. Se o domínio do aplicativo for desinstalado, esta instância de timer irá parar de disparar eventos. Além disso, como o CLR tem um padrão rígido para o número de threads por processo, pode haver uma situação em um servidor muito carregado em que o temporizador pode não garantir que os threads continuem a concluir a operação e, até certo ponto, pode causar atrasos . O ASP.NET tenta minimizar a chance de isso acontecer, mantendo um certo número de threads disponíveis no processo e usando apenas uma parte do total de threads para processamento de solicitações. No entanto, isso pode ser um problema se você tiver muitas operações assíncronas.
Não há espaço suficiente aqui para esse código, mas você pode baixar um exemplo fácil de entender em www.rob-howard.net . Confira os slides e demonstrações da apresentação Blackbelt TechEd 2004.
Dica 7 – Cache de saída de página e servidores proxy
ASP.NET é sua camada de apresentação (ou deveria ser sua camada de apresentação); consiste em páginas, controles de usuário, controles de servidor (HttpHandlers e HttpModules) e o conteúdo que eles geram. Se você tem uma página ASP.NET que gera saída (HTML, XML, imagens ou qualquer outro dado) e quando você executa esse código em cada solicitação ele gera a mesma saída, então você tem uma ferramenta que pode ser usada para ASP.NET ótima alternativa para cache de saída de página.
Adicionando a seguinte linha ao topo da página:
<%@ Page OutputCache VaryByParams="none" Duration="60" %>
Você pode gerar efetivamente a saída para esta página uma vez e reutilizá-la várias vezes por até 60 segundos, momento em que a página será executada novamente e a saída será adicionada ao cache do ASP.NET novamente. Esse comportamento também pode ser realizado usando algumas APIs programáveis de baixo nível. Existem várias configurações configuráveis para cache de saída, como a propriedade VaryByParams que acabamos de mencionar. VaryByParams é apenas solicitado, mas também permite especificar parâmetros HTTP GET ou HTTP POST para alterar entradas de cache. Por exemplo, basta definir VaryByParam="Report" para armazenar em cache a saída para default.aspx?Report=1 ou default.aspx?Report=2. Parâmetros adicionais podem ser especificados especificando uma lista separada por ponto e vírgula.
Muitas pessoas não percebem que quando o cache de saída é usado, as páginas ASP.NET também geram cabeçalhos HTTP que fluem para servidores de cache, como aqueles usados pelo Microsoft Internet Security and Acceleration Server ou Akamai. Depois de definir o cabeçalho da tabela de cache HTTP, os documentos podem ser armazenados em cache nesses recursos de rede e as solicitações do cliente podem ser atendidas sem retornar ao servidor de origem.
Portanto, usar o cache de saída de página não tornará seu aplicativo mais eficiente, mas poderá reduzir a carga no servidor porque a tecnologia de cache downstream armazena o documento em cache. Claro, isso só pode ser conteúdo anônimo; uma vez que vai para o downstream, você nunca mais verá as solicitações e não poderá mais realizar autenticação para impedir o acesso a ele.
Dica 8 — Execute o IIS 6.0 (mesmo que seja apenas para usar o cache do kernel)
Se você não estiver executando o IIS 6.0 (Windows Server 2003), estará perdendo alguns ótimos aprimoramentos de desempenho nos servidores Web da Microsoft. Na Dica 7, discuti o cache de saída. No IIS 5.0, as solicitações passam pelo IIS e depois pelo ASP.NET. Quando se trata de cache, o HttpModule no ASP.NET recebe a solicitação e retorna o conteúdo do cache.
Se você estiver usando o IIS 6.0, encontrará um pequeno recurso interessante chamado cache do kernel que não requer nenhuma alteração de código no ASP.NET. Quando é feita uma solicitação de cache de saída pelo ASP.NET, o cache do kernel do IIS recebe uma cópia dos dados armazenados em cache. Quando uma solicitação vem de um driver de rede, o driver em nível de kernel (sem mudança de contexto para o modo de usuário) recebe a solicitação, libera os dados armazenados em cache para a resposta, se estiver em cache, e então conclui a execução. Isso significa que ao usar o cache no modo kernel com cache de saída IIS e ASP.NET, você verá resultados de desempenho incríveis. Durante o desenvolvimento do ASP.NET no Visual Studio 2005, fui o gerente de desenvolvimento responsável pelo desempenho do ASP.NET. Os desenvolvedores fazem o trabalho específico, mas posso ver todos os relatórios que acontecem todos os dias. Os resultados do cache do modo kernel são sempre os mais interessantes. A característica mais comum é que a rede está inundada com solicitações/respostas, enquanto o IIS está rodando com apenas cerca de 5% de uso da CPU. Isso é chocante! É claro que existem outros motivos para usar o IIS 6.0, mas o cache no modo kernel é o mais óbvio.
Dica 9 – Use compactação Gzip
Embora o uso do gzip não seja necessariamente um truque de desempenho do servidor (já que você pode observar um aumento no uso da CPU), o uso da compactação gzip pode reduzir o número de bytes enviados pelo servidor. Isso resulta em um aumento percebido na velocidade da página e redução no uso da largura de banda. Dependendo dos dados que estão sendo enviados, quão compressíveis eles podem ser e se o navegador do cliente os suporta (o IIS só enviará conteúdo compactado com gzip para clientes que suportam compactação gzip, como Internet Explorer 6.0 e Firefox), seu servidor pode servir Mais solicitações. Na verdade, quase sempre que você reduz a quantidade de dados retornados, você aumenta o número de solicitações por segundo.
A compactação Gzip está integrada ao IIS 6.0 e seu desempenho é muito melhor do que a compactação gzip usada no IIS 5.0, o que é uma boa notícia. Infelizmente, ao tentar ativar a compactação gzip no IIS 6.0, talvez você não consiga encontrar a configuração na caixa de diálogo Propriedades do IIS. A equipe do IIS incorporou uma excelente funcionalidade gzip no servidor, mas esqueceu de incluir uma UI administrativa para habilitá-la. Para ativar a compactação gzip, você precisa se aprofundar nas definições de configuração XML do IIS 6.0 (para não ficar com o coração fraco). Aliás, o crédito vai para Scott Forsyth da OrcsWeb por me ajudar a levantar esta questão com o servidor www.asp.net hospedado na OrcsWeb.
Este artigo não descreverá as etapas. Leia o artigo de Brad Wilson em IIS6 Compression. Há também um artigo da base de conhecimento sobre como habilitar a compactação para ASPX em Habilitar compactação ASPX no IIS. Você deve observar, entretanto, que devido a alguns detalhes de implementação, a compactação dinâmica e o cache do kernel não podem existir simultaneamente no IIS 6.0.
Dica 10 – Estado de visualização do controle do servidor
View state é um nome interessante para ASP.NET que armazena alguns dados de estado em campos de saída ocultos da página gerada. Quando a página é enviada de volta ao servidor, o servidor pode analisar, validar e aplicar esses dados de estado de visualização de volta à árvore de controle da página. Visualizar estado é um recurso muito poderoso porque permite que o estado seja persistido com o cliente e não requer cookies ou memória do servidor para salvar esse estado. Muitos controles de servidor ASP.NET usam o estado de exibição para persistir configurações criadas durante interações com elementos de página, como salvar a página atual exibida durante a paginação de dados.
No entanto, usar o estado de visualização também tem algumas desvantagens. Primeiro, aumenta a carga geral da página quando ela é veiculada ou solicitada. A sobrecarga adicional também ocorre ao serializar ou desserializar dados de estado de exibição enviados de volta ao servidor. Finalmente, o estado de visualização aumenta a alocação de memória no servidor.
Vários controles de servidor tendem a usar excessivamente o estado de visualização, mesmo quando não é necessário, sendo o mais notável o DataGrid. O comportamento padrão da propriedade ViewState está ativado, mas você pode desativá-lo no nível do controle ou da página se não precisar dele. Dentro do controle, basta definir a propriedade EnableViewState como false ou defini-la globalmente na página usando a seguinte configuração:
<%@Página EnableViewState="false" %>
Se você não postar de volta a página ou sempre gerar novamente os controles na página em cada solicitação, você deverá desabilitar o estado de visualização no nível da página.
resumo
Dei algumas dicas que considero úteis ao escrever aplicativos ASP.NET de alto desempenho. Como mencionei anteriormente neste artigo, este é um guia preliminar e não a palavra final sobre o desempenho do ASP.NET. (Para obter informações sobre como melhorar o desempenho de aplicativos ASP.NET, consulte Melhorando o desempenho do ASP.NET.) A melhor maneira de resolver um problema de desempenho específico só pode ser encontrada por meio de sua própria experiência. No entanto, essas dicas devem fornecer uma boa orientação em sua jornada. No desenvolvimento de software, existem poucos valores absolutos; cada aplicativo é único.
Consulte a barra lateral "Mitos comuns sobre desempenho".
Rob Howard é o fundador da Telligent Systems, especializada em aplicações Web de alto desempenho, gerenciamento de base de conhecimento e sistemas de colaboração. Rob trabalhou anteriormente na Microsoft, onde ajudou a projetar a infraestrutura para ASP.NET 1.0, 1.1 e 2.0. Para entrar em contato com Rob, visite [email protected] .
Link original: http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx