| | | | |
| |||||||
| PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen |
|
| | LinkBack | Themen-Optionen | Thema bewerten |
| | |
| Gast
Beiträge: n/a
| Ich stelle diese Frage im Profi-Forum weil ich hoffe dass sie für Profis anspruchsvoll genug ist. Ich habe diese Frage auch schonmal anderswo gestellt, aber da das hier ein auf PHP spezialisertes Forum ist sind meine Chancen auf Antworten vermutlich besser ![]() Gleich eines vorweg: Dier hier ist ein etwas längerer Beitrag. --- (so, jetzt geht's los) Ich arbeite schon seit längerem an einem PHP-CSS Parser und Optimierer, wer sich den mal angucken möchte kann das tun. Nun möchte ich für die nächste Version einen Fehler beheben, dieser ist allerdings etwas komplizierter als er aussieht. Wenn man dem Optimierer jetzt folgendes zum Verarbeiten gibt... Code: b {color:red;}
c,b {color:green;}
a {color:red;}
Code: c,b {
color:green
}
b,a {
color:red
}
Richtig wäre es natürlich so: Code: b,c {color:green;}
a {color:red;}
Um das Problem also richtig zu beheben, müsste der Optimierer zuerst die Selektoren zerlegen und anschließend wieder richtig zusammenfassen. Das Zerlegen stellt kein Problem dar, wohl aber das Zusammenfassen. Kleiner Hinweis für alle nicht CSS-Experten: Selektoren können mit Code: explode(',',$selectoren);
Um das CSS dann sinnvoll zusammenzufassen habe ich mir gedacht, dass zuersteinmal die Größe der Gemeinsamkeiten mehrerer Selektoren herausgefunden werden muss (um "intelligent" das zu optimieren was den größten "Gewinn" bringt) und welche Übereinstimmungen das genau sind. Dafür habe ich auch schon eine Funktion geschrieben, die zwar fast perfekt funktioniert, allerdings schnell jegliche Zeit- und Speicherlimits überschreitet (abhängig von der Größe des CSS Codes). Was ich also jetzt ganz gerne hätte wäre ein Vorschlag wie man meine Funktion deutlich beschleunigt oder einen komplett neuen Ansatz von mir aus auch. Jetzt erstmal die konkreten Informationen: Struktur der Daten Die Daten in denen das CSS gespeichert wird, sehen etwa so aus: Code: $css['standard']['a'][]['color'] = 'red'; $css['standard']['a'][]['size'] = '1em'; $css['standard']['b'][]['size'] = '1em'; // also $css[MEDIUM][SELEKTOR][ZAHL][EIGENSCHAFT] = WERT "standard" steht für keinen Medium-Typ. Bisherhige Funktion Das hier ist meine Funktion (das ultimative foreach-Chaos), hoffentlich gut genug kommentiert. Vorraussetzung ist, dass beim ersten Durchlauf keine Selektoren wie "a,b" oder "a,b#id,c" etc. vorhanden sind, bzw. diese zerlegt sind (dafür kann der Rest meines CSS Parsers garantieren). Wer alles im Zusammenhang sehen möchte: http://cdburnerxp.se/cssparse/css_parser.txt Die Funktion ist da komplett drin, wer will kann den Parser damit mal durchlaufen lassen (in der Klasse die Funktion parse($string) [diese "Superoptimierung" wird automatisch mit ausgeführt], das Ergebnis als Array befindet sich danach in der Variable $css). Hier jetzt die Funktion mit Kommentar: Code: function merge_selectors(&$css)
{
$return = FALSE;
Code: foreach($css as $medium => $vali)
{
$diff = array();
$diff_c = array();
Code:
foreach($vali as $selector => $valj)
{
Code: foreach($valj as $num_key => $valk)
{
foreach($valk as $property => $value)
{
Code: foreach($css[$medium] as $selector2 => $vall)
{
Code: $selector_combine_r = serialize(array($selector2,$selector)); Hier wird also die serialisierte Form der Selektoren 1 und 2 in umgekehrter Reichenfolge gespeichert, womit wir... Code:
// Prevent duplicate comparisions (a-b, b-a) and self-comparisons (a-a)
if($selector2 === $selector || isset($diff[$selector_combine_r]))
{
continue;
}
Code:
$selector_combine = serialize(array($selector,$selector2));
if(!isset($diff[$selector_combine]))
{
$diff[$selector_combine] = 0;
$diff_[$selector_combine] = array();
}
Code:
foreach($vall as $num_key2 => $valm)
{
foreach($valm as $property2 => $value2)
{
Code: if($property2 === $property && $value2 === $value)
{
$diff[$selector_combine] += (strlen($property)+strlen($value));
$diff_c[$selector_combine][][$property] = $value;
}
Code: }
}
if($diff[$selector_combine] === 0)
{
unset($diff[$selector_combine]);
unset($diff_c[$selector_combine]);
}
Code: } } } } Code: // Move best matches to the top array_multisort($diff,SORT_NUMERIC,SORT_DESC); Code:
foreach($diff as $key => $value)
{
$key_u = unserialize($key);
foreach($key_u as $selector)
{
// If there are no matches or if selector is already dissolved
if(!isset($diff_c[$key]) || !isset($css[$medium][$selector]))
{
continue;
}
Code:
foreach($diff_c[$key] as $num_key => $valj)
{
foreach($valj as $property => $value)
{
rm_subkey($property,$css[$medium][$selector],$value);
}
}
Code:
// If no properties are left, remove selector
if(empty($css[$medium][$selector]))
{
unset($css[$medium][$selector]);
}
Code:
// Create the new selector if matches are left
if(!empty($diff_c[$key]))
{
$css[$medium][implode(',',$key_u)] = $diff_c[$key];
$return = TRUE;
}
Code: }
// Go through diff_c and remove no-more-shareable properties
// and possibly the complete entry
foreach($diff_c as $keyi => $valuei)
{
$selectors = unserialize($keyi);
if(in_array($key_u[0],$selectors) || in_array($key_u[1],$selectors))
{
unset($diff_c[$keyi]);
}
}
Code: } } return $return; } Code: while(csspp::merge_selectors($this->css)) {}
Das einzigste was die Funktion noch beachten müsste ist, dass ein gewisses Verhältnis zwischen Größe der optimierten Eigenschaften und Anzahl der Selektoren erhalten bleibt (damit nacher nicht sowas wie Code: ein,ganz,langer,langer,................................,selektor{size:1em;(und ganz wenig Eigenschaften)}
Jetzt zum Abschluss nochmal ein kleines Beispiel für die Funktionsweise der Funktion: Das wird optimiert: Code: $css['standard']['a'][]['margin'] = '0'; $css['standard']['a'][]['color'] = 'red'; $css['standard']['a'][]['text'] = 'none'; $css['standard']['a'][]['text'] = '!important'; $css['standard']['b'][]['text'] = 'none'; $css['standard']['b'][]['color'] = 'red'; $css['standard']['d'][]['color'] = 'red'; $css['standard']['e'][]['margin'] = '2'; Code: Array
(
[a:2:{i:0;s:1:"a";i:1;s:1:"b";}] => 16
[a:2:{i:0;s:1:"a";i:1;s:1:"d";}] => 8
[a:2:{i:0;s:1:"b";i:1;s:1:"d";}] => 8
)
Code: Array
(
[a:2:{i:0;s:1:"a";i:1;s:1:"b";}] => Array
(
[0] => Array
(
[color] => red
)
[1] => Array
(
[text] => none
)
)
[a:2:{i:0;s:1:"a";i:1;s:1:"d";}] => Array
(
[0] => Array
(
[color] => red
)
)
[a:2:{i:0;s:1:"b";i:1;s:1:"d";}] => Array
(
[0] => Array
(
[color] => red
)
)
)
Code: Array
(
[standard] => Array
(
[a] => Array
(
[0] => Array
(
[margin] => 0
)
[3] => Array
(
[text] => !important
)
)
[e] => Array
(
[0] => Array
(
[margin] => 2
)
)
[a,b] => Array
(
[1] => Array
(
[text] => none
)
)
[d,a,b] => Array
(
[0] => Array
(
[color] => red
)
)
)
)
Ich hoffe auf zahlreiche Vorschläge |
|
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
| | |
| Erfahrener Benutzer Registriert seit: 21.05.2008
Beiträge: 387
![]() | Dass es da nichts zu entschlacken gibt war mir schon bewusst, das hatte ich ja auch geschrieben. Zum Zend-Optimizer: Ich würde an deiner Stelle einfach mal in einem WAMP testen, wie schnell deine Funktionen ohne Optimizer sind und dann einmal MIT Optimizer. Installiert ist das Ding unter Windows schnell und einfach. Download ist hier: http://www.zend.com/store/products/zend-optimizer.php an der rechten Seite. Leider muss man sich registrieren, aber das lohnt sich für den Optimizer meiner Meinung nach schon. Prüfen, ob es aktiv ist, kannst du mit der Ausgabe von phpinfo (); Dort müsste dann irgendwo stehen, dass ein Modul namens "Zend Optimizer" als Tabelle angezeigt werden (normalerweise direkt unter dem "PHP Core"). Dann ist er aktiv. Steht es nicht drin, dann ist er auch nicht aktiv. Ausprobieren würde ich es jedoch mal, um wirklich sicher zu gehen, ob und wenn ja wieviel es bringt. C++ wäre sicher schneller, nur kannst du es dann wieder schlechter auf einer Homepage anbieten... Alternativ höchstens noch ein Java-Applet, dass dann den Client benutzt, um das umzuwandeln und gleichzeitig ne Statusanzeige rausrückt!? Oder: Probier einfach mal PHP über die Shell zu starten und ein StyleSheet berechnen zu lassen. Vielleicht bringt das durch den Wegfall des Apaches noch wieder etwas mehr Performance!? |
| | |
| | |||
| Gast
Beiträge: n/a
| Zitat:
![]() Zitat:
| ||
|
| | |
| Erfahrener Benutzer Registriert seit: 21.05.2008
Beiträge: 387
![]() | Das kannst du nur aktivieren, wenn du root-Rechte am Server hast und die Config des Webservers ändern kannst. Dann ist es auch recht einfach, da wie in Windows auch hier eine Installations-Routine vorliegt. Du gehst unter den besagten Link, lädst für die entsprechende Linux-Version die Datei auf deinen Server, entpackst sie und startest die Installationsdatei (ich meine es war eine install.sh). Der Rest geht fast von alleine. Ein paar Pfade überprüfen, ob diese richtig erkannt wurden, nach der Installation (falls angegeben "fehlerfrei installiert") den Webserver neu starten und dann sollte es laufen. Wenn du ein WAMP hast empfehle ich jedoch erstmal dort zu testen, ob es überhaupt was bringt an Geschwindigkeit. Messe die Zeit mit microtime () und vergleiche. Am besten startest du immer im Wechsel mit und ohne Zend 10 mal das Script mit den selben Daten und errechnest dann einen Mittelwert. Je öfter du dies machst, desto genauer wird dein Ergebnis letztendlich, auch wenn es immer nur ein Näherungswert bleibt. Klar kannst du7 mit PHP auch nen C-Programm ansteuern, jedoch ist dann die Frage, wie sicher dein Script noch ist, wenn du z.B. exec () nutzt... *hust* |
| | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| JS: Einführung - Javascript im Schichtenmodell | nikosch | Tutorials | 4 | 11.04.2009 17:06 |
| Rekursive Funktion bricht ab... | duras666 | PHP Tipps 2008 | 9 | 28.04.2008 11:36 |
| gpc_quotes funktion: verbesserungsvorschläge? | Promaetheus | PHP Tipps 2007 | 10 | 12.08.2007 19:29 |
| variable in funktion | JanM | PHP Tipps 2006 | 2 | 23.07.2006 20:06 |
| Komplexe Funktion: +Übersichtlichkeit, -Performance | Jacks Rache | PHP Tipps 2006 | 3 | 07.06.2006 14:22 |
| Array in rekursiver Funktion auslesen | Gumfuzi | PHP Tipps 2007 | 17 | 15.11.2005 12:01 |
| PHP-GTK Tutorial | Beitragsarchiv | 9 | 02.11.2005 21:07 | |
| Rückgabewert einer rekrusiven Funktion | PHP-Fortgeschrittene | 7 | 06.10.2005 18:44 | |
| In einer Funktion auf eine Funktion der Klasse zugreifen | phpbeginner | PHP Tipps 2005-2 | 2 | 28.07.2005 00:30 |
| Funktion in einer Funktion aufrufen? | PHP Tipps 2005-2 | 11 | 14.06.2005 15:14 | |
| [Erledigt] Array-Übergabe in Funktion | PHP Tipps 2005 | 1 | 08.05.2005 21:05 | |
| [Erledigt] Variablen in eine Funktion übernehmen | PHP Tipps 2005 | 1 | 26.02.2005 17:19 | |
| [Erledigt] Wie kann ich beliebig viele Werte an eine Funktion übergeben | PHP Tipps 2005 | 11 | 25.01.2005 10:44 | |
| [Erledigt] sql syntax error in funktion, kann aber nix finden :( | PHP Tipps 2004 | 10 | 20.07.2004 19:19 | |
| Referenz auf Funktion übergeben | PHP-Fortgeschrittene | 7 | 20.07.2004 09:51 | |
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| css dateien zusammenfassen, css zusammenfassen, mehrere css zusammenfassen, css-dateien zusammenfassen, zend css zusammenfassen, css zusammenführen, css zusammenfassen php, css selektoren zusammenfassen, mehrere css dateien zusammenfassen, css automatisch zusammenfassen, php css zusammenfassen, css zusammenfassen automatisch, id selector zusammenfassen, css funktion, css doppelte selektoren finden, css zusammenfassen eigenschaften, css doppelte eigenschaften löschen, function in css, css unterobjekte, zend mehrere css zusammen fassen |

Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.