Web前端性能优化整理

高性能HTML

一、避免使用iframe
  iframe也叫内联frame,可将一个HTML文档嵌入另一个HTML文档中。
  iframe的好处是,嵌入的文档独立于父文档,通常也借此使浏览器模拟多线程。缺点是:

  ①虽然iframe能模拟多线程,但主流浏览器的同域名并行下载数是不变的,浏览器对同域名的链接总是共享浏览器级别的连接池,
     即使是不同窗口或标签页的同域名网页。
  ②在页面加载时,iframe会阻塞父文档onload事件的触发。并且有些浏览器需在触发onload事件后才能被触发onunload事件。
     故用户用onload事件长久未触发而离开页面时,不会触发onunload事件。
    ※不兼容IE6~8的解决方案:使用JavaScript动态加载iframe元素或动态设置其src属性。

    <iframe id=ifr ></iframe>
    document.getElementById( ‘ifr’ ).setAttribute( ‘src’ , ‘url ’ );

   ③iframe是文档内最消耗资源的元素之一,即使是空iframe的开销也是昂贵的。【通过Steve Souders测试】

二、避免空连接属性
  空连接指:img、link、script 和 iframe元素的src或href属性的值为空。(如src = ””)
  设置了空连接后浏览器依然会以默认规则发送请求:
  ①IE6~8中只有img元素会出问题:IE会将img的空地址解析为当前页面地址的目录地址并请求。
   如当前网页地址为http://aaa.com/bb/c.html,img的地址会被解析为http://aaa.com/bb
  ②早些版本的Webkit和Firefox会将空连接解析为当前页面的地址。在ios与android中此问题较严重。
   如果页面有多个空连接属性元素,会增加服务器的请求次数。
  ③幸运的是,主流浏览器对iframe的src属性值为空时,会解析为about:blank地址,而不发送额外请求。

三、避免节点深层级嵌套
  层级越深的节点在初始化构建时,所占内存越多。
  通过浏览器HTML解析器会将整个HTML文档的结构存储为DOM树结构。当节点嵌套层次越深,构建的DOM书层次也越深。

四、缩减HTML文档大小
  ①删除对执行结果无影响的空格空行和注释;
  ②避免table布局;
  ③使用HTML5;

五。显式指定文档字符集
  在HTML页面开时指定字符集有助于浏览器立即开始解析HTML代码。
  HTML文档通常被解析为一序列的带字符集编码信息的字符串,通过Internet传送。
  字符集编码在HTTP响应头中,或HTML标记中指定。浏览器通过指定的字符集,吧编码解析为可现实在屏幕上的字符。
  若浏览器无法获知页面的编码字符集,一般会在执行脚本和渲染页面之前,先将字节流缓存,再搜索可进行解析的字符集 或 以默认字符集来解析。

六、显示设置图片的宽高
  有时需要在页面加载完之前,就对页面布局进行定位。
  若页面中的图片没指定尺寸,或尺寸与实际图片大小不符,浏览器会在图片下载完成后再"回溯"该图片并重新显示,从而浪费时间。
  故最好为页面的图片设置指定尺寸(行内样式或CSS样式)。

    <img src="hello.png" width="400" height="300">

七、避免 脚本阻塞加载
  浏览器在解析常规script标签时,会等待script下载完毕后,才解析执行,之后的HTML代码就只能等待。故应该将脚本放在文档的末尾。

 

高性能CSS

一、避免使用@import
  CSS2.1加入的@import,会使页面在加载时添加额外延迟。
  由于浏览器不能并行下载样式,会导致页面增添额外的往返耗时。而使用<link>能并行下载样式,但任然是多次请求。

二、避免AlphaImageLoader滤镜
  此滤镜能解决IE6即一下版本显示PNG图片的半透明效果,但会在加载图片时终止内容的呈现,并冻结浏览器。
  在每个元素(不仅仅是图片)都会运算一次,添加内存开支。
  应使用PNG8格式来代替,或用下划线(_filter)只针对IE6。

三、避免CSS表达式
  CSS表达式是设置动态CSS属性的即强调又危险的方法。IE5开始支持,IE独有。

    //实现每隔一小时切换一次背景颜色
    background-color: expression((new Date()).getHours()%2?"#FFFFFF": "#000000" );

  CSS表达式的缺点是技术频率极大,在页面显示、缩放、滚动 或 移动鼠标,都会重新计算一次。移动随便会达到1w次以上的计算量。
  ①使用一次性的表达式能减少计算次数,在第一次运行时将结果赋给指定样式属性,并用该属性代替CSS表达式。
  ②如果样式属性必须在页面周期内动态地改变,使用时间句柄代替CSS表达式是一个可行的办法。

四、避免通配选择器
  优化选择器的原则是减少匹配时间。CSS选择器的匹配机制是:从右向左进行规制匹配的!
    #header > a { font-weight:blod; }
      上面这条规制实际是浏览器遍历页面所有a元素,并确定其父元素的id是否为header。
    #header  a {...}
      后代选择器开销更大,在遍历页面的所有a元素后,会需向上遍历直到根节点。

  由此可知,选择器最右边的规制 往往决定了向左移匹配的工作量。故最右边的选择规则 称之为关键选择器。
    .selected * {...}
      在匹配所有元素后,再分别向上匹配直至根节点。通常比开销最小的ID选择器高出·~3个数量级。

五、避免单规则的属性选择器
  .selected [href='#index'] {...}
    浏览器先匹配所有的元素,检查其是否有href属性并且值为“#index”,再分别向上匹配class为selected的元素。
  故应该避免使用关键选择器是单规则属性选择器的规则。

六、避免正则的属性选择器
  CSS3添加了复杂的属性选择器,通过类正则表达式进行匹配。但这些类型的选择器会比基于类别的匹配慢很多。

七、移除无匹配的样式
  ①删除无用的样式,可缩减样式文件大小,加快加载速度。
  ②对于浏览器,所有样式规则都会被解析后索引起来,即使是当前页面无匹配的规则!故移除无匹配的规则,减少索引项,加快浏览器查找速度。


高性能JavaScript

一、使用事件代理
  当过多的时间句柄被频繁触发时,页面反应会迟钝。
  如一个div有10个按钮,只需给div附加一次事件句柄,而不必给每个按钮添加一个句柄。
  事件冒泡时刻捕捉到事件 并判断时那个事件发出的。【触发事件的元素 = ev.srcElement ? ev.srcElement : ev.target;】

二、缓存选择器查询结果
  减少选择器查询的次数,并尽可能缓存选中的结果,便于以后的重用。

jQuery('#top').find('p.classA');
...
jQuery('#top').find('p.classB');

//使用下面的方法 减少开销
var cached = jQuery('#top');
cached.find('p.classA');
...
cached.find('p.classB');

三、避免频繁的IO操作
  应减少对cookie或localstorage的操作,因为对它们进行操作的API是同步的,而它们是多个tab页面间共享的。
  多页面同时操作cookie和localstorage时,会存在同步加锁机制。

四、避免频繁的DOM操作
  JavaScript访问DOM元素缓慢,应做到:
  ①缓存已经查询过的元素;
  ②线下更新完节点之后,在将它们添加到文档树中;
  ③避免使用JavaScript来修改页面布局。

五、使用微类库
  尽量避免使用大而全的类库,而是按需使用微类库来辅助开发。

图片优化

1. 优化图片 (Optimize Images)

使用 GIF 、JPG 还是 PNG 格式的图片? 尽可能的使用 PNG 格式的图片,更多的功能,更小的尺寸(与GIF 相比)。

对于 PNG 图片,考虑用 Pngcrush 或类似的工具进行优化。常见的工具如下表:

  • pngcrush http://pmt.sourceforge.net/pngcrush/
  • pngrewrite http://www.pobox.com/~jason1/pngrewrite/
  • OptiPNG http://www.cs.toronto.edu/~cosmin/pngtech/optipng/ (refer: 教程)
  • PNGOut http://advsys.net/ken/utils.htm

另请参见: Five Tips For the Effective Use of PNG Images

JPEG 图片的优化工具:

  • jpegtran (http://jpegclub.org/)

必需要强调的是,图片设计的同学啊,请考虑设计面向 Web 的图片,不要动不动就设计超过可接受尺寸之外大家伙,这应该是一种习惯,而不是什么高超的技能,只需要记住就成了。

2. 使用 CSS Sprites 技巧对图片优化 (OptimizeCSS Sprites)

之前提到过,简单的说就是"利用 CSS background 相关元素进行背景图绝对定位",把多次HTTP 调用变为一次调用,更多参考:CSS Sprites: Image Slicing's Kiss of Death

补充一下:对于这个技巧我曾经见到有人滥用的。把多个背景图片揉成一个,减少 HTTP 调用,这是一个很好的思路。但一定要记住这个大图片不能太"重",我看到过 100 多K 的背景图。一个图片就把整个网站拖得很慢。比较好的例子可以参考雅虎关系的这个图.

更新:使用 CSS Sprites 的一个潜在的副作用是客户端将消耗更多内存(参考)。

3. 不要在 HTML 中使用缩放图片 (Don't Scale Images inHTML)

更多的时候,可能是因为偷懒而没有制作合适大小的图片,如果是批量处理图片的话,可能一条 ImageMagic 命令(convert )就能搞定 。必须提及的是,看到太多的对图片拉伸很难看的页面,救救这些页面!

4. 用更小的并且可缓存的 favicon.ico (Make favicon.ico Small and Cacheable)

更小,可缓存,这两条可能都不是问题。问题是,太多站点根本没有 favicon.ico 。有的时候,判断独立域名的 Blog 是否专业,基本看一下是否有 favicon.ico 就差不多了。

--EOF--

补充:视觉设计者应该尽量考虑控制图片大小,推荐在 200K 以下。

Web 前端优化最佳实践最后一部分是针对移动应用的,其实只是针对 iPhone 的,目前只有两条规则。
1. 单个数据对象小于 25K (Keep Components under 25K)

这个似乎只是针对 iPhone 研究的。建议保持单个 Web 数据对象在 25 K 以下。为什么是 25K? Apple 官方信息指出可缓存到内存中的 Web 对象最大支持到 10M,但经过测试,发现也就是 25K 左右。

iPhone 在市场上的优异表现,让 Web 人员不得不考虑如何针对其进行优化。相信这部分内容也在不断变化中。

2. Pack Components into a Multipart Document

把Web 页面组件打包成一个多部分组成的文档。其目的是减少 HTTP 请求。对这部分语焉不详,等待后续更新吧。



站点优化

一、把CSS放在页面头部,把JavaScript放在页面底部

        这样就不会阻塞页面渲染,让页面出现长时间的空白。

二、选择合适的图片格式

        如果图片颜色数较多就使用JPG格式,如果图片颜色数较少就使用PNG格式,如果能够通过服务器端判断浏览器支持WebP,那么就使用WebP格式和SVG格式。

三、合并静态资源

       包括CSS、JavaScript和小图片,减少HTTP请求。

四、压缩源码和图片

       JavaScript文件源代码可以采用混淆压缩的方式,CSS文件源代码进行普通压缩,JPG图片可以根据具体质量来压缩为50%到70%,PNG可以使用一些开源压缩软件来压缩,比如24色变成8色、去掉一些PNG格式信息等。

五、开启服务器端的Gzip压缩

       这对文本资源非常有效,对图片资源则没那么大的压缩比率。

六、使用CDN

       或者一些公开库使用第三方提供的静态资源地址(比如jQuery、normalize.css)。一方面增加并发下载量,另一方面能够和其他网站共享缓存。

七、延长静态资源缓存时间

       这样,频繁访问网站的访客就能够更快地访问。不过,这里要通过修改文件名的方式,确保在资源更新的时候,用户会拉取到最新的内容。

八、使用GET来完成Ajax请求

       Yahoo!Mail团队发现,当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,然后才发送数据。因此使用GET最为恰当,因为它只需发送一个TCP包(除非你有很多cookie)。IE中URL的最大长度为2K,因此如果你要发送一个超过2K的数据时就不能使用GET了。一个有趣的不同就是POST并不像GET那样实际发送数据。根据HTTP规范,GET意味着“获取”数据,因此当你仅仅获取数据时使用GET更加有意义(从语意上讲也是如此),相反,发送并在服务端保存数据时使用POST。

九、为文件头指定Expires或Cache-Control

        对于静态内容:设置文件头过期时间Expires的值为“Never expire”(永不过期)
        对于动态内容:使用恰当的Cache-Control文件头来帮助浏览器进行有条件的请求
        第一次访问你页面的用户就意味着进行多次的HTTP请求,但是通过使用Expires文件头就可以使这样内容具有缓存性。它避免了接下来的页面访问中不必要的HTTP请求。Expires文件头经常用于图像文件,但是应该在所有的内容都使用他,包括脚本、样式表和Flash等。

十、减少 DNS 查找 (Reduce DNS Lookups)

必须明确的一点,DNS 查找的开销是很大的。另外,我倒是觉得这是 Yahoo! 所有站点的通病,Yahoo!主站点可能还不够明显,一些分站点,存在明显的类似问题。对于国内站点来说,如果过多的使用了站外的 Widget ,也很容易引起过多的 DNS 查找问题。

十一、避免重定向 (Avoid Redirects)

不是绝对的避免,尽量减少。另外,应该注意一些不必要的重定向。比如对 Web 站点子目录的后面添加个 / (Slash) ,就能有效避免一次重定向。http://www.dbanotes.net/arch 与 http://www.dbanotes.net/arch/ 二者之间是有差异的。如果是 Apache 服务器,通过配置 Alias 或mod_rewrite 或是 DirectorySlash 能够消除这个问题。

十二、 缩小 Cookie (Reduce Cookie Size)

Cookie 是个很有趣的话题。根据 RFC 2109 的描述,每个客户端最多保持 300 个 Cookie,针对每个域名最多 20 个 Cookie (实际上多数浏览器现在都比这个多,比如 Firefox 是 50 个) ,每个 Cookie 最多 4K,注意这里的 4K 根据不同的浏览器可能不是严格的 4096 。别扯远了,对于 Cookie 最重要的就是,尽量控制 Cookie 的大小,不要塞入一些无用的信息。


本文整理自:

http://developer.51cto.com/art/201509/490612.htm

http://www.cnblogs.com/slowsoul/archive/2013/06/13/3133838.html

http://www.poluoluo.com/jzxy/200912/75133.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值