Старый 25.02.2008, 01:53   #1 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Компрессия JS

Хочу спросить вашего совета.
Вобщем вопрос вот в чем. Начал я тут недавно мутить свой движек для сайтов. А т.к. повсюду только и слышно Web 2.0, Ajax и т.п., решил не изобретать велосипед, а установить готовые решения: xajax, prototype, scriptaculous, prototip. Всё вроде работает, но меня напрягает размер этого барахла. Итого, 1 страница с простенькой всплывающей подсказкой весит чуть-ли не 200 кило.
Решил, что это всё лучше-б сжать gzip'ом чтоли. И родилась такая идея:
В CMS есть специальная дира, в ней лежат *.js файлы. И если запрашивается файл из неё, то выдается он в сжатом виде. Написал пару нехитрых скриптов, и всё вроде работает. Но есть сомнения по поводу разных браузеров/хостингов - везде-ли будет это работать. Может кто уже сталкивался с такой задачей и что посоветует для улучшения этого скрипта. Да и другим людям, столкнувшимся с подобными вещами будет с чего начать.
Например та страница с подсказкой, о которой я писал в начале, теперь весит в 4 раза меньше. А это уже куда лучше.
Итак повторю вопрос: "что можно сделать для улучшения самого скрипта и его универсальности"

Вот скрипт compress.php:
PHP код:
<?php

// тип компрессии
$compress_type=3;

// 0 - не использовать компрессию
// 1 - програмное сжатие
// 2 - gzip сжатие
// 3 - gzip сжатие, если не поддерживается то програмное сжатие

function program_compress($layout){// заимствовано из xajaxCompress.php
    
$layout str_replace("\r","",$layout);
    
$literal_strings = array();
    
$lines explode("\n",$layout);
    
$clean "";
    
$inComment false;
    
$literal "";
    
$inQuote false;
    
$escaped false;
    
$quoteChar "";
    for(
$i=0;$i<count($lines);$i++){
        
$line $lines[$i];
        
$inNormalComment false;
        for(
$j=0;$j<strlen($line);$j++){
            
$c substr($line,$j,1);
            
$d substr($line,$j,2);
            if(!
$inQuote && !$inComment){
                if((
$c=="\"" || $c=="'") && !$inComment && !$inNormalComment){
                    
$inQuote true;
                    
$inComment false;
                    
$escaped false;
                    
$quoteChar $c;
                    
$literal $c;
                }else if(
$d=="/*" && !$inNormalComment){
                    
$inQuote false;
                    
$inComment true;
                    
$escaped false;
                    
$quoteChar $d;
                    
$literal $d;
                    
$j++;
                }else if(
$d=="//"){
                    
$inNormalComment true;
                    
$clean .= $c;
                }else{
                    
$clean .= $c;
                }
            }else{
                if(
$c == $quoteChar && !$escaped && !$inComment){
                    
$inQuote false;
                    
$literal .= $c;
                    
$clean .= "___" count($literal_strings) . "___";
                    
array_push($literal_strings,$literal);
                }else if(
$inComment && $d=="*/"){
                    
$inComment false;
                    
$literal .= $d;
                    
$clean .= "___" count($literal_strings) . "___";
                    
array_push($literal_strings,$literal);
                    
$j++;
                }else if(
$c == "\\" && !$escaped)
                    
$escaped true;
                else
                    
$escaped false;
                
$literal .= $c;
            }
        }
        if(
$inComment$literal .= "\n";
        
$clean .= "\n";
    }
    
$lines explode("\n",$clean);
    for(
$i=0;$i<count($lines);$i++){
        
$line $lines[$i];
        
$line preg_replace("/\/\/(.*)/","",$line);
        
$line trim($line);
        
$line preg_replace("/\s+/"," ",$line);
        
$line preg_replace("/\s*([!\}\{;,&=\|\-\+\*\/\)\(:])\s*/","\\1",$line);
        
$lines[$i] = $line;
    }
    
$layout implode("\n",$lines);
    
$layout preg_replace("/[\n]+/","\n",$layout);
    
$layout preg_replace("/;\n/",";",$layout);
    
$layout preg_replace("/[\n]*\{[\n]*/","{",$layout);
    for(
$i=0;$i<count($literal_strings);$i++)$layout str_replace("___".$i."___",$literal_strings[$i],$layout);
    return 
$layout;
}

function 
gzip_compress($layout){
    global 
$supportsGzip;
    
$supportsGzip=1;
    if (isset(
$_SERVER['HTTP_ACCEPT_ENCODING'])||$_SERVER['HTTP_TE']){// Проверка, потдерживается ли gzip
        
$enco=($_SERVER['HTTP_TE'])?$_SERVER['HTTP_ACCEPT_ENCODING'].", ".$_SERVER['HTTP_TE']:$_SERVER['HTTP_ACCEPT_ENCODING'];
        
$encodings explode(','strtolower(preg_replace("/\s+/"""$enco)));
        if(
is_array($encodings)){
            if ((
in_array('gzip'$encodings) || in_array('x-gzip'$encodings) || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
                
$enc in_array('gzip'$encodings) ? "gzip" "x-gzip";
                
$supportsGzip 2;
            }
        }else{
            if (((
$encodings=='gzip') || ($encodings=='x-gzip') || isset($_SERVER['---------------'])) && function_exists('ob_gzhandler') && !ini_get('zlib.output_compression')) {
                
$enc = ($encodings=='gzip') ? "gzip" "x-gzip";
                
$supportsGzip 2;
            }
        }
    }
    if(
$supportsGzip==2){// сжать, если можно
        
$layout=gzencode($layout9FORCE_GZIP);// сжать данные
        
header("Content-Encoding: $enc");// заголовок
        
$layout=$layout;
    }
    return 
$layout;
}

// получаем файл
$q=explode('?',$_SERVER['REQUEST_URI']);
$filename=$q[0];
if(@
is_file($_SERVER["DOCUMENT_ROOT"].$filename)){
    
$layout=implode('',file($_SERVER["DOCUMENT_ROOT"].$filename));
    
$len1=strlen($layout);// запоминаем его размер до сжатия
    
$layout2=$layout;
    if(
$compress_type==1){// програмная компрессия
        
$layout=program_compress($layout);
    }elseif(
$compress_type==2){// gzip компрессия
        
$layout=gzip_compress($layout);
    }if(
$compress_type==3){// gzip компрессия
        
$layout=gzip_compress($layout);
        
// если gzip компрессия не сработала - програмная компрессия
        
if($supportsGzip==1)$layout=program_compress($layout);
    }

    
$len2=strlen($layout);
    
$layout=(strlen($layout2)<$len2)?$layout2:$layout;// если после сжатия файл стал больше исходного

    // вывод
    
header ("Content-type: text/javascript");
    echo 
"$layout";
}else{
    echo 
"alert('Файл не найден: $filename');";
}

?>


=====================================

+ .htaccess файл:


Options +FollowSymlinks
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} (.*)\.js$
    RewriteRule ^(.*)$ compress.php [L]
</IfModule>


=====================================
сори что текст не отформатирован, пользуюсь оперой, а она здесь глючит.

Последний раз редактировалось AleX; 25.02.2008 в 01:57.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
2 пользователя(ей) отблагодарили RXcoder за это сообщение:
AleX (25.02.2008), Devil (26.02.2008)
Старый 25.02.2008, 01:59   #2 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

Да, как использовать забыл сказать:
1. создаем диру на сайте. допустим js
2. закидываем туда эти 2 файла
3. кидаем туда js скрипты, чтобы потом подключать их со своих страниц
4. проверяем. Если что-то нетак - пишем сюда
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Этот пользователь отблагодарил RXcoder за это сообщение:
Devil (26.02.2008)
Старый 27.02.2008, 19:14   #3 (permalink)
Администратор
 
Аватар для Devil
 
Специализация: Кодер
Регистрация: 05.12.2007
Адрес: Москва
Сообщений: 3,637
Репутация: 1684
Номер ICQ 599613
По умолчанию Ответ: Компрессия JS

RXcoder, проверил на двух хостингах на мСхост и Можордомо - всё прекрасно пашет, спасибо за скрипт
__________________
Мы те, кто мы есть
Мой личный блог
Devil вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 02.03.2008, 04:30   #4 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

эт хорошо, а то я только на денвере тестироавл. Были сомнения, что в реальной работе что-нибудь не так пойдет.
Кстате можно и в поддиректории js скрипты закидывать, не обязательно в папку с этими скриптами. Можно немного их подправить для сжатия html, css и других файлов, которые сами себя сжать не могут. Например txt.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 02.03.2008, 06:11   #5 (permalink)
Администратор
 
Аватар для Devil
 
Специализация: Кодер
Регистрация: 05.12.2007
Адрес: Москва
Сообщений: 3,637
Репутация: 1684
Номер ICQ 599613
По умолчанию Ответ: Компрессия JS

RXcoder, вся шутка в том, что почему - то скрипт неадекватен при гзип на шестом уровне...начинаються тормаза просто ад...
__________________
Мы те, кто мы есть
Мой личный блог
Devil вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 02.03.2008, 06:38   #6 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

эт хорошо, а то я только на денвере тестироавл. Были сомнения, что в реальной работе что-нибудь не так пойдет.
Кстате можно и в поддиректории js скрипты закидывать, не обязательно в папку с этими скриптами. Можно немного их подправить для сжатия html, css и других файлов, которые сами себя сжать не могут. Например txt.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 02.03.2008, 06:43   #7 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

Извиняюсь, 2й раз сообщение отправил по ошибке.
Ну тогда на 4й уровень поставить и не парится из-за лишних нескольких байт. Так хоть пошустрей работать будет.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 02.03.2008, 06:56   #8 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

Сам скрипт не должен сильно напрягать сервер, но вот функция сжатия, выдранная мной из компрессора xajax'a (я обозвал её - program_compress()) действительно тормозная. Попробуй в начале скрипта поставить только gzip -

$compress_type=2;

Если помогло, значит в ней дело.

Я потому и написал, что интересно было узнать, как это дело будет вести себя в реальных условиях.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Этот пользователь отблагодарил RXcoder за это сообщение:
Devil (02.03.2008)
Старый 02.03.2008, 17:23   #9 (permalink)
Администратор
 
Аватар для Devil
 
Специализация: Кодер
Регистрация: 05.12.2007
Адрес: Москва
Сообщений: 3,637
Репутация: 1684
Номер ICQ 599613
По умолчанию Ответ: Компрессия JS

RXcoder, Да при 4 уровне, всё шшикарно на выше указанных хостах. Спасибо
__________________
Мы те, кто мы есть
Мой личный блог
Devil вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Старый 03.03.2008, 05:14   #10 (permalink)
Новичок
 
Регистрация: 25.02.2008
Сообщений: 13
Репутация: 16
По умолчанию Ответ: Компрессия JS

Да незачто, пусть люди юзают.
RXcoder вне форума  
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post! Добавить в закладки Google
Ответить с цитированием
Этот пользователь отблагодарил RXcoder за это сообщение:
Devil (03.03.2008)
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения



Часовой пояс GMT +4, время: 03:53.
Powered by vBulletin® Version 7.51.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Web Mastering By Devil Art