SORU
20 Mayıs 2009, ÇARŞAMBA


Bağlamak ve anında JavaScript VEYA zaman - ASP.NET MVC inşa at küçült

Bu soruyu burada Linking JavaScript Libraries in User Controls bir uzantısı olarak insanlar ve inşa zaman sinek VEYA JavaScript bitiştirmek küçültmeye nasıl bazı örnekler peşindeydim. Ayrıca, ana sayfaları olarak nasıl çalıştığını görmek istiyorum.

Sorun değil sayfa belirli dosyaları olmak minified ve Bağlantılı inidividually olarak onlar şu anda (aşağıya bakınız) ama tüm JavaScript dosyaları üzerinde ana sayfa (yaklaşık 5 veya 6) isterim birleştirilmiş ve minified.

Bonus da CSS birleştirme ve minification içermektedir herkes için puan! :-)

Yaygın JavaScript ile geçerli Ana Sayfa birleştirilmiş ve minified istediğim dosyaları:

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<head runat="server">
    ... BLAH ...
    <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" />
    ... BLAH ...
    <%= Html.CSSBlock("/styles/site.css") %>
    <%= Html.CSSBlock("/styles/jquery-ui-1.7.1.css") %>
    <%= Html.CSSBlock("/styles/jquery.lightbox-0.5.css") %>
    <%= Html.CSSBlock("/styles/ie6.css", 6) %>
    <%= Html.CSSBlock("/styles/ie7.css", 7) %>
    <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" />
</head>
<body>
    ... BLAH ...
    <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %>
    <%= Html.JSBlock("/scripts/jquery-ui-1.7.1.js", "/scripts/jquery-ui-1.7.1.min.js") %>
    <%= Html.JSBlock("/scripts/jquery.validate.js", "/scripts/jquery.validate.min.js") %>
    <%= Html.JSBlock("/scripts/jquery.lightbox-0.5.js", "/scripts/jquery.lightbox-0.5.min.js") %>
    <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %>
    <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" />
</body>

Böyle bir sayfa ile mutluyum) kullanılan:

<asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server">
    <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %>
</asp:Content>

GÜNCELLEME:Tavsiyeler için şimdi (2013 sonu):

Microsoft ASP.NET'Bundling and Minification s inşa edilmiş. bakar

CEVAP
11 Kasım 2009, ÇARŞAMBA


Bunu deneyin:

Son zamanlarda oldukça çok web uygulamasının performansını ön uç geliştirmek için gittiği iş yerinde araştırma ve geliştirme sonucu adil bir bit tamamladım. Temel çözümü burada paylaşayım dedim.

Yapmanız gereken ilk şey besbelli ki sitenizi Yahoo YSlow kullanarak kriter ve Google PageSpeed. Vurgular bu "düşük asılı meyve" yapmak için performans geliştirmeleri. Zaten bunu yaptığın sürece, ortaya çıkan öneriler neredeyse kesinlikle birleştiren ve statik içerik küçültmeye gzipping yer alacak.

Gerçekleştirmek için gidiyoruz adımlar şunlardır:

Özel bir HTTPHandler birleştirmek için yaz ve CSS minify. Özel bir HTTPHandler birleştirmek için yaz ve JS minify. Uygulama hata ayıklama modunda değilse, yukarıda sadece büyü yapmak emin olmak için bir mekanizma vardır. Sunucu tarafında css/js korumak içerme dosyası için kontrol web özel yazma. IIS 6 üzerinde belirli içerik türleri GZİP etkinleştirme. Tamam, hadi CSSHandler ile başlar.asax bunu uygular .NET IHttpHandler arabirimi:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;

namespace WebApplication1
{
    public class CssHandler : IHttpHandler
    {
        public bool IsReusable { get { return true; } }

        public void ProcessRequest(HttpContext context)
        {
            string[] cssFiles = context.Request.QueryString["cssfiles"].Split(',');

            List<string> files = new List<string>();
            StringBuilder response = new StringBuilder();
            foreach (string cssFile in cssFiles)
            {
                if (!cssFile.EndsWith(".css", StringComparison.OrdinalIgnoreCase))
                {
                    //log custom exception
                    context.Response.StatusCode = 403;
                    return;
                }

                try
                {
                    string filePath = context.Server.MapPath(cssFile);
                    string css = File.ReadAllText(filePath);
                    string compressedCss = Yahoo.Yui.Compressor.CssCompressor.Compress(css);
                    response.Append(compressedCss);
                }
                catch (Exception ex)
                {
                    //log exception
                    context.Response.StatusCode = 500;
                    return;
                }
            }

            context.Response.Write(response.ToString());

            string version = "1.0"; //your dynamic version number 

            context.Response.ContentType = "text/css";
            context.Response.AddFileDependencies(files.ToArray());
            HttpCachePolicy cache = context.Response.Cache;
            cache.SetCacheability(HttpCacheability.Public);
            cache.VaryByParams["cssfiles"] = true;
            cache.SetETag(version);
            cache.SetLastModifiedFromFileDependencies();
            cache.SetMaxAge(TimeSpan.FromDays(14));
            cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        }
    }
}

Tamam, şimdi bir açıklama:

Isreusable özelliği:

Bizim ProcessRequest iş parçacığı için güvenli olduğu için güvenli bir şekilde işleyicisi aynı örneği birden çok istekleri ile başa çıkmak için yeniden, biz demek ki bir şey örneğe özel ile karşı karşıya değiliz. Daha fazla bilgi.

ProcessRequest metodu:

Çok telaşlı oluyor burada. CSS dosyalarını bize verilen (CSSControl aşağıda geliyorlar ne için) döngü ve her biri sıkıştırarak, bir kullanıyoruz .Yahoo NET port YUİCompressor, giden yanıt akışı içeriğini eklemeden önce.

Bu yöntem kalan bazı HTTP önbelleğe alma özellikleri daha fazla tarayıcı istemci (veya, duruma göre değil) içerik popülerlik şekilde optimize etmek için ayarlama ile ilgilidir.

Sunucu grubundaki tüm makineler arasında aynı olabilir, böylece kod Etags kurduk. Değiştirilmesi gerekir, önbellek geçersiz olacak bizim gerçek dosyalar üzerinde Tepki ve Önbellek bağımlılıkları kurduk. Cacheability vekiller önbellek böyle kurduk. Bizim cssfiles başına CSS dosyası işleyicisi aracılığıyla sunulan grup önbellek böylece özniteliği kullanarak VaryByParams. Ve işte CSSControl, özel bir sunucu tarafı denetimi devralmasını .NET LiteralControl.

Ön:

<customcontrols:csscontrol id="cssControl" runat="server">
  <CustomControls:Stylesheet File="main.css" />
  <CustomControls:Stylesheet File="layout.css" />
  <CustomControls:Stylesheet File="formatting.css" />
</customcontrols:csscontrol>

Geri:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Linq;
using TTC.iTropics.Utilities;

namespace WebApplication1
{
    [DefaultProperty("Stylesheets")]
    [ParseChildren(true, "Stylesheets")]
    public class CssControl : LiteralControl
    {
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public List<Stylesheet> Stylesheets { get; set; }

        public CssControl()
        {
            Stylesheets = new List<Stylesheet>();
        }

        protected override void Render(HtmlTextWriter output)
        {
            if (HttpContext.Current.IsDebuggingEnabled)
            {
                const string format = "<link rel=\"Stylesheet\" href=\"stylesheets/{0}\"></link>";

                foreach (Stylesheet sheet in Stylesheets)
                    output.Write(format, sheet.File);
            }
            else
            {
                const string format = "<link type=\"text/css\" rel=\"Stylesheet\" href=\"stylesheets/CssHandler.ashx?cssfiles={0}&version={1}\"/>";
                IEnumerable<string> stylesheetsArray = Stylesheets.Select(s => s.File);
                string stylesheets = String.Join(",", stylesheetsArray.ToArray());
                string version = "1.00" //your version number

                output.Write(format, stylesheets, version);
            }

        }
    }

    public class Stylesheet
    {
        public string File { get; set; }
    }
}

HttpContext.Mevcut.İsDebuggingEnabled web içinde aşağıdaki ayarı bağladım.config:

<system.web>
  <compilation debug="false">
</system.web>

Eğer sitenizde hata ayıklama modunda ise yani, temelde, bu gibi HTML biçimlendirme:

<link rel="Stylesheet" href="stylesheets/formatting.css"></link>
<link rel="Stylesheet" href="stylesheets/layout.css"></link
<link rel="Stylesheet" href="stylesheets/main.css"></link>

Ama eğer üretim modu (debug=false), bu gibi biçimlendirme: var

<link type="text/css" rel="Stylesheet" href="CssHandler.ashx?cssfiles=main.css,layout.css,formatting.css&version=1.0"/>

İkincisi birleştirerek, küçültmeye ve önbelleği hazırlanan statik CSS içerik ilgilenecek olan o zaman tabii ki CSSHandler çağırmak olacaktır.

Yukarıdaki tüm sonra da statik JavaScript içeriği için çoğaltılmış olabilir:

`JSHandler.ashx:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;

namespace WebApplication1
{
    public class JSHandler : IHttpHandler
    {
        public bool IsReusable { get { return true; } }

        public void ProcessRequest(HttpContext context)
        {
            string[] jsFiles = context.Request.QueryString["jsfiles"].Split(',');

            List<string> files = new List<string>();
            StringBuilder response = new StringBuilder();

            foreach (string jsFile in jsFiles)
            {
                if (!jsFile.EndsWith(".js", StringComparison.OrdinalIgnoreCase))
                {
                    //log custom exception
                    context.Response.StatusCode = 403;
                    return;
                }

                try
                {
                    string filePath = context.Server.MapPath(jsFile);
                    files.Add(filePath);
                    string js = File.ReadAllText(filePath);
                    string compressedJS = Yahoo.Yui.Compressor.JavaScriptCompressor.Compress(js);
                    response.Append(compressedJS);
                }
                catch (Exception ex)
                {
                    //log exception
                    context.Response.StatusCode = 500;
                    return;
                }
            }

            context.Response.Write(response.ToString());

            string version = "1.0"; //your dynamic version number here

            context.Response.ContentType = "application/javascript";
            context.Response.AddFileDependencies(files.ToArray());
            HttpCachePolicy cache = context.Response.Cache;
            cache.SetCacheability(HttpCacheability.Public);
            cache.VaryByParams["jsfiles"] = true;
            cache.VaryByParams["version"] = true;
            cache.SetETag(version);
            cache.SetLastModifiedFromFileDependencies();
            cache.SetMaxAge(TimeSpan.FromDays(14));
            cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        }
    }
}

Ve beraberindeki JSControl:

Ön:

<customcontrols:JSControl ID="jsControl" runat="server">
  <customcontrols:Script File="jquery/jquery-1.3.2.js" />
  <customcontrols:Script File="main.js" />
  <customcontrols:Script File="creditcardpayments.js" />
</customcontrols:JSControl>

Geri:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Linq;

namespace WebApplication1
{
    [DefaultProperty("Scripts")]
    [ParseChildren(true, "Scripts")]
    public class JSControl : LiteralControl
    {
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public List<Script> Scripts { get; set; }

        public JSControl()
        {
            Scripts = new List<Script>();
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (HttpContext.Current.IsDebuggingEnabled)
            {
                const string format = "<script src=\"scripts\\{0}\"></script>";

                foreach (Script script in Scripts)
                    writer.Write(format, script.File);
            }
            else
            {
                IEnumerable<string> scriptsArray = Scripts.Select(s => s.File);
                string scripts = String.Join(",", scriptsArray.ToArray());
                string version = "1.0" //your dynamic version number
                const string format = "<script src=\"scripts/JsHandler.ashx?jsfiles={0}&version={1}\"></script>";

                writer.Write(format, scripts, version);
            }
        }
    }

    public class Script
    {
        public string File { get; set; }
    }
}

GZİP etkinleştirme:

Jeff Atwood dediği gibi, web sitenizin sunucu üzerinde Gzip sağlayan bir no-brainer olduğunu. Bazı izleme sonra aşağıdaki dosya türleri üzerinde Gzip etkinleştirmek için karar verdi:

.css .js .axd (Microsoft Javascript dosyaları) .SEO (her Zamanki ASP.NET Web Formları içerik) .ashx (işleyicileri) IIS 6.0 web server üzerinde HTTP Sıkıştırmasını etkinleştirmek için:

Sağ tıklayarak Web Siteleri IIS, Uygulama Dosyaları Sıkıştırmak etkinleştirmek Hizmetleri sekme ve Sıkıştırma Statik açık Dosyaları Dur IIS IIS Metatabanı Not Defteri'nde (c:\windows\system32\inetsrv\metabase.xml açık) – ve eğer bu şeyler hakkında endişeleriniz varsa yedekleyin olun Ve iki İİsCompressionScheme ve yerini tespit üzerine İİsCompressionSchemes aşağıdaki unsurları:

Ve işte bu! Bu bant genişliği bize bir yığın kaydedilir ve daha duyarlı bir web uygulaması boyunca sonuçlandı.

Tadını çıkarın!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • lilstevie89

    lilstevie89

    25 Mart 2011
  • Matthew Pearce

    Matthew Pear

    9 AĞUSTOS 2009
  • williamfitzsimmons

    williamfitzs

    14 Mart 2008