Condividi tramite


Miglioramento delle prestazioni con la cache di output (VB)

da Microsoft

In questa esercitazione si apprenderà come migliorare notevolmente le prestazioni delle applicazioni Web ASP.NET MVC sfruttando la memorizzazione nella cache di output. Si apprenderà come memorizzare nella cache il risultato restituito da un'azione del controller in modo che lo stesso contenuto non debba essere creato ogni e ogni volta che un nuovo utente richiama l'azione.

L'obiettivo di questa esercitazione è spiegare come è possibile migliorare notevolmente le prestazioni di un'applicazione MVC ASP.NET sfruttando la cache di output. La cache di output consente di memorizzare nella cache il contenuto restituito da un'azione del controller. In questo modo, lo stesso contenuto non deve essere generato ogni e ogni volta che viene richiamata la stessa azione controller.

Si supponga, ad esempio, che l'applicazione MVC ASP.NET visualizzi un elenco di record di database in una vista denominata Index. Normalmente, ogni e ogni volta che un utente richiama l'azione controller che restituisce la visualizzazione Indice, il set di record di database deve essere recuperato dal database eseguendo una query di database.

Se, d'altra parte, si sfrutta la cache di output, è possibile evitare di eseguire una query di database ogni volta che qualsiasi utente richiama la stessa azione del controller. La visualizzazione può essere recuperata dalla cache anziché rigenerata dall'azione del controller. La memorizzazione nella cache consente di evitare di eseguire operazioni ridondanti nel server.

Abilitazione della memorizzazione nella cache di output

È possibile abilitare la memorizzazione nella cache dell'output aggiungendo un <attributo OutputCache> a un'azione del controller singolo o a un'intera classe controller. Ad esempio, il controller nell'elenco 1 espone un'azione denominata Index(). L'output dell'azione Index() viene memorizzato nella cache per 10 secondi.

Elenco 1 - Controller\HomeController.vb

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    <OutputCache(Duration:=10, VaryByParam:="none")> _
    Function Index()
        Return View()
    End Function

End Class

Nelle versioni beta di ASP.NET MVC la memorizzazione nella cache dell'output non funziona per un URL come http://www.MySite.com/. È invece necessario immettere un URL come 'http://www.MySite.com/Home/Index'.

Nell'elenco 1 l'output dell'azione Index() viene memorizzato nella cache per 10 secondi. Se si preferisce, è possibile specificare una durata della cache molto più lunga. Ad esempio, se si vuole memorizzare nella cache l'output di un'azione del controller per un giorno, è possibile specificare una durata della cache di 86400 secondi (60 secondi * 60 minuti * 24 ore).

Non è garantito che il contenuto venga memorizzato nella cache per il tempo specificato. Quando le risorse di memoria diventano basse, la cache avvia automaticamente l'eliminazione del contenuto.

Il controller Home nell'elenco 1 restituisce la visualizzazione Indice nell'elenco 2. Non c'è nulla di speciale su questa vista. La visualizzazione Indice visualizza semplicemente l'ora corrente (vedere la figura 1).

Presentazione 2 : Views\Home\Index.aspx

<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <div>
    
    The current time is: <%= DateTime.Now.ToString("T") %>
    
    </div>
</body>
</html>

Figura 1 - Visualizzazione indice memorizzata nella cache

clip_image002

Se si richiama l'azione Index() più volte immettendo l'URL /Home/Index nella barra degli indirizzi del browser e premendo ripetutamente il pulsante Aggiorna/Ricarica nel browser, l'ora visualizzata dalla visualizzazione Indice non cambierà per 10 secondi. La stessa volta viene visualizzata perché la visualizzazione viene memorizzata nella cache.

È importante comprendere che la stessa visualizzazione viene memorizzata nella cache per tutti gli utenti che visitano l'applicazione. Chiunque richiama l'azione Index() otterrà la stessa versione memorizzata nella cache della visualizzazione Indice. Ciò significa che la quantità di lavoro che il server Web deve eseguire per servire la visualizzazione Indice è notevolmente ridotta.

La visualizzazione nell'elenco 2 sta facendo qualcosa di veramente semplice. La visualizzazione visualizza solo l'ora corrente. Tuttavia, è possibile memorizzare facilmente nella cache una visualizzazione che visualizza un set di record di database. In tal caso, il set di record di database non deve essere recuperato dal database ogni e ogni volta che viene richiamata l'azione del controller che restituisce la visualizzazione. La memorizzazione nella cache può ridurre la quantità di lavoro che deve essere eseguita sia dal server Web che dal server di database.

Non usare la direttiva <%@ OutputCache %> in una visualizzazione MVC. Questa direttiva sta sanguinando dal mondo Web Forms e non deve essere usata in un'applicazione MVC ASP.NET.

Dove il contenuto viene memorizzato nella cache

Per impostazione predefinita, quando si usa l'attributo OutputCache>, il <contenuto viene memorizzato nella cache in tre posizioni: il server Web, tutti i server proxy e il Web browser. È possibile controllare esattamente dove il contenuto viene memorizzato nella cache modificando la proprietà Location dell'attributo <OutputCache> .

È possibile impostare la proprietà Location su uno dei valori seguenti:

· Qualsiasi

· Client

· Downstream

· Server

· Nessuno

· ServerAndClient

Per impostazione predefinita, la proprietà Location ha il valore Any. Tuttavia, esistono situazioni in cui è possibile memorizzare nella cache solo il browser o solo nel server. Ad esempio, se si memorizzano nella cache le informazioni personalizzate per ogni utente, non è consigliabile memorizzare nella cache le informazioni sul server. Se si visualizzano informazioni diverse a utenti diversi, è necessario memorizzare nella cache le informazioni solo sul client.

Ad esempio, il controller nell'elenco 3 espone un'azione denominata GetName() che restituisce il nome utente corrente. Se Jack accede al sito Web e richiama l'azione GetName(), l'azione restituisce la stringa "Hi Jack". Se, successivamente, Jill accede al sito Web e richiama l'azione GetName(), riceverà anche la stringa "Hi Jack". La stringa viene memorizzata nella cache nel server Web per tutti gli utenti dopo che Jack richiama inizialmente l'azione del controller.

Elenco 3 - Controller\BadUserController.vb

Public Class BadUserController
    Inherits System.Web.Mvc.Controller

    <OutputCache(Duration:=3600, VaryByParam:="none")> _
    Function Index()
        Return "Hi " & User.Identity.Name
    End Function

End Class

Probabilmente, il controller nell'elenco 3 non funziona come si vuole. Non si vuole visualizzare il messaggio "Hi Jack" a Jill.

Non è mai necessario memorizzare nella cache del server contenuto personalizzato. Tuttavia, è possibile memorizzare nella cache il contenuto personalizzato nella cache del browser per migliorare le prestazioni. Se si memorizza nella cache il contenuto nel browser e un utente richiama l'azione del controller più volte, il contenuto può essere recuperato dalla cache del browser anziché dal server.

Il controller modificato nella lista 4 memorizza nella cache l'output dell'azione GetName(). Tuttavia, il contenuto viene memorizzato nella cache solo nel browser e non nel server. In questo modo, quando più utenti richiamano il metodo GetName(), ogni persona ottiene il proprio nome utente e non il nome utente di un'altra persona.

Elenco 4 - Controller\UserController.vb

Public Class UserController
    Inherits System.Web.Mvc.Controller

    <OutputCache(Duration:=3600, VaryByParam:="none", Location:=OutputCacheLocation.Client, NoStore:=True)> _
    Function GetName()
        Return "Hi " & User.Identity.Name
    End Function

End Class

Si noti che l'attributo <OutputCache in List 4 include una proprietà Location impostata sul valore OutputCacheLocation.Client> . L'attributo <OutputCache> include anche una proprietà NoStore. La proprietà NoStore viene usata per informare i server proxy e i browser che non devono archiviare una copia permanente del contenuto memorizzato nella cache.

Variabile della cache di output

In alcune situazioni, è possibile che si vogliano versioni memorizzate nella cache diverse dello stesso contenuto. Si supponga, ad esempio, di creare una pagina master/dettaglio. La pagina master visualizza un elenco di titoli del film. Quando si fa clic su un titolo, si ottengono i dettagli per il film selezionato.

Se si memorizza nella cache la pagina dei dettagli, i dettagli per lo stesso film verranno visualizzati indipendentemente dal film che si fa clic. Il primo filmato selezionato dal primo utente verrà visualizzato a tutti gli utenti futuri.

È possibile risolvere questo problema sfruttando la proprietà VaryByParam dell'attributo <OutputCache> . Questa proprietà consente di creare versioni memorizzate nella cache diverse dello stesso contenuto quando un parametro di modulo o un parametro stringa di query varia.

Ad esempio, il controller nell'elenco 5 espone due azioni denominate Master() e Details(). L'azione Master() restituisce un elenco di titoli del film e l'azione Details() restituisce i dettagli per il film selezionato.

Elenco 5 - Controller\MoviesController.vb

Public Class MoviesController
    Inherits System.Web.Mvc.Controller

    Private _dataContext As MovieDataContext

    Public Sub New()
        _dataContext = New MovieDataContext()
    End Sub

    <OutputCache(Duration:=Integer.MaxValue, VaryByParam:="none")> _
    Public Function Master()
        ViewData.Model = (From m In _dataContext.Movies _
                          Select m).ToList()
        Return View()
    End Function

    <OutputCache(Duration:=Integer.MaxValue, VaryByParam:="id")> _
    Public Function Details(ByVal id As Integer)
        ViewData.Model = _dataContext.Movies.SingleOrDefault(Function(m) m.Id = id)
        Return View()
    End Function

End Class

L'azione Master() include una proprietà VaryByParam con il valore "nessuno". Quando viene richiamata l'azione Master(), viene restituita la stessa versione memorizzata nella cache della visualizzazione Master. Tutti i parametri della stringa di modulo o delle stringhe di query vengono ignorati (vedere la figura 2).

Figura 2 : visualizzazione /Movies/Master

clip_image004

Figura 3 : visualizzazione /Movies/Dettagli

clip_image006

L'azione Details() include una proprietà VaryByParam con il valore "ID". Quando vengono passati valori diversi del parametro Id all'azione controller, vengono generate versioni cache diverse della visualizzazione Dettagli.

È importante comprendere che l'uso della proprietà VaryByParam comporta una maggiore memorizzazione nella cache e non meno. Viene creata una versione diversa memorizzata nella cache della visualizzazione Dettagli per ogni versione diversa del parametro ID.

È possibile impostare la proprietà VaryByParam sui valori seguenti:

* = Creare una versione memorizzata nella cache diversa ogni volta che un parametro di una maschera o di una stringa di query varia.

none = Non creare mai versioni memorizzate nella cache diverse

Elenco di parametri con punto e virgola = Creare versioni memorizzate nella cache diverse ogni volta che uno dei parametri della maschera o della stringa di query nell'elenco varia

Creazione di un profilo cache

In alternativa alla configurazione delle proprietà della cache di output modificando le proprietà dell'attributo <OutputCache> , è possibile creare un profilo della cache nel file di configurazione Web (web.config). La creazione di un profilo di cache nel file di configurazione Web offre un paio di vantaggi importanti.

Prima di tutto, configurando la memorizzazione nella cache di output nel file di configurazione Web, è possibile controllare il modo in cui le azioni del controller memorizzano nella cache il contenuto in un'unica posizione centrale. È possibile creare un profilo della cache e applicare il profilo a diverse azioni controller o controller.

In secondo luogo, è possibile modificare il file di configurazione Web senza ricompilare l'applicazione. Se è necessario disabilitare la memorizzazione nella cache per un'applicazione già distribuita nell'ambiente di produzione, è sufficiente modificare i profili di cache definiti nel file di configurazione Web. Tutte le modifiche apportate al file di configurazione Web verranno rilevate automaticamente e applicate.

Ad esempio, la sezione memorizzazione nella cache> della configurazione Web nell'elenco <6 definisce un profilo di cache denominato Cache1Hour. La <sezione caching> deve essere visualizzata all'interno della <sezione system.web> di un file di configurazione Web.

Elenco 6 : sezione Memorizzazione nella cache per web.config

<caching>
<outputCacheSettings>
    <outputCacheProfiles>
        <add name="Cache1Hour" duration="3600" varyByParam="none"/>
    </outputCacheProfiles>
</outputCacheSettings>
</caching>

Il controller nell'elenco 7 illustra come applicare il profilo Cache1Hour a un'azione del controller con l'attributo <OutputCache> .

Elenco 7 : Controllers\ProfileController.vb

Public Class ProfileController
    Inherits System.Web.Mvc.Controller

    <OutputCache(CacheProfile:="Cache1Hour")> _
    Function Index()
        Return DateTime.Now.ToString("T")
    End Function

End Class

Se si richiama l'azione Index() esposta dal controller nell'elenco 7, verrà restituita la stessa ora per 1 ora.

Riepilogo

La memorizzazione nella cache dell'output offre un metodo molto semplice per migliorare notevolmente le prestazioni delle applicazioni MVC ASP.NET. In questa esercitazione si è appreso come usare l'attributo <OutputCache> per memorizzare nella cache l'output delle azioni del controller. Si è anche appreso come modificare le proprietà dell'attributo <OutputCache> , ad esempio le proprietà Duration e VaryByParam per modificare la modalità di memorizzazione nella cache del contenuto. Infine, si è appreso come definire i profili di cache nel file di configurazione Web.