.foo { color : red; font-size: 16px; height: 20px; } .bar { color : red; font-size: 16px; height: 30px; }
要压缩到:
.foo,.bar { color : red; font-size : 16px; } .foo { height : 20px; } .bar { height : 30px; }
要明确的是,我知道的所有minifier,如YUI Compressor,只能删除空格,并可能加入一些属性(如font-family和font-size).我正在寻找一些愿意完全重写文件结构的东西.
如果有人知道任何人对这个背后的压缩逻辑所做的任何工作都知道,那么这个信息将不胜感激.如果我找不到自己,我正在想自己写,但有一百万件事情要考虑,比如边际翻译部分的边际,选择器特异性和包括订单等等…然后如何有效地压缩信息的工作,像重复选择器或财产更有效率?
解决方法
建立
>展开你的CSS(边距:1px 0 0 0;到margin-top:1px; margin-left:0px; …).
>用V作为顶点的集合构建G =(V,E),E作为边的集合:
> V由两个集合A(唯一选择器,例如div,p> span,#myid)和B(唯一属性,例如display:block; color:#deadbeef;)组成.
> E由选择器(在A中)和属性(在B中)之间的所有关联组成.
在b中使用适当的权重函数c作为元素.这可以是给定元素b的相邻数量或累积的属性长度 – 选择器的累积长度.你的选择.
您可能会注意到,通过使用这种方法,您将得到一个二分图.现在尝试以下贪心算法(伪代码):
算法
>取B中具有最大权重的元素b,并将其添加到空集Z
>检查B中的另一个元素d是否具有相同的权重
>如果这样的d存在检查它是否覆盖相同的选择器.
>如果d覆盖相同的选择器:将d添加到Z并转到步骤2.
>如果d不覆盖相同的选择器,请检查相同重量的下一个元素,或者如果您检查了所有元素,则转到步骤3.
现在Z是覆盖一些选择器的一组属性.将其解析为CSS缓冲区.
删除Z中Z及其相邻边的所有元素,并删除Z本身.
>如果B不为空,请执行步骤1.
>您的缓冲区包含一个预先精简的CSS代码.您现在可以合并一些属性(例如margin-top:0px; margin-left:1px).
备注
请注意,实际压缩取决于您的重量功能.因为它是一个贪心的算法,它可能会返回一个最小的CSS,但我相信有人会发布一个反例.还要注意,删除Z中的元素后,必须更新您的权重函数.
运行时间估计
如果我没有错误,算法将永远终止,并将在O(| B | ^ 2 * | A |)中运行.如果您使用堆并对每个邻接列表中的属性进行排序(设置时间O(| B | * | A | log(| A |))),您将得到O(| B | * | A | * | B |)log(| A |))).