规则8 使用外部JavaScript和CSS
1. 内联 VS 外置
a. 纯粹而言,内联快点,因为内联的组件http请求少,虽然合一并行下载组件,但总之外置要慢;
b. 然而由于JavaScript和CSS外部文件可以被缓存,HTML文档的大小减小,而且不会增加HTTP请求的数量;
c. 比较依赖于页面查看(一次会话查看次数和查看周期)、空缓存VS完整缓存、组件重用。
2. 组件重用---JavaScript和CSS作为外部文件可以被组件重用
a. 为每个页面提供一组分离的外部文件---每个页面都要强制用户使用另外一组外部组件并产生HTTP请求;(一般一次会话只访问网站一个页面)
b. 创建一个单独的、联合所有的JavaScript文件和CSS文件;(一次会话访问网站多个页面)
c. 折中:将页面划分为几种页面类型,然后为没中类型创建单独的脚本和样式表。这比维护一个单独的文件要复杂,但通常比为每个页面维护不同的脚本和样式表要容易,并且对给定的任意页面都只需下载很少多余的JavaScript和CSS。---决定组件重用程度
3. 主页---内联方式更好
页面查看:拥有很高的页面查看数量,然而每次会话只有一个页面查看;
空缓存 VS 完整缓存:完整缓存的百分比低,处于安全考虑,很多用户选择每次关闭浏览器时清空缓存;
组件重用:很多主页是用户来到网站访问的唯一页面。并不是所有主页都这样,所以作为多次后续页面查看的第一次的主页,我们希望为主页内联JavaScript和CSS,但又能为后续页面查看提供外部文件。---加载后下载 或 动态内联
4. 加载后下载
<script>
function doOnload(){
setTimeout("downloadComponents", 1000) ;
}
window.onload = doOnload ;
function downloadComponents(){
downloadJs("test.js") ;
downloadCSS("test.css")
}
function downloadJs(url){
var elem = document.createElement("script") ;
elem.src = url ;
document.body.appendChild(elem) ;
}
function downloadCSS(url){
var elem = document.createElement("link") ;
elem.rel = "stylesheet" ;
elem.href = url ;
document.body.appendChild(elem) ;
}
</script>
必须处理双重定义:脚本不能执行函数,CSS不能使用相对单位(% or em)。更好的方式是将这些组件放到一个不可见的Iframe中。
5. 动态内联
主页服务器不知道组件是否缓存在浏览器中,可以cookie可以指示浏览器中是否有主页缓存,有则使用缓存,没有则先内联再下载。
<?php
if($_COOKIE['CA']){
echo <<<OUTPUT
<link rel="stylesheet" href="test.css" type="text/css">
<script src="test.js"></script>
OUTPUT;
}
else{
echo "<style>\n".file_get_contents("test.css")."</style>\n" ;
echo "<script type=\"text/javascript\">\n".file-get_contents("test.js")."</script>\n" ;
echo <<<ONLOAD
<script>
function doOnload(){
setTimeout("downloadComponents", 1000) ;
}
window.onoad = doOnload ;
function downloadComponents(){
document.cookie = "CA=1" ;
downloadJs("test.js") ;
downloadCSS("test.css")
}
function downloadJs(url){
var elem = document.createElement("script") ;
elem.src = url ;
document.body.appendChild(elem) ;
}
function downloadCSS(url){
var elem = document.createElement("link") ;
elem.rel = "stylesheet" ;
elem.href = url ;
document.body.appendChild(elem) ;
}
</script>
ONLOAD
}
?>
即便cookie状态和缓存状态不匹配,页面也能工作。基于会话的cookie在下次会话中即便缓存中有主页还是会内联主页,可以将cookie改为短期cookie解决这个问题。但是无论如何,页面都能正常工作,并且最大限度的只能选择内联后下载还是直接使用缓存的外部文件。