Очень часто веб-разработчики сталкиваются с проблемой большого количества мелких файлов. Картинки, скрипты, css — неудобно, все дела. Нужно как-то бороться с этим. import, спрайты, блаблабла — это хорошо, но можно попробовать и иначе. Мой вариант — упаковка всех необходимых ресурсов в архив на стороне сервера(реализация — на php), получение данных на клиенте, установка ресурсов в нужных местах.
Проблемы на данный момент: не придумал толком, как кешировать полученный архив, таким способом не стоит паковать динамический контент или большие файлы.
Для распаковки архива на клиенте использована библиотека , для удобства — jQuery.
Итак, посмотрим на код.
ziplogic.php:
class ZipLogic extends ZipArchive{ public $filename; public function __construct() { $filename = "current/latest.zip"; $this->filename = $filename; if(file_exists($filename)) unlink($filename); if ($this->open($filename, ZIPARCHIVE::CREATE)!==TRUE) { $error = error_get_last(); echo $error["message"]; return null; } } public function pack($url){ $this->addFile($url); } }
Этот класс наследуется от ZipArchive и нужен только для чуть более удобной работы с архивом.
Теперь — код для упаковки нужных ресурсов:
index.php:
include "ziplogic.php"; $zpack = new ZipLogic(); if($zpack==null) { echo 'wrong data'; return; } $zpack->pack('img/screen.png'); $zpack->pack('img/screen_1.png'); $zpack->pack('img/screen_2.png'); $zpack->pack('css/alotofstyles.css'); $zpack->pack('js/cooljs.js'); $zpack->close(); include 'content.html';
Тут, собственно, тоже нет ничего особо интересного: создаем объект ZipLogic, перечисляем все ссылки на ресурсы, которые нужно упаковать, закрываем объект, подключаем конечную html’ку. В результате в папке current создается архив latest.zip, который содержит в себе все нужные ресурсы(см. ziplogic.php).
По хорошему, использовать его нужно перед публикацией страницы, каждый раз генерировать нет смысла.
Ну и на закуску — сама html’ка. Верстку не критиковать, пожалуйста — ее здесь нет.
content.html:
<script src="js/jquery-1.9.1.js"></script> <script src="js/jszip.min.js"></script> <link type="text/css" zpack="css/alotofstyles.css" rel="stylesheet"> <script zpack="js/cooljs.js"></script> <style> body{margin: 0;} </style> <div id="loader" style="position: absolute; width: 100%; height: 100%;background: rgba(148, 148, 148, 1);"> <img src="" style=" position: relative; top: 50%; left: 50%; height: 25px; width: 250px; margin-left: -125px; margin-top: -12.5px; "> </div> <img zpack="img/screen.png"/> <img zpack="img/screen_1.png"/> <img zpack="img/screen_2.png"/> <script> function getBinary(url, callback){ var oReq = new XMLHttpRequest(); oReq.open("GET", url, true); oReq.responseType = "arraybuffer"; oReq.onload = function (oEvent) { var arrayBuffer = oReq.response; if (arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer); callback(byteArray); } }; oReq.send(null); } function unpackResources(data){ var pack = new JSZip(); pack.load(data); $.each(pack.files, function(k, v){ var blob = new Blob([pack.file(k).asArrayBuffer()], {type: 'application/octet-binary'}); var url = URL.createObjectURL(blob); $('[zpack="'+k+'"').each(function(){ switch($(this).prop("tagName").toLowerCase()) { case 'img' : $(this).attr('src', url); break; case 'script' : $(this).attr('src', url); break; case 'link' : $(this).attr('href', url); break; case 'a' : $(this).attr('href', url); break; } }); }); } $(document).ready(function(){ getBinary('current/latest.zip', function(data){ unpackResources(data); $('#loader').hide(); }); }); </script>
Тут стоит описать чуть подробнее.
Функция getBinary, если не ошибаюсь, честно сперта со stackoverflow. Скачивает архив и передает полученный массив байт в callback.
Функция unpackResources, собственно, и делает основную часть работы: обрабатывает содержимое архива, вытаскивает пути, находит все элементы, ресурсы в которых помечены через zpack, создает соотв. blob и подгружает его в нужный элемент.
Пока все это добро не подгрузится, висит загрузчик.
В итоге получаем довольно простой код, позволяющий упаковать большое количество ресурсов в 1 архив и распаковать его на стороне клиента.
Спасибо за внимание, комментарии и идеи крайне приветствуются, критика без использования слов «идиот» и «криворукий ламер» — тоже.
ссылка на оригинал статьи http://habrahabr.ru/post/232823/
Добавить комментарий