Показано с 1 по 8 из 8

Тема: Сжатие и кеширование

  1. #1
    Джентльмен лжец Аватар для Fallen A.
    Регистрация
    03.09.2011
    Адрес
    Минск, БССР
    Возраст
    30
    Сообщений
    2,409
    Репутация: 337

    Звание: как роза среди колючек

    Сжатие и кеширование

    • Предисловие

    При разработке веб проектов наступает тот момент, когда "создатель" и его детище сталкиваются с т.н. высокими нагрузками, замедляющими работу всего проекта. Чтобы этого избежать, разработчики стали придумывать вещи, снижающие нагрузку на оборудование. Одной из этих вещей и явилось всевозможное кеширование или сжатие необходимых файлов/данных/страниц.

    • Начало

    Пожалуй, начну я с самого просто и буду двигаться вперед к сложному по нарастающей.
    Первым делом поговорим о так называемом "GZIP compression" - GZIP обеспечивает сжатие без потерь, иными словами, исходные данные можно полностью восстановить при распаковке. Прочесть об этом подробнее можно здесь.

    Предоставлю рабочий код:
    PHP код:
    class g_ZIP 
    {
        
        public function 
    start_gZIP() 
        {
            
    ob_start();
            
    ob_implicit_flush(0);
        }

        public function 
    output_gZIP($compress true$use_etag true$send_body true
        {
            
    $min_gz_size 1024;
            
    $page ob_get_contents();
            
    $length strlen($page);
            
    ob_end_clean();

            if (
    $compress && extension_loaded('zlib') && (strlen($page) > $min_gz_size) && isset($globals['http_server_vars']['http_accept_encoding'])) 
            {
                
    $ae explode(','str_replace(' '''$globals['http_server_vars']['http_accept_encoding']));
                
    $enc false;
                if (
    in_array('gzip'$ae)) 
                    
    $enc 'gzip';
                else if (
    in_array('x-gzip'$ae))
                    
    $enc 'x-gzip';
        
                if (
    $enc
                {
                    
    $length strlen($page);
                    
    header('content-encoding: ' $enc);
                    
    header('vary: accept-encoding');
                } else
                    
    $compress false;
            } else
                
    $compress false;

            if (
    $use_etag
            {
                
    $etag '"' md5($page) . '"';
                
    header('etag: ' $etag);
                if (isset(
    $globals['http_server_vars']['http_if_none_match'])) 
                {
                    
    $inm explode(','$globals['http_server_vars']['http_if_none_match']);
                    foreach (
    $inm as $i
                    {
                        if (
    trim($i) == $etag
                        {
                            
    header('http/1.0 304 not modified');
                            
    $send_body false;
                            break;
                        }
                    }
                }
            }

            if (
    $send_body
            {
                
    header('content-length: ' $length);
                echo 
    $page;
            }
        }
        

    Использовать данный код на практике можно смело. Делается это вот так:
    PHP код:
    $g_ZIP = new g_ZIP();
    $g_ZIP->start_gZIP();
    // Тело документа/страницы
    $g_ZIP->output_gZIP(); 
    P.S. Код писался не мной и пояснять его работу я не буду, благо, во всемирной паутине хватает различного материала.

    Так же можно использовать следующие манипуляции с файлом .htaccess ( подробнее об этом файле можно узнать здесь. ) :
    PHP код:
    <IfModule mod_gzip.c>
            
    mod_gzip_on Yes
            mod_gzip_dechunk Yes
            mod_gzip_item_include file 
    \.(html?|txt|css|js|php|pl)$ 
            
    mod_gzip_item_include handler ^cgi-script$
            
    mod_gzip_item_include mime ^text\.*
            
    mod_gzip_item_include mime ^application/x-javascript.*
            
    mod_gzip_item_exclude mime ^image\.*
            
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* 
    </
    IfModule
    Однако, можно зайти еще дальше и использовать вот такие вот "извращения":

    PHP код:
    class pages_Cache 

        
        var 
    $ID
        var 
    $path
        var 
    $file_cache
        var 
    $full_url_cache

        public function 
    _cacheInit($ID$path$file_cache
        { 
            if(!
    is_writable($path))
                
    chmod($path0644); // Доступ на запись и чтение для владельца, доступ на чтение для других
            
    $this->ID $ID;
            
    $this->full_url_cache $path.$file_cache
            if(
    file_exists($this->full_url_cache))
            { 
                echo 
    file_get_contents($this->full_url_cache);
                exit; 
            } else
                
    ob_start(); 
        } 
        
        public function 
    _cacheStop_and_Write() 
        { 
            
    $handle fopen($this->full_url_cache'w'); // Открываем файл для записи и стираем его содержимое
            
    fwrite($handleob_get_contents()); // Сохраняем всё содержимое буфера в файл
            
    fclose($handle); // Закрываем файл
            
    ob_end_flush(); // Выводим страницу в браузере
        
    }
        
        public function 
    _clearCache($file)
        {
            @
    unlink($file);    
        }
        
        public function 
    _cleanCacheDir($dir
        {
            
    $files glob($dir."/*");
            if(
    count($files) > 0
            {
                foreach (
    $files as $file
                {      
                    if(
    file_exists($file)) 
                    {
                        
    unlink($file);
                    }   
                }
            }
        }


    К примеру у вас есть страница с некоторыми данными, которые обновляются крайне редко и вам не хотелось бы нагружать сервер лишними запросами -> этот код, думаю, будет лучшим решением данной проблемы.
    Как же он работает: при первой загрузке страницы, код проверяет, есть ли данный кеш с таким ID ( к примеру ) на сервере, если да, то данные не будут читаться дальше из базы, а просто вам будет показано то, что уже записано в файл. Если же кеша нет на сервере, то данные запишутся в файл->создастся кеш и будет происходить то, что было описано выше. Прошу прощения за примитивный пример.

    Как же это использовать:

    PHP код:
    $pages_Cache = new pages_Cache();
    $pages_Cache->_cacheInit($_GET_IDrtrim($_SERVER['DOCUMENT_ROOT'],'/')."/cache/news/""cache_news_".$_GET_ID.".tmp");
    //Тело документа/страницы
    $pages_Cache->_cacheStop_and_Write(); 
    Как же обновить кеш? Спросите вы. Очень легко. К примеру: у нас уже есть готовая новость, выведенная на главную страницу и добавленная в кеш. Вдруг произошла необходимость что-то подкорректировать в ее содержании->просто добавляем вот этот код в необходимое место ( где в коде происходит "редактирование" ) и пользователи свободно увидят внесенные вами изменения, а кеш успешно сам обновится:

    PHP код:
    $pages_Cache->_clearCache(rtrim($_SERVER['DOCUMENT_ROOT'],'/')."/cache/news/cache_news_".$_GET_ID.".tmp"); 
    • Конец


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

    P.S. Использование данного кода и результат его работы лежат ответственностью только на вас.

  2. 1 пользователь сказал cпасибо Fallen A. за это полезное сообщение:

    vasyok28 (27.01.2016)

  3. #2
    unknown2154
    Бродяга
    Неплохо бы было указать авторов кода, а методы из класса g_ZIP сделать статическими, ибо смысла делать их динамическими нет. Насчет класса pages_Cache:
    Цитата Сообщение от Fallen A.
    Так никто не оформляет как классы, так и код вообще.

  4. #3
    Джентльмен лжец Аватар для Fallen A.
    Регистрация
    03.09.2011
    Адрес
    Минск, БССР
    Возраст
    30
    Сообщений
    2,409
    Репутация: 337

    Звание: как роза среди колючек
    Цитата Сообщение от Hidden125661 Посмотреть сообщение
    Неплохо бы было указать авторов кода, а методы из класса g_ZIP сделать статическими, ибо смысла делать их динамическими нет. Насчет класса pages_Cache:
    Автора сжатия GZIP я уже и не вспомню даже, ибо брал код чуть меньше года назад. Второй класс написан мной и что в нем не так, кроме названия?

  5. #4
    unknown2154
    Бродяга
    Цитата Сообщение от Fallen A. Посмотреть сообщение
    Второй класс написан мной
    Кроме одной функции :p
    Цитата Сообщение от Fallen A. Посмотреть сообщение
    Автора сжатия GZIP я уже и не вспомню даже, ибо брал код чуть меньше года назад. Второй класс написан мной и что в нем не так, кроме названия?
    Названия методов) Зачем в методы класса добавлять префикс, состоящий из названия класса?)

  6. #5
    Джентльмен лжец Аватар для Fallen A.
    Регистрация
    03.09.2011
    Адрес
    Минск, БССР
    Возраст
    30
    Сообщений
    2,409
    Репутация: 337

    Звание: как роза среди колючек
    Цитата Сообщение от Hidden125661 Посмотреть сообщение
    Кроме одной функции :p
    Какой?

    Цитата Сообщение от Hidden125661 Посмотреть сообщение
    Зачем в методы класса добавлять префикс, состоящий из названия класса?)
    Привычка такая, древняя

    Со static можно подумать, но для новичка это слишком сложно, пожалуй.

  7. #6
    unknown2154
    Бродяга
    Цитата Сообщение от Fallen A. Посмотреть сообщение
    Какой?
    _cacheStop_and_Write (нашел такой же код с такими же комментариями)

  8. #7
    Джентльмен лжец Аватар для Fallen A.
    Регистрация
    03.09.2011
    Адрес
    Минск, БССР
    Возраст
    30
    Сообщений
    2,409
    Репутация: 337

    Звание: как роза среди колючек
    Цитата Сообщение от Hidden125661 Посмотреть сообщение
    _cacheStop_and_Write (нашел такой же код с такими же комментариями)
    Ссылку в телеграме дай, ибо функция точно моя. Название даже взято из головы.

  9. #8
    Люблю Окса :3 Аватар для Folleah
    Регистрация
    26.09.2012
    Сообщений
    2,045
    Репутация: 184

    Звание: - весьма и весьма положительная личность
    Советую так же юзать на фронтэнде SVG разметку вместо обычных изображений (где это возможно) - это даст значительный прирост к загрузке макета.

Ваши права

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