jmeMedlem sedan maj 20012 237 inlägg Hej.
Jag tänkte laborera lite med optimering av javascript och css filer.
Grundidén är att en webbsida har ofta ett antal js och css filer som laddas in vid varje sidanrop. Givetvis cachas dessa hos webbläsaren men man kan få ut lite extra boost genom att packa ihop (ta bort kommentarer osv) och sammanfoga dessa till en enda fil (packad.js, packad.css).
Hur har ni löst detta? Känner ni till bra färdiga script som hanterar detta?
Tanken är att man kan via ett administrativt gränssnitt välja, om man vill optimera eller inte.
För sakens skull kan jag nämna att jag kör med Zend Framework.
Tar gärna emot förslag och tips!
Något som man kanske lätt missar är att http har inbyggt stöd för komprimering. Kolla här t ex:
http://headphono.us/2007/05/07/how-to-load-your-site-faster-http-compression/
Om du använder jQuery finns det en "minifierad" version av biblioteket. Liknande finns säkert för andra ramverk.
jmeMedlem sedan maj 20012 237 inlägg Vad jag menar med komprimering i detta fall är att man först tar bort onödiga tecken osv från js och css filerna. T ex kommentarerna är ju oväsentliga för parsern, men de tar plats och bandbredd. Sedan kan man givetvis packa DESSA modifierade filer med vad som nu stöds av systemet (t ex just det som du nämde).
Jag vill alltså:
filA.css
filB.css
filC.css
->
joined.css
filA.js
filB.js
->
joined.js
Så istället för att ha femtioelva css och js includes i html-filen så har jag två, en för css och en för js! :)
EDIT: jag hittade följande artikel:
http://www.catswhocode.com/blog/3-ways-to-compress-css-files-using-php
Kanske nåt att använda....
Nate.AMedlem sedan mars 2006296 inlägg Jag brukar använda en JS-packer till mina js-filer när allt är klart. http://dean.edwards.name/packer/
Sedan kan man använda apache's gzipkomponent för att packa filerna innan de skickas till klienten http://www.samaxes.com/2008/04/htaccess-gzip-and-cache-your-site-for-faster-loading-and-bandwidth-saving/
jmeMedlem sedan maj 20012 237 inlägg Nate.A
EDIT: inget. Man kan ju ladda ned den också.
ercizMedlem sedan maj 20011 826 inlägg Det kan också vara bra att skicka javascript, css och andra statiska filer från en annan domän eller subdomän ifall man använder nån form av cookie-data. Då skickas nämligen inte cookien med hela tiden, vilket kan snabba upp kommunikationen lite.
dAEkMedlem sedan feb. 20041 816 inlägg
erciz skrev:
Det kan också vara bra att skicka javascript, css och andra statiska filer från en annan domän eller subdomän ifall man använder nån form av cookie-data. Då skickas nämligen inte cookien med hela tiden, vilket kan snabba upp kommunikationen lite.
Dessutom kan webbläsarna ladda ner övrigt innehåll parallellt.
SPiNMedlem sedan mars 20007 896 inlägg Jag har också laborerat lite med detta, och skapat en FileProvider-klass till ett eget ramverk (finns under sidan i min sign.). Det fungerar faktiskt riktigt bra, jag YUI-komprimerar även JavaScript och CSS innan jag sätter projekt i produktion.
Klassen i nästan sin helhet (ett par omskrivningar har jag bara gjort för bättre förståelse);
<?php
/**
* Bw Framework File Provider Class
*
* Bw Framework :: Lightweight MVC Framework, in an easy-to-use suit
* using Smarty as template engine
*
* PHP version 5.3 >
*
* (c) Copyright 2009, Björn Wikström
* (c) Copyright of third party software [Smarty], PHP Group
* (c) Copyright of third party software [FirePHP], Christoph Dam
*
* @category BwFramework
* @package BwFramework
* @author Björn Wikström <bjorn@bwit.se>
* @license http://www.gnu.org/copyleft/lesser.html LGPL, Lesser General Public License
* @version 1.0
* @link http://dev.bwit.se/framework
*/
/**
* BwFramework File Provider Class
*
* This class is used gzipping and caching css and javascript
*
* @category BwFramework
* @package BwFramework
* @author Björn Wikström <bjorn@bwit.se>
* @license http://www.gnu.org/copyleft/lesser.html LGPL, Lesser General Public License
* @version 1.0
* @link http://dev.bwit.se/framework
*/
class FileProvider
{
/**#@+
* @access const
*/
const CSS = 'css';
const JS = 'javascript';
/**#@-*/
/**#@+
* @access private
*/
private $_type;
private $_charset;
private $_extension;
private $_cache;
private $_assets;
/**#@-*/
/**
* This method starts the file provider
*
* @param string $type The type of the files to be provided - css/js
* @param string $files The files to be provided, separated by comma
* @param string $charset The charset to be transferred in
*
* @access public
* @return void
*/
public static function provide($type, $files, $charset = 'UTF-8')
{
$fp = new FileProvider();
$fp->_start($type, str_replace(' ', '', $files), $charset);
}
/**
* Private constructor
*
* @access constructor
*/
private function __construct()
{
}
/**
* Set up file paths and creating cache
*
* @param string $type The type of the file to be provided - css/js
* @param string $files The files to be provided, separated by comma
* @param string $charset The charset to be transferred in
*
* @access private
* @return void
*/
private function _start($type, $files, $charset = 'UTF-8')
{
$this->_cache = '/non-www-accessible-cache-folder/';
$this->_assets = '/javascript-and-css-folder/';
$this->_type = $type;
$this->_charset = $charset;
if ($type == 'css') {
$this->_extension = '.css';
} else {
$this->_extension = '.js';
}
ini_set("zlib.output_compression", "Off");
if ($this->_getLatestModTime(explode(',', $files)) > $this->_getLatestCachingTime($type) || !file_exists($this->_cache . $this->_type)) {
$this->_createCache(explode(',', $files));
}
$this->_output();
}
/**
* Get the latest modification time of the files
*
* @param array $files The files to be provided
*
* @access private
* @return int
*/
private function _getLatestModTime(array $files)
{
$latestModTime = 0;
foreach ($files as $file) {
if (!file_exists($this->_assets . $this->_type . DIRECTORY_SEPARATOR . $file . $this->_extension)) {
$latestModTime = 0;
break;
}
$currentModTime = @filemtime($this->_assets . $this->_type . DIRECTORY_SEPARATOR . $file . $this->_extension);
if ($currentModTime > $latestModTime) {
$latestModTime = $currentModTime;
}
}
return $latestModTime;
}
/**
* Get the latest modification time of the cache
*
* @param string $type The type of the files to be provided
*
* @access private
* @return int
*/
private function _getLatestCachingTime($type)
{
return @filemtime($this->_cache . $type);
}
/**
* Create a cache of the files and their contents
*
* @param array $files The files to be provided
*
* @access private
* @return void
*/
private function _createCache(array $files)
{
ob_start();
foreach ($files as $file) {
if (!file_exists($this->_assets . $this->_type . DIRECTORY_SEPARATOR . $file . $this->_extension)) {
continue;
}
readfile($this->_assets . $this->_type . DIRECTORY_SEPARATOR . $file . $this->_extension);
}
$content = ob_get_contents();
ob_end_clean();
$pointer = @fopen($this->_cache . $this->_type, 'w');
@fwrite($pointer, $content);
@fclose($pointer);
$pointer = @fopen($this->_cache . $this->_type . '.gz', 'w');
@fwrite($pointer, gzencode($content, 9, FORCE_GZIP));
@fclose($pointer);
}
/**
* Output the merged files to the client, with gzip compression if
* the client can decompress them - plain text otherwise
*
* @access private
* @return void
*/
private function _output()
{
header("Content-Type: text/" . $this->_type . "; charset=" . $this->_charset);
header("Cache-Control: must-revalidate");
header("Expires: " . gmdate('D, d M Y H:i:s', time() + (3600 * 12)) . " GMT");
if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
header("Content-Encoding: gzip");
header("Content-Length: " . filesize($this->_cache . $this->_type . '.gz'));
readfile($this->_cache . $this->_type . '.gz');
} else {
header("Content-Length: " . filesize($this->_cache . $this->_type));
readfile($this->_cache . $this->_type);
}
die();
}
}
Jag orkade inte klippa ned det till det mest vitala, men undrar du något ska jag försöka ta ork till mig och svara. ;)
LedelMedlem sedan dec. 2004736 inlägg Googles Closure Compiler för JavaScript verkar riktigt bra tycker jag, vill minnas att jQuery numer använder den för att packa biblioteket.
http://closure-compiler.appspot.com/home
SPiNMedlem sedan mars 20007 896 inlägg Jag hade inte sett Googles Closure Compiler, trevligt. Dock verkar den inte vara något "jätteextra" om man jämför med YUI - jag tjänade ingenting med SIMPLE_OPT. Med ADVANCED_OPT tjänade jag dock mellan 1-2 kb på ett mindre JS-dokument (~10kb), dock fick jag varningar då.