引入:
上文中我们已经提到了如果设置了css_fast_load=1,会进入Minifier Filter之后,对minifyCss方法进行调用,而如果设置css_fast_load=0,那么就算进入Minifier Filter,也不会对minifyCss方法进行调用。我们这片文章的重点是研究这个方法。
调试分析:
从这里可以看出,从宏观上,这个方法先会去读取原始迷你化之前的css文件(比如我们的platform-In-theme/css/main.css)文件,
然后调用aggregateCss()方法来递归的聚合css,这个方法是递归方法,会递归的吧多个资源文件合并到一个文件中。我们来看下它的实现:
public static String aggregateCss(String dir, String content)
throws IOException {
StringBuilder sb = new StringBuilder(content.length());
int pos = 0;
while (true) {
int commentX = content.indexOf(_CSS_COMMENT_BEGIN, pos);
int commentY = content.indexOf(
_CSS_COMMENT_END, commentX + _CSS_COMMENT_BEGIN.length());
int importX = content.indexOf(_CSS_IMPORT_BEGIN, pos);
int importY = content.indexOf(
_CSS_IMPORT_END, importX + _CSS_IMPORT_BEGIN.length());
if ((importX == -1) || (importY == -1)) {
sb.append(content.substring(pos, content.length()));
break;
}
else if ((commentX != -1) && (commentY != -1) &&
(commentX < importX) && (commentY > importX)) {
commentY += _CSS_COMMENT_END.length();
sb.append(content.substring(pos, commentY));
pos = commentY;
}
else {
sb.append(content.substring(pos, importX));
String importFileName = content.substring(
importX + _CSS_IMPORT_BEGIN.length(), importY);
String importFullFileName = dir.concat(StringPool.SLASH).concat(
importFileName);
String importContent = FileUtil.read(importFullFileName);
if (importContent == null) {
if (_log.isWarnEnabled()) {
_log.warn(
"File " + importFullFileName + " does not exist");
}
importContent = StringPool.BLANK;
}
String importDir = StringPool.BLANK;
int slashPos = importFileName.lastIndexOf(CharPool.SLASH);
if (slashPos != -1) {
importDir = StringPool.SLASH.concat(
importFileName.substring(0, slashPos + 1));
}
importContent = aggregateCss(dir + importDir, importContent);
int importDepth = StringUtil.count(
importFileName, StringPool.SLASH);
// LEP-7540
String relativePath = StringPool.BLANK;
for (int i = 0; i < importDepth; i++) {
relativePath += "../";
}
importContent = StringUtil.replace(
importContent,
new String[] {
"url('" + relativePath,
"url(\"" + relativePath,
"url(" + relativePath
},
new String[] {
"url('[$TEMP_RELATIVE_PATH$]",
"url(\"[$TEMP_RELATIVE_PATH$]",
"url([$TEMP_RELATIVE_PATH$]"
});
importContent = StringUtil.replace(
importContent, "[$TEMP_RELATIVE_PATH$]", StringPool.BLANK);
sb.append(importContent);
pos = importY + _CSS_IMPORT_END.length();
}
}
return sb.toString();
}
从上面可以看出,它先会先把所有的@import url()这种外部导入的文件递归的导入,合并为一个大的css文件:
然后调用重载的minifyCss()方法,吧刚才产生的合并后的content,以及这个目标文件的真实路径作为入参传递进去:
然后调用DynamicCSSUtil的parseSass方法,吧这个合并的css文件中的全部Sass语法解析掉,成为一个普通的大的css文件。
紧接着,它会调用如下代码:
If(!browserId.equals(BrowserSniffer.BROWSER_ID_IE)
Matcher matcher= _pattern.matcher(content);
Content=matcher. replaceAll(StringPool.BLANK);
}
这段代码是消除ie的负面css影响。
然后再调用私有的重载的minifyCss方法,这是利用YuiCompressor的CssCompressor对于刚才的大的css文件进行压缩,变为小的css文件。最后结果放入输出流。
压缩前的css文件:
压缩后的css文件:
对比下,发现注释被去掉了,一些该合并的被合并了,尺寸被大大缩小了
最后吧这个结果放入ServletOutputStream中,我们和最终返回到页面上的比较,发现是完全一致的。
总结:
从以上简单的分析中我们可以有以下结论:
(1)minifyCss会先把所有的@import url()外部进入的css文件递归插入。
(2)其次,它会吧插入完的大的css文件中利用parseSass()方法去除其中的sass标记,还原为普通css文件。
(3)再次它会消除ie的特殊行为。
(4)最后它会用yui-compressor对于这个css文件进行压缩,包括合并相似样式,去除注解,去除空白等。
转载于:https://blog.51cto.com/supercharles888/1284092