Свяжите и уменьшите JavaScript на лету ИЛИ во время изготовления - ASP.NET MVC

Наиболее питоническим является "root.wm_state('zoomed'), как упомянуто @ J.F.Sebastian

46
задан Community 23 May 2017 в 12:24
поделиться

5 ответов

В приложении к Professional ASP.NET 3.5 Скотт Хансельман рассказывает о Packer for .NET . Он будет интегрирован с MSBuild и упаковать файлы javascript для производственных развертываний и т. Д.

7
ответ дан 26 November 2019 в 20:29
поделиться

Почему бы не использовать ScriptManager? Вот MVCScriptManager , который объединяет И сжимает.

14
ответ дан 26 November 2019 в 20:29
поделиться

Используйте компрессор YUI или компрессор Dojo. Оба они используют механизм синтаксического анализа Rhino JS, который токенизирует ваш код и поэтому будет работать только в том случае, если код является действительным. Если произойдет ошибка, они сообщат вам (что является приятным бонусом, IMO!) Packer, с другой стороны, упакует ваш код, даже если он содержит ошибки.

Я использую YUI во всех своих проектах через скрипты сборки . Никогда не делайте это на лету, на сжатие уходит слишком много времени. И YUI, и Dojo основаны на Java (ala Rhino), и если вы сделаете это «на лету», вы будете порождать фоновые процессы для генерации вывода, что не очень хорошо для производительности. Всегда делайте это во время сборки.

6
ответ дан 26 November 2019 в 20:29
поделиться

Here's what I've used for concatenating, compressing and caching CSS and JS files: http://gist.github.com/130913

It just requires Yahoo.Yui.Compressor.dll in the bin directory. It doesn't compress at compile time, but the files are cached with a file dependency, so they are only loaded once, until they're changed.

Then I just add this code in the :

<link rel="stylesheet" type="text/css" href="/YuiCompressor.ashx?css=reset,style,etc" />

and this just before the :

<script type="text/javascript" src="/YuiCompressor.ashx?js=main,other,etc"></script>

It's designed to work with multiple files all in the same path but could easily be upgraded to support different paths.

2
ответ дан 26 November 2019 в 20:29
поделиться

Попробуйте следующее:

Я недавно завершил изрядное исследование и последующую разработку на работе, которая далеко идет в направлении повышения производительности внешнего интерфейса нашего веб-приложения. Я подумал, что поделюсь здесь основным решением.

Первое, что нужно сделать, это протестировать ваш сайт с помощью Yahoo YSlow и Google PageSpeed. Это подчеркнет необходимость улучшения производительности "низко висящих фруктов". Если вы еще не сделали этого, то в итоговых предложениях почти наверняка будут входить объединение, минимизация и сжатие статического содержимого.

Шаги, которые мы собираемся выполнить, следующие:

Напишите собственный HTTPHandler для объединения и минимизации CSS. Напишите собственный HTTPHandler для объединения и минимизации JS. Включите механизм, гарантирующий, что вышеперечисленное будет действовать только тогда, когда приложение не находится в режиме отладки. Напишите пользовательский веб-элемент управления на стороне сервера, чтобы легко поддерживать включение файлов css / js. Включите GZIP для определенных типов содержимого в IIS 6. Хорошо, давайте начнем с CSSHandler.asax, который реализует интерфейс .NET IHttpHandler:

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);
        }
    }
}

Хорошо, теперь некоторые пояснения:

Свойство IsReUsable:

Мы не имеем дело ни с чем, зависящим от конкретного экземпляра, что означает, что мы можем безопасно повторно использовать один и тот же экземпляр обработчика для обработки нескольких запросов, потому что наш ProcessRequest является потокобезопасным. Подробнее

Метод ProcessRequest:

Здесь не происходит ничего особенного. Мы просматриваем предоставленные нам файлы CSS (см. CSSControl ниже, чтобы узнать, как они поступают) и сжимаем каждый из них, используя .NET-порт Yahoo YUICompressor, перед добавлением содержимого в исходящий поток ответов.

Остальная часть метода связана с настройкой некоторых свойств кэширования HTTP для дальнейшей оптимизации способа загрузки (или не загрузки, в зависимости от обстоятельств) содержимого клиентом браузера. Мы устанавливаем зависимости Response и Cache для наших фактических файлов, поэтому в случае их замены кеш станет недействительным. Мы устанавливаем Cacheability так, чтобы прокси могли кэшировать. Мы VaryByParams используем наш атрибут cssfiles, чтобы мы могли кэшировать для каждой группы файлов CSS, отправленных через обработчик. А вот CSSControl, настраиваемый серверный элемент управления, наследующий .NET LiteralControl.

Front:

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

Back:

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.Current.IsDebuggingEnabled подключается к следующему параметру в вашем web.config:

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

Итак, в основном, если ваш сайт находится в режиме отладки, вы получите разметку HTML, подобную этой:

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

Но если вы находитесь в рабочем режиме (debug = false), вы получите разметку, подобную этой:

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

Последняя затем, очевидно, вызовет CSSHandler, который позаботится об объединении, минимизации и подготовке кеша вашего статического содержимого CSS.

Все вышеперечисленное также может быть продублировано для вашего статического содержимого JavaScript:

`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);
        }
    }
}

И сопровождающий его JSControl:

Передняя сторона:

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

Задняя сторона:

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; }
    }
}

Включение GZIP:

Как говорит Джефф Этвуд, включение Gzip на сервере вашего веб-сайта не составляет труда. После некоторого отслеживания, .js .axd (файлы Microsoft Javascript) .aspx (обычное содержимое веб-форм ASP.NET) .ashx (Наши обработчики) Чтобы включить сжатие HTTP на веб-сервере IIS 6.0:

Откройте IIS, щелкните правой кнопкой мыши веб-сайты, вкладку «Службы», включите «Сжатие файлов приложений» и «Сжатие статических файлов». Остановить IIS Откройте метабазу IIS в Блокноте (C: \ WINDOWS \ system32 \ inetsrv \ MetaBase.xml) - и сделайте резервную копию, если вы нервничаете по поводу этих вещей. Найдите и перезапишите два элемента IIsCompressionScheme и один IIsCompressionSchemes следующим образом:

И все! Это сэкономило нам массу ресурсов и привело к тому, что веб-приложение стало более отзывчивым.

Наслаждайтесь!

41
ответ дан 26 November 2019 в 20:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: