企鹅SEO干货分享:最新最全面的网站SEO优化前端解决方案都在这里
网站优化离不开前后端的互相协作,但是对于前端工程师来说,在保证后端技术方案不变时,能不能只利用前端技术来优化网站呢?答案是肯定。雅虎的邮件团队总结了常用的35条网站优化最佳实践,其中就有很多实践,只要我们前端人员在日常开发过程中遵循这些实践,就可以在一定程度优化网站加载速度。
本文篇幅较长,主要内容就是网站优化的35条最佳实践,以及对每条最佳实践的说明。技术文章看起来都是很枯燥,特别对于这种篇幅较长的文章,这里先列出来有哪些实践,不是每条实践的说明都要看,才能明白这个实践的意思。
80%的终端响应时间花费在前端,这其中的大部分时间又浪费在下载页面内容上,页面内容包括图片,样式表,脚本,flash等等。减少页面内容的数量,转而就减少了渲染页面需要的HTTP请求数量。这是优化页面的关键。
减少页面内容的一种方法是简化页面设计。但是是否存在其它方法既可以用丰富的内容来构建页面,又可以获取快速的相应时间呢?下面的几种技术即可以减少HTTP请求数量,又可以支持丰富的页面设计。
合并文件是一种减少HTTP请求的方式,通过合并多个Js文件到一个Js文件,合并多个CSS文件到一个CSS文件的方式。文件合并是非常有挑战性的,因为每个页面的和CSS都不一样,但是如果在你的发布过程中有这个步骤确实可以响应时间。
Image maps 合并多个图片到一个图片中。图片总大小是一样的,但是减少了一定数量的HTTP请求,加快了页面展示速度。只有当页面中的图片是连续的,Image maps才有用,例如导航栏。定义Image maps的坐标可能非常乏味并且也容易出错,为导航使用Image maps也不是很方便,所以不推荐这种方式。
Inline images 使用data:URL scheme把图片数据内嵌到当前页面中。这种方式会增加HTML文档的大小。把Inline images写到(缓存的)样式文件中是减少HTTP请求的同时避免增加页面大小的一种方法。Inline images还没有被所有的主流浏览器支持。
用户跟Web服务器的距离对相应时间是有影响的。从用户的角度来说,把你的内容部署在多个地理位置分散的服务器上有利于页面加载的更快。
实施内容分发,首先不要尝试把Web应用重构成分布式架构。根据不同的应用,改变架构可能会有艰巨的任务,比如在不同的服务器之前同步session状态,复制数据库事务。这样的话应用架构这一步可能就会导致这种尝试延迟。
记住80%到90%的终端响应时间花费在下载页面内容上面:iamges,css,js,flash等等,这是性能的黄金法则。而不是以重构web应用架构的艰巨任务开始,最好首先分散静态内容。这样不仅最大化的减少响应时间,而且利用内容分发网络可以变得更简单。
内容分发网络(CDN)是分布在多个地点的web服务器的集合,可以有效的为用户分发内容。给用户分发内容的服务器是根据网络距离选择的,例如,选择拥有最少网络跳转或者最快相应速度的服务器。
对于静态资源:实行永不过期策略,通过在header中把Expires设置尽量长点对于动态资源:使用一个适当的Cache-Control header帮助浏览器响应条件请求
页面设计的越来越丰富,这就意味着页面中有更多的js,css,images,falsh等。首次访问页面的用户可能会有几个HTTP请求,但是通过使用Expires header你可以使这些内容缓存。这样在后续页面访问时可以避免不必要的HTTP请求次数。Expires header经常和图片一起用,但是js,css,flash都可以使用。
谨记,如果你使用了Expires header,那么当你的文件内容有改变时,内容的文件名必须改变。这样内容才会更新。可以再文件名中加版本后,这样每次发布时文件名都会改变。
使用Expire header只会影响已经访问过你站点的用户。如果用户第一次访问站点或者浏览器还没有缓存,它不会减少HTTP请求次数。因此这种性能改善的影响依赖于用户是不是经常访问带缓存的页面。通过使用Expires header你可以让浏览器增加缓存内容数量,在后续页面访问时重用这些内容而不用在通过网络请求获取。
前端工程师做出的某些决定可以显著的减少HTTP请求以及响应的网络传输时间。终端用户的带宽速度,网络服务提供商,距网络交换节点的距离这些因素都不受开发团队的控制。但是仍有其它的因素会影响响应时间。比如,通过压缩HTTP响应来减少响应时间。
Gzip是目前最流行以及最有效的压缩方法。其它你有可能看到的压缩格式是deflate,但是它不是很流行以及很有效。
Gzip通常可以把响应内容大小减少70%。目前浏览器当中接近90%的网络流量支持gzip。
对于浏览器以及代理来说还有一个已知问题就是浏览器期望的内容和它获取的压缩内容可能不匹配。幸运的是,这种情况随着旧版浏览器的使用率越来越低会越来越少。Apache模块通过添加适当的不同响应头来解决这个问题。
服务端选择用Gzip压缩内容主要依赖于文件类型,但是通常也受限于要决定压缩的内容。大部分web站点用gzip压缩html文档。当然也值的压缩脚本以及样式文件,但是很多网站都没有选择这么做。事实上,可以用gzip压缩任何文本响应内容,包括XML和JSON。Image和PDF不建议gzip压缩,因为它们都是被压缩过的。试图压缩它们不仅浪费CPU也有可能会增加文件大小。
用gzip压缩尽可能多的文件类型是减少页面大小提升用户体验的一种简单方法。
把CSS文件移到文档的HEAD中看起来好像可以加快页面载入速度,其实这是因为把CSS文件放到HEAD中,可以让页面逐步渲染。
前端工程师可能只关注性能,希望页面可以逐步加载,但是对于用户来说,不管页面有多少内容,希望浏览器可以尽快的展示页面。对于页面内容很多以及用户网络环境不好的情况,这一点非常重要。给用户视觉反馈(例如进度提示)的重要性不言而喻,有很多类似的研究。当浏览器加载页面时逐步加载头部,导航栏,以及顶部logo等的过程,HTML页面就相当于进度提示,这样就给等待页面加载的用户一个视觉反馈。提高整体的用户体验。
如果把CSS文件放到页面底部,在很多浏览器中可能会影响逐步渲染过程,包括IE浏览器。因为这些浏览器会阻塞渲染过程以防页面元素样式改变时重绘元素。用户就会看到一个空白页。
脚本文件会导致的一个问题就是它们会阻塞并行下载。HTTP/1.1规范建议不要在一个主机上并行下载不超过两个脚本文件。如果把图片托管到多台主机上面,那就可以并行下载多个图片文件。但是当一个脚本文件正在下载时,浏览器不会下载其他的脚本文件,即便这个脚本文件在其它主机上面。
在有些情况下想要把脚本文件移动文档底部并不容易。例如如果脚本使用document.write插入页面内容,它就不能移到页面底部。这可能会引起作用域问题。在很多情况下,还有其它的途径解决类似的这种问题。
一个常用的建议就是使用延时脚本。的DEFER属性表明脚本不包含document.write,告诉浏览器可以继续渲染。但是也不是所有的浏览器都支持。Firefox不支持DEFER属性,IE对DEFER的支持也不尽如意。
如果脚本可以延迟加载,它就可以放到页面底部,这样就会加快页面的载入速度。
如上面展示的,expression方法接受一个js表达式参数,CSS的属性是根据js表达式的计算结果设置的。其它浏览器不支持expression方法,所以它只适用于IE浏览器。
CSS表达式的问题是计算太频繁了,不仅页面渲染缩放时,需要计算,页面滚动甚至鼠标滑过页面时都需要重新计算。如果在CSS表达式里面加个计数器来追踪CSS表达式的计算频率,把鼠标滑过页面就会发现计算次数会轻易的超过10000次。
减少CSS表达式计算次数的方法是使用一次性表达式,表达式第一次计算时会给样式属性设置一个显示值来代替表达式。如果样式属性必须根据页面活动动态设置,用事件绑定代替CSS表达式是一个好的选择。
有很多性能规则来处理外部组件管理。然而,在考虑这些因素之前,有一个更基本的问题需要考虑:js和css应该包含在外部文件中,还是内联在页面里面?
使用外部文件通常会加快页面速度,因为这样js,css文件可以被浏览器缓存。如果js,css内联在页面中,每次请求页面的时候都会重新加载。这样虽然减少了http请求数量,但是增加了html的大小。从另一方面来说,如果js,css在外部文件中并且被浏览器缓存,那么后续请求不会增加html文档大小,也不会增加http请求数量(外部文件从浏览器缓存中取,不经过http请求了)。
关键是html文档使用缓存的js,css文件的频率。这个因素尽管难以量化,但是也可以通过其它维度衡量。如果一个站点用户每个session周期需要访问多个页面,并且这多个页面有共同的脚本和样式文件,那么使用缓存的文件就有潜在的好处。
一般情况下都是把js,css写到外部文件中,但是也有例外,内联适合应用在首页。首页的每个session的访问次数少,内联js,css可以加快终端的响应时间。
内联可以降低http请求,使用外部文件缓存也有好处。通常的处理是首页内联js,css,当也加载完成之后再动态下载外部文件,这样后续页面就可以从浏览器缓存中获取这些文件。
域名系统(DNS)是把域名映射到IP地址上,就像手机通讯录把人名映射到手机号上一样。当你在浏览器输入的时候,DNS解析服务连接到浏览器然后返回服务器的IP地址。DNS是有开销的,一般会花费20-120ms为主机查询IP地址。浏览器不能通过主机名下载任何东西,除非DNS解析已完成。
为了性能考虑DNS查询都会缓存。这个缓存可能发生在某一台缓存服务器上面,这个缓存服务器有用户的ISP或者局域网维护,也有可能缓存到个别用户电脑上。DNS信息保存在操作系统的DNS缓存中(windows上面的DNS client service)。大部分浏览器都是自己的DNS缓存以区分于操作系统的缓存。一旦浏览器在自己的缓存中保存了DNS记录,它就不会从操作系统里面查这条记录了。
当客户端的DNS缓存都是空时(浏览器和操作系统的),DNS的查询次数就和页面中主机的DNS查询次数一样。包括页面url,图片,脚本样式文件,flash对象里面的主机名。减少独立主机名,就可以减少DNS查询次数。减少独立主机名对页面中需要并行下载的地方有潜在的影响。避免DNS查询虽然可以减少响应时间,但是减少并行下载也会增加响应时间。这两者是相互矛盾的,作者的建议是保持2到4个单独主机,这样DNS查询不至于过多,也有一定的并行下载。
和中的代码块也应该压缩。尽管你用gzip压缩了你的脚本和样式文件,再次压缩它们仍然可以减少5%或者更多的体积。随着使用的js和css越来越多,压缩代码可以消减成本。
压缩的做法就是移除代码中不必要的字符减少文件大小进而提升加载速度。代码一旦被压缩,所有的注释,不需要的空白字符(空格,换行,tab)都会被移除。对于Js来说,这会提高响应时间性能,因为要下载的文件大小减少了。常用的压缩js代码的工具是JSMin,YUI Compressor。YUICompressor也可以压缩css。和中的代码块也应该压缩。尽管你用gzip压缩了你的脚本和样式文件,再次压缩它们仍然可以减少5%或者更多的体积。随着使用的js和css越来越多,压缩代码可以消减成本。
代码混淆是处理源代码的另一种选择,它比代码压缩更复杂,因此在混淆过程中也更容易产生问题。有调查指出代码压缩可以减少21%的大小,代码混淆可以减少25%的大小。尽快代码混淆有更高的压缩率,但是代码压缩风险更低。m6米乐平台 米乐官方网站