Назад | Перейти на главную страницу

Как разрешить IIS всегда предварительно сжимать / предварительно архивировать определенный файл?

У меня есть js-файл размером 4 МБ (сжатая версия - 900 КБ). Файл выглядит следующим образом: main.328479fdsdf.js (поэтому у него есть хэш на основе содержимого).

Кажется, что IIS сжимает мой большой js-файл, только если к нему обращаются 2 раза за 10 секунд. Однако, если у меня есть пользователь, подключенный к сети 3G, каждую минуту ему придется ждать около 30 секунд, прежде чем откроется веб-сайт. Если GZIPPED, пользователь ждет всего 12 секунд.

Я знаю, что GZIP не должен использоваться для всего содержимого, но для моего конкретного файла мне нужно всегда отправлять его в сжатом виде по сети. Как я могу этого добиться?

Я нашел обходной путь. Я считаю, что это хакерское решение, но оно устранило мою проблему.

Моя идея состояла в том, чтобы создать службу Windows, которая будет выполнять запрос каждые пару секунд, чтобы IIS всегда считал мои файлы JavaScript частыми попаданиями и всегда имел их сжатую версию:

class JsScriptCompressKeeper
{
    private bool keepRunning = true;
    public void Start()
    {
        var thread = new Thread(Run);
        thread.Start();
    }

    public void Stop()
    {
        keepRunning = false;
    }


    public void Run()
    {
        var mainUrl = "www.example.com";
        var pingTimeout = 7;  //seconds
        // my js filenames are like babel-polyfill.asd123eqwed.js and main.113edweq.js 
        var patterns = new[] { @"babel-polyfill.([A-Za-z0-9\-]+).js", @"main.([A-Za-z0-9\-]+).js"};

        using (var client = new WebClient())
        {
            // parse the HTML and find my JS files
            var mainHtml = client.DownloadString(new Uri(mainUrl));
            var urls = patterns.Select(pattern =>
            {
                var match = Regex.Match(mainHtml, pattern);
                var fileName = match.Groups[0].Value;
                return new Uri($"{mainUrl}/{fileName}");
            }).ToList();

            while (true)
            {
                if (!keepRunning)
                {
                    break;
                }

                Thread.Sleep(TimeSpan.FromSeconds(pingTimeout));
                urls.ForEach(url =>
                {
                    client.DownloadString(url);
                });
            }
        }

    }
}

P.S. Я считаю, что мои решения слишком хакерские, поэтому я не приму свой ответ. Может у кого-нибудь есть более чистое решение! :)