Liferay 中Minifier Filter的minifyCss 奥秘窥探
引入:
上文中我们已经提到了如果设置了css_fast_load=1,会进入Minifier Filter之后,对minifyCss方法进行调用,而如果设置css_fast_load=0,那么就算进入Minifier Filter,也不会对minifyCss方法进行调用。我们这片文章的重点是研究这个方法。
调试分析:
从这里可以看出,从宏观上,这个方法先会去读取原始迷你化之前的css文件(比如我们的platform-In-theme/css/main.css)文件,
然后调用aggregateCss()方法来递归的聚合css,这个方法是递归方法,会递归的吧多个资源文件合并到一个文件中。我们来看下它的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
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文件。
紧接着,它会调用如下代码:
1
2
3
4
|
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文件进行压缩,包括合并相似样式,去除注解,去除空白等。
Liferay 中Minifier Filter的minifyCss 奥秘窥探相关推荐
- Liferay Dynamic CSS Filter方法的研究 - 总体过程
背景知识: 最近项目组遇到一个问题就是改了一个new theme之后导致某些css文件不起作用了,这也激起了我的好奇心,让我有机会去研究下Liferay Dynamic CSS Filter的原理. ...
- SpringBoot学习之路:09.Spring Boot中添加Filter应用
2019独角兽企业重金招聘Python工程师标准>>> 上篇文章中说了SpringBoot中是如何使用servlet的,本文将讲解在SpringBoot中对过滤器Filter的实现 ...
- Java Web中的Filter和Interceptor的区别
2019独角兽企业重金招聘Python工程师标准>>> 1.问题的来源 项目中使用了Filter,进行白名单的控制,同时使用了Filter进行了跨域请求的控制,使用了Intercep ...
- javaweb过滤器_JavaWeb技术(2):SpringMVC中的Filter
Filter顾名思义就是过滤器,在JavaWeb体系中,他在服务端,卡在请求/响应与Servlet之间做一些操作: 过滤器相关的类的顶层接口如下,以下方法都由Web容器自动调用: package 你可 ...
- vue 中的el表达式_Vue中vue.filter()的使用方法介绍(过滤)
本篇文章给大家带来的内容是关于Vue中vue.filter()的使用方法介绍(过滤),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. Vue过滤器 {{msg |msgFormat}} ...
- web.xml 中的filter
Servlet API的2.3版本中最重要的一个新功能就是能够为servlet和JSP页面定义过滤器.过滤器提供了某些早期服务器所支持的非标准"servlet链接"的一种功能强大且 ...
- Python3中的 Filter的改变
在python3中,filter处理之后,变成了一个可迭代对象,解决办法有2中: ① 切成python2 ② 在filter外面套一层list df = df.dropna() lines=df.co ...
- JS中 map, filter, some, every, forEach, for in, for of 用法总结
for.for in和for of和forEach的区别:http://blog.sina.com.cn/s/blog_c112a2980102xqg9.html JS中 map, filter, s ...
- 数组中的filter方法_数组filter()方法以及JavaScript中的示例
数组中的filter方法 JavaScript filter()方法 (JavaScript filter() method) filter() method is used to returns a ...
最新文章
- 项目管理ppt_「PPT」几近满分的项目管理PPT干货
- 60幅精美绝伦的绘景(Matte Paintings)作品欣赏(上篇)
- C语言实现斐波那契搜索Fibonacci search算法(附完整源码)
- element UI 单选框设置默认选中值
- 扩展CheckBoxList实现选中绑定
- ssl证书的生成与签名
- 巧用DBGrid控件的Sort属性实现“点击标题栏自动排序功能”。(改进版本)
- bootstrap 输入错误提示_网上体育用品商城(ssm,mysql,bootstrap,html,css)
- Linux拷贝分区内容,dd复制分区后目标分区的大小变成原分区了
- linux info命令详解,Linux info 命令简介
- 习题--答案--22/6/8
- 用《圣经》做训练数据集,达特茅斯学院完美打造语言风格转换工具
- 电影《失控玩家》:软件2.0,让游戏角色“觉醒”了?
- RK3399平台开发系列讲解(其他篇)1.31、 什么是虚拟化
- 牛客每日练习----あなたの蛙が帰っています,おみやげをまらいました,写真がとどいています
- MacOS使用conan
- 使用Requests库+re库爬取猫眼电影评分
- 遥感影像分类算法C++实现(一)
- 英国python工资_就业强势起薪高?英国BA硕士哪家强?!
- FGH60N60SMD 60A600V IGBT单管在工业逆变应用中的解决方案
热门文章
- xib加载的两种方式
- 大数据之-Hadoop3.x_MapReduce_二次排序案例---大数据之hadoop3.x工作笔记0116
- C++提高部分_C++普通函数与函数模板的区别---C++语言工作笔记084
- 持续集成部署Jenkins工作笔记0011---配置构建命令并手动执行一次构建
- 移动APP开发工作笔记002---Hbuilder js判断当前设备是安卓设备还是苹果设备
- Android零碎要点---eclipse两个小技巧
- Android学习笔记06---电话拨号器的制作:项目结构深化
- JPA学习笔记---JPA理解---第一个JPA程序
- resnet18 参数解读
- CSS样式重叠,前端显示的效果