高性能网站建设指南 — 笔记– 8.将脚本放在底部
我们知道浏览器可以并行下载内容。 但脚本却会阻塞这种并行机制。 浏览器遇到脚本时,就不会另起线程下载别的组件。 所以,脚本应该放在最后,以让浏览器逐步呈现其他组件。 你不放最后也可以,可以通过“DEFER”脚本告诉浏览器:下载此脚本时不必阻塞其他组件(可惜的是,firefox不支持DEFER) 最后,还要注意到并不是所有脚本都可以放在最后。带了document.write的脚本就不行。
我们知道浏览器可以并行下载内容。 但脚本却会阻塞这种并行机制。 浏览器遇到脚本时,就不会另起线程下载别的组件。 所以,脚本应该放在最后,以让浏览器逐步呈现其他组件。 你不放最后也可以,可以通过“DEFER”脚本告诉浏览器:下载此脚本时不必阻塞其他组件(可惜的是,firefox不支持DEFER) 最后,还要注意到并不是所有脚本都可以放在最后。带了document.write的脚本就不行。
如果一个链接占一张图片,那么为了展现N个链接,就要让用户下载N张图片,也就是N个HTTP请求。 所以可以想办法在一张图片里嵌入多个链接,比如左少角放一个,右下角放一下。 具体的办法是 Image Map 和 CSS Sprites
不感兴趣,我本来就没用过这种表达式。以后再说。
把原有的多个样式表文件合成一个,可以使用户在浏览网页时只需下载一个CSS文件。这样减少了HTTP请求,速度自然就快了些。 Javascript文件也一样。 不过这样做似乎不符合模块化的开发原则。 本书作者提出的建议是:开发时仍用多个文件,部署时再把它们合并在一起。
script/css可以内联在HTML里,也可以放到外部文件中,哪种效率更高? 按理来说内联的效率应该更高。因为它没有新增HTTP请求。 但是,它也有个缺点,就是浏览器不会去缓存内联了的script/css 所以总的来说,还是用外部文件这种方式比较划算 话又说回来,首页可能是个例外。作为站长,你可能会希望首页的速度比其他页面要快,这时候可以考虑采用内联方案。
CDN是 Content Delivery Network的缩写。 通过把静态内容发部到多台服务器上,可以在用户访问时选择较近的服务器给予响应,以缩短响应时间。 比如说,把我们网站的静态内容发布到两台服务器上,一台放在教育网,另一台放在ChinaNet; 教育网用户将从前一台下载内容,公众网将从后一台下载内容。 可以自己搞CDN(如果有钱的话),也可以找CDN供应商。后者的缺点是你的系统发布受到供应商的约束,并且如果供应商当了,你也当了。
减少javascript中的空格或字符,缩小javascript代码的字节数,减少传输时间。 你可以 do minification(去掉字符及注释),也可以do obfuscation(缩短函数名和变量名的长度)。不过后者会导致完全不可读的代码,并且有可能出错。 用什么工具? JSMin 或 Dojo Compressor gzip压缩后还要精简吗? Yes. gzip压缩可以起到主要作用,但精简能够进一步减小文件大小 css可以精简吗? 可以。但可能没什么用,因为CSS里的空格和注释一般比较少。
通过Http头设置缓存,可以减少重复的HTTP请求 — 因为第二次下载时只需从浏览器缓存中去拿。 有两种头可以设置。 1. Expires: “此图片将在2010年12月30日过期,在此之前的重复请求可以使用浏览器中的缓存” 2. Cache-Control max-age: “在未来10年里都可以使用浏览器中的缓存来获得此图片” 第一种头用的是绝对时间,这就存在时钟同步的问题,而且真正到期后服务器端还要更新一下这个日期;第二种头的问题在于它不适用于只支持Http 1.0的浏览器 第三种方案是:如果你用的是Apache服务器,可以使用mode_expires指令来设置超时。它可以避免上述第二种方案的问题。 ============================================================================== 现在的问题是,如果静态内容真的变了,需要浏览器刷新缓存怎么办? 办法是修改静态内容的文件名。当它被请求时,浏览器中由于没有相应的缓存,所有就会请求服务器以重新下载。 当然这会带来版本管理上的负担。 ===================================================================== 注意:如果没有设置缓存头浏览器仍会试图通过缓存来提高效率;第二次请求一个图片时,浏览器会先发送一个 Conditional Get Request问一下此内容是否已被修改,如果没有的话就使用缓存。
Redirect导致新的HTTP请求,或多或少会浪费时间。 可以想法避免Redirect,比如 1.在链接里写 "www.yoursite.com/" 而不是 "www.yoursite.com",后者会产生一个redirect到前者 2.Prefer URL rewrite to redirect. Apache就支持URL Rewrite.
1.你的页面上有三个Widget,三个Widget依赖同一套数据集,但这些Widget所需要的数据组织方式各不相同。 这种情况下,你应该声明一个 Data对象还是三个? 我的体会是只使用一个比较好。这样需在刷新Widget时临时转换数据格式,但这比起建三个对象、然后维护三个对象之间的一致性 要简单的多。 2.当某个Widget往数据集里增一条数据时,依赖这套数据集的其他Widget应该根据这条 新数据微调一下界面 还是 把整个数据集重新读取一次并整个地刷新? 我的经验是 刷新整个数据集比较好。这种作法的性能虽然不如前一种,但它比较简单: Widget的展现逻辑只有一种,即读取当前所有数据,它不用针对数据的增、删、改分别提供处理逻辑;另一方面,这种作法也是Widget之间的解耦更彻底。