日期:2014-05-16  浏览次数:20370 次

liferay的js加载问题深度分析
今天遇到liferay一个很郁闷的问题
问题描述
在开发环境中,直接访问liferay系统,没有问题。
在运行环境中,经过一个中间系统转发,通过https来访问liferay系统,结果页面上出现很多js错误,并且有些功能不能使用。
解决思路
经过对页面的分析,发现页面存在css和js文件的缺失。
有点莫名其妙~~
比较两个环境,发现之后的环境与之前环境的区别为:经过了一次转发,以及使用了https。
确定是这个环境使访问liferay时缺失了某些js和css文件。
立即想考虑liferay是如何加载js和css文件的。
后来想到在配置文件中有网页内容传输以及js的相关配置,想试试对配置进行修改。
最后定位下来,是portal.properties下的属性 javascript.fast.load 在起作用。
设置 javascript.fast.load=false即可。
 
    #
    # Set this property to true to load the combined JavaScript files from the
    # property "javascript.files" into one compacted file for faster loading for
    # production. Set this property to false for easier debugging for
    # development. You can also disable fast loading by setting the URL
    # parameter "js_fast_load" to "0".
    #
    javascript.fast.load=false
该属性的含义:设置该属性为true,属性javascript.files中指定的js文件集将整合到一个文件中,进行压缩,然后加载,这样就能更快的加载。
如果设置为false,更容易在开发中进行调试。
也可以设置URL参数js_fast_load 为0,就不会快速加载。

深入分析
为了更具体比较把该参数设置为false之后的区别,
分别保存下设置为true和false之后的同一个页面。
发现设置为false时,在保存的那个页面文件夹中多了很多js文件。
仔细比较下载下来的js文件名称:
当设置为true时,下载了5个js文件。everything_packed.js文件的大小为4M多。
当设置为false时,下载了43个js文件,包含上述5个中的四个js,除了everything_packed.js。

跟踪加载js的过程:
首先查看处理js相关的文件:
1,在portal.properties中的js相关设置:
    javascript.files=\        设置js文件列表;
    javascript.fast.load=false
2,类com.liferay.portal.tools.JavaScriptBuidler中:
把javascript.files中的js文件列表合并到一个文件mergedFile中
	public JavaScriptBuilder(String jsDir, String mergedFile) {
		try {
			StringMaker sm = new StringMaker();

			String[] files = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);

			for (int i = 0; i < files.length; i++) {
				String content = FileUtil.read(jsDir + files[i]);

				sm.append(content);
				sm.append("\n");
			}

			FileUtil.write(mergedFile, sm.toString());
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

3,页面  /html/common/themes/top_js.jsp中:
该页面判断属性javascript.fast.load值,并根据取值分别处理。即设为true的时候,只需要加载everything.packed.js文件,当设为false时,则循环加载属性javascript.files中设置的文件列表。
<c:choose>
	<c:when test='<%= ParamUtil.getBoolean(request, "js_fast_load", PropsValues.JAVASCRIPT_FAST_LOAD) %>'>

		<%--
		everything_packed.js includes all of the JavaScript files. It is
		autogenerated with the Ant build-javascript task.
		--%>

		<script src="<%= themeDisplay.getPathJavaScript() %>/everything_packed.js?bn=<%= ReleaseInfo.getBuildNumber() %>" type="text/javascript"></script>
	</c:when>
	<c:otherwise>

		<%
		String[] javaScriptFiles = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);

		for (int i = 0; i < javaScriptFiles.length; i++) {
		%>

			<script src="<%= themeDisplay.getPathJavaScript() %>/<%= javaScriptFiles[i] %>?bn=<%= ReleaseInfo.getBuildNumber() %>" type="text/javascript"></script>

		<%
		}
		%>

	</c:otherwise>
</c:choose>

4,再看ant文件,portal-web/build.xml:
在部署时,把设置的js文件列表合并到文件everything_unpacked.js中,然后使用压缩处理类,压缩成文件everything_packed.js。
	<target name="build-javascript">
		<java
			classname="com.liferay.portal.tools.JavaScriptBuilder"
			classpathref="project.classpath"
			fork="true"
			newenvironment="true"
		>
			<arg value="docroot/html/js/" />
			<arg value="docroot/html/js/everything_unpacked.js" />
		</java>
		<