精华内容
下载资源
问答
  • 前端代码优化

    千次阅读 2019-04-14 16:48:12
    上次写了浏览器渲染出网页的过程,想到了一些代码优化的小知识,当然了,我学识太浅,想到了还是太少了,所以这篇文章就长期更新啦。以后可能还有其他的框架如React等单独的代码优化的知识,毕竟这样的知识实在是太...

    上次写了浏览器渲染出网页的过程,想到了一些代码优化的小知识,当然了,我学识太浅,想到了还是太少了,所以这篇文章就长期更新啦。以后可能还有其他的框架如React等单独的代码优化的知识,毕竟这样的知识实在是太多了,一篇文章也会有些乱。

    个人能力有限,文中可能会有很多错误之处,希望大家看到后可以在评论里指出来,一起进步,谢谢啦。

    那下面开始正文。

    操作DOM比较慢的原因

    在浏览器中,DOM是属于渲染引擎的,JS是属于JS引擎的,JS来操作DOM,也就是两个引擎之间进行通信。

    浏览器中,这个通信是需要通过接口来实现的,而每次使用这个接口就会产生一些性能的损耗。

    async和defer的作用和区别

    在引用JS的时候,会有三种使用方法,1. 直接使用;2. async加载;3. defer加载

    在浏览器中会出行下面这样的区别

    *pic* async和defer区别

    图画的不太好,见谅哈。

    1. 直接使用
    <script src = "script.js"></script>
    

    在浏览器中遇到JS代码,就会阻塞HTML解析,进行JS的加载和执行,等执行结束后,再进行HTML解析,这样是最基本的使用方法,也是比较常见的。

    2. async加载
    <script async src = "script.js"></script>
    

    异步加载执行,从图中我们可以看到,当浏览器遇到JS代码,就会再开一个线程,先去加载JS,等加载完之后,阻塞HTML解析,执行JS,执行完再回去解析HTML。

    也就是说,这种方式,也会阻塞HTML的进行,但是时间可能是在HTML解析,也可能是在解析完成后进行。

    3. defer
    <script defer src = "script.js"></script>
    

    延迟加载执行,在图中可以看到,当浏览器遇到JS代码,会另开一个线程,加载JS代码,加载完后不会立即执行JS,而会等整个文档解析完毕后,再执行JS代码。之后进行DOM加载。

    • 至于到底使用async还是的defer就看具体要求了,但是这两个基本都会提升一定的性能。

    回流(Reflow)和重绘(Repiont)

    首先介绍一下这两个概念:

    • 回流
      浏览器根据浏览器可见区域的大小,将所有的“盒子模型”的大小,位置转换为实际的像素值。

    • 重绘
      当“盒子模型”的一些样式发生变化,这里样式指的是颜色,背景,前景等,不会引起盒子大小和位置的。会发生重绘。

    回流一定重绘,但重绘一定会出现回流,回流在重绘之前进行

    下面看一下什么时候发生回流和重绘
    • 发生回流的时刻
      • 添加或删除可见DOM元素(不包括display: none 的)
      • 元素尺寸发生变化,包括margin, brder, padding, width, height等
      • 位置发生变化
      • 元素内容变化,包括input 框中输入文字
      • 浏览器尺寸发生变化(这也是很多网站在我们改变浏览器宽度的时候会卡的原因)
      • 设置style属性的值
    • 发生重绘的时刻
      • 基本都是CSS样式,颜色、边框样式、背景(包括改变背景图片、背景尺寸)、阴影等

    代码优化的方法就是尽量减少回流,或者用重绘来替代回流

    • 使用Transform替代Top
    • 使用visibility替代display: none
    • 复杂的动画可以使用absolute ,可以让动画的对象脱离文档流,这样,只会让动画的元素产生回流,而页面其他元素不会受动画影响也产生回流。
    • GPU加速,这个就不介绍了,毕竟我也不会

    大概就写这么多了,以后遇到了再补上

    参考链接

    你真的了解回流和重绘吗

    深入浅出浏览器渲染原理

    展开全文
  • 前端代码优化基本方法

    千次阅读 2017-10-12 13:51:20
    前端性能优化

    减少HTTP请求

    • HTML优化:

      • 使用语义化标签
      • 减少iframe:iframe是SEO的大忌,iframe有好处也有弊端
      • 避免重定向
    • CSS优化:

      • 布局代码写前面
      • 删除空样式
      • 不滥用浮动,字体,需要加载的网络字体根据网站需求再添加
      • 选择器性能优化
      • 避免使用表达式,避免用id写样式
    • js优化:

      • 压缩
      • 减少重复代码
    • 图片优化:

      • 使用WebP
      • 图片合并,CSS sprite技术

    减少DOM操作

    • 缓存已经访问过的元素
    • "离线"更新节点, 再将它们添加到树中
    • 避免使用 JavaScript 输出页面布局–应该是 CSS 的事儿

    使用JSON格式来进行数据交换
    使用CDN加速
    使用HTTP缓存:添加 Expires 或 Cache-Control 信息头
    使用DNS预解析

    • 预解析的实现:
    用meta信息来告知浏览器, 当前页面要做DNS预解析:<meta http-equiv="x-dns-prefetch-control" content="on" />
    在页面header中使用link标签来强制对DNS预解析: <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
    
    展开全文
  • 如何优化前端代码

    千次阅读 2018-10-06 18:00:14
    HTTP协议是前端性能乃至安全中一个非常重要的话题,最近在看《web性能权威指南(High Performance Browser Networking)》,把其中关于HTTP部分的内容拿出来分享一下,加了一点自己的想法,当然没有《HTTP权威指南》讲...

    HTTP协议是前端性能乃至安全中一个非常重要的话题,最近在看《web性能权威指南(High Performance Browser Networking)》,把其中关于HTTP部分的内容拿出来分享一下,加了一点自己的想法,当然没有《HTTP权威指南》讲得详细,但对于理解我们平常做的事情很有启发。预计会有两三篇文章,重点分别会涉及到HTTP 1.1、HTTPS、HTTP 2.0等内容,本篇主要涉及HTTP 1.1及其应用。

    HTTP的历史

    HTTP 0.9

    HTTP的第一个版本被官方称为HTTP0.9,这是个只有一行的协议,例如:

    GET /about/
    
    (超文本响应……)
    (连接关闭……)

    HTTP 0.9有几个要点:

    • 客户端/服务器、请求/响应协议
    • ASCII 协议,运行于TCP/IP链接之上
    • 设计用来传输超文本文档(HTML)
    • 服务器与客户端之间的连接在每次请求之后都会关闭

    这个版本的HTTP主要用来传输文本,并且没有共用TCP连接。

    HTTP 1.0

    一个典型的HTTP 1.0请求过程如下:

    GET /rfc/rfc1945.txt HTTP/1.0 
    User-Agent: CERN-LineMode/2.15 libwww/2.17b3 
    Accept: */* 
    
    HTTP/1.0 200 OK 
    Content-Type: text/plain 
    Content-Length: 137582
    Expires: Thu, 01 Dec 1997 16:00:00 GMT 
    Last-Modified: Wed, 1 May 1996 12:45:26 GMT Server: Apache 0.84
    
    (超文本响应……)
    (连接关闭……)

    相对前一个版本,HTTP 1.0主要有以下几点变化:

    • 请求和相应可以由于多行首部字段构成
    • 响应对象前面添加了一个响应状态
    • 响应对象不局限于超文本
    • 服务器与客户端之间的连接在每次请求之后都会关闭
    • 实现了Expires等传输内容的缓存控制
    • 内容编码Accept-Encoding、字符集Accept-Charset等协商内容的支持

    这时候开始有了请求及返回首部的概念,开始传输不限于文本(其他二进制内容)

    HTTP 1.1

    HTTP 1.1是当前大部分应用所使用的协议版本。相对前面的1.0版本,HTTP 1.1语义格式基本保持不变,但是它加入了很多重要的性能优化:持久连接、分块编码传输、字节范围请求、增强的缓存机制、传输编码及请求管道

    实际上,持久链接在后来被反向移植到了HTTP1.0上

    HTTP 2.0

    HTTP 2.0 的主要目标是改进传输性能,实现低延迟和高吞吐量。HTTP 2.0作了很多性能角度的优化,另一方面,HTTP的高层协议语义并不会因为这次版本升级而受影响。所有HTTP首部、值,以及它们的使用场景都不会变。现有的任何网站和应用,无需做任何修改都可以在 HTTP 2.0 上跑起来。换句话说, 等以后我们的服务器、客户端(如浏览器)都支持HTTP 2.0的时候,我们不用为了利用 HTTP 2.0 的好处而修改标记,作很多额外的编码,却能享受到它带来的更低的延迟和更高的网络连接利用率交付!

    HTTP 2.0的内容将在下篇或下下篇放出,本文不对其做过多润色

    HTTP 1.1与前端性能

    前面讲到,HTTP 1.1这个版本引入了大量增强性能的重要特性,其中包括:

    • 持久化连接以支持连接重用
    • 分块传输编码以支持流式响应
    • 请求管道以支持并行请求处理
    • 字节服务以支持基于范围的资源请求
    • 改进的更好的缓存机制

    这里重点讲一下持久化、管道在前端性能优化中的一些应用

    持久连接

    所谓持久连接,就是重用 TCP连接,多个HTTP请求公用一个TCP连接。

    HTTP 1.1 改变了 HTTP 协议的语义,默认使用持久连接。换句话说,除非明确告知(通过 Connection: close 首部),否则服务器默认会保持TCP连接打开。如果你使用的是 HTTP 1.1,从技术上说不需要 Connection: Keep-Alive 首部,但很多客户端还是选择加上它,比如我们的浏览器在发起请求的时候,一般会默认帮我们带上 Connection: Keep-Alive 首部。

    我们来看一下为什么持久连接对我们来说这么重要。

    假设一个网页仅包含一个HTML文档及一个CSS样式文件,服务器响应这两个文件的时间分别为40ms及20ms,服务器和浏览者分别在哈尔滨和深圳,两者之间单向光纤延迟为28ms(假设的理想状态,实际会比这个要大)。

    1. 首先是获取HTML文档的请求过程:

    img

    HTML下载完毕后,TCP连接关闭。

    1. 其次,发起CSS资源的请求,再次经历一次TCP握手

    img

    可以看到,两个HTTP请求都分别需要经历一次TCP的三次握手时间,另外,图中没有体现到的是,每一次TCP请求都有可能会经历一次TCP慢启动 过程,这是影响传播性能的一个不可忽视的重要因素。

    假如我们底层的TCP连接得到重用,这时候的情况会是这样子:

    img

    很明显,在获取CSS的请求中,减少了一次握手往返。

    一开始,每个请求要用两个TCP连接,总延迟为284ms。在使用持久连接后,避免了一次握手往返,总延迟减少为228ms。这里面两次请求节省了56ms(一个 RTT,Round-Trip Time)的时间

    上面的例子还只是只有一个HTML和一个CSS的简单假设情况,而现实世界的web的HTTP请求数量比这个要多得多,在启用持久连接的情况下,N次请求节省的总延迟时间就是(N-1)×RTT。

    现实情况中,延迟更高、请求更多,性能提升效果比这里还要高得多。事实上,网络延迟越高,请求越多,节省的时间就越多。实际应用中,这个节省的总时间可按秒来算了。如果每一个HTTP都重启一个TCP连接,可想而知要浪费多少时间!

    HTTP管道

    持久 HTTP 可以让我们重用已有的连接来完成多次应用请求,但多次请求必须严格满足先进先出(FIFO,first in first out)的队列顺序:发送请求,等待响应完成,再发送客户端队列中的下一个请求。

    举一下上一节持久连接的那个例子,首先,服务器处理完第一次请求后,会发生了一次完整的往返:先是响应回传,接着是第二次请求,在第二次请求到达服务器之间的这段时间里,服务器空闲。

    如果服务器能在处理完第一次请求后,立即开始处理第二次请求呢?甚至,如果服务器可以并行处理两个请求呢?

    这时候HTTP管道就派上用场了,HTTP管道是一个很小但对上述工作流非常重要的一次优化。

    有了HTTP管道,我们的HTTP请求在一定程度上不用再一个一个地串行请求,而是可以多个并行了,看起来好像很理想:

    img

    如上图,HTML和CSS的请求同时到达服务器,服务器同时处理,然后返回。

    这一次,通过使用HTTP管道,又减少了两次请求之间的一次往返,总延迟减少为 172 ms。从一开始没有持久连接、没有管道的284ms,到优化后的172ms,这40%的性能提升完全拜简单的协议优化所赐。

    等一下,刚刚那个例子好像哪里还不够好:既然请求同时到达,同时处理,为什么后面要先返回HTML,然后再返回CSS?两者不能同时返回吗?

    理想很丰满,现实却有点骨感,这就是HTTP 1.1管道的一个很大的局限性:HTTP请求无法很好地利用多路复用,不允许一个连接上的多个响应数据交错返回(多路复用)。因而一个响应必须完全返回后,下一个响应才会开始传输。

    这个管道只是让我们把FIFO队列从客户端迁移到了服务器。也就是说,请求可以同时到达服务器,服务器也可以同时处理两个文件,但是,两个文件还是得按顺序返回给用户,如下图:

    img

    • HTML和CSS请求同时到达,但先处理的是HTML请求
    • 服务器并行处理两个请求,其中处理 HTML 用时40ms,处理CSS用时20ms
    • CSS请求先处理完成,但被缓冲起来以等候HTML响应先发送
    • 发送完HTML响应后,再发送服务器缓冲中的CSS响应

    可以看到,即使客户端同时发送了两个请求,而且CSS资源先准备就绪,但是服务器也会先发送 HTML 响应,然后再交付 CSS。

    题外话 上面两节举的例子,说到了HTML和CSS请求同时到达,这是书中的例子,实际上,个人觉得这个例子举得不是很恰当。 实际的web中,HTML及其包含的CSS一般不会同时到达服务器,正常的 瀑布图也不是这样的,往往是要先获取HTML内容后浏览器才能发起其中的CSS等资源请求。我想作者只是为了阐述原理吧,个人认为换成同一个HTML文档中CSS和JS可能更加恰当。

    这个问题的原理在于TCP层面的“队首阻塞”,感兴趣可以去复习下计算机网络的课程。其代价往往是:不能充分利用网络连接,造成服务器缓冲开销,有可能导致客户端更大的延迟。更严重的时,假如前面的请求无限期挂起,或者要花很长时间才能处理完,所有后续的请求都将被阻塞,等待它完成。

    所以,在HTTP 1.1中,管道技术的应用非常有限,尽管其优点毋庸置疑。实际上,一些支持管道的浏览器,通常都将其作为一个高级配置选项,但大多数浏览器都会禁用它。换句话说,作为前端工程师,开发的应用是面向普通浏览器应用的话,还是不要过多的指望HTTP管道,看来还是期待一下HTTP 2.0中对管道的优化吧。

    不过,实际上还是有很好地利用HTTP管道的一些应用,例如在WWDC 2012上,有苹果的工程师分享了一个针对HTTP优化取得巨大成效的案例:通过使用HTTP的持久连接和管道,重用iTunes中既有的TCP连接,使得低网速用户的性能提升到原来的3倍!

    实际上假如你想充分利用管道的好处,必须要保证下面这几点条件:

    • HTTP客户端支持管道
    • HTTP服务器支持管道
    • 应用可以处理中断的连接并恢复
    • 应用可以处理中断请求的幂等问题
    • 应用可以保护自身不受出问题的代理的影响

    因为iTunes的服务器和客户端都受开发者控制的应用,所以他们能满足以上的条件。这也许能给开发hybrid应用或者开发浏览器之外的web应用的前端工程师们一些启发,如果你开发的网站面向的用户是使用五花八门的浏览器,你可能就没辙了。

    使用多个TCP连接

    因为HTTP 1.1管道存在上面的缺点,所以利用率不高。那么问题来了:假设没有使用HTTP管道,我们的所有HTTP请求都只能通过持久连接,一个接一个地串行返回,这得有多慢?

    实际上,现阶段的浏览器厂商采取了另外的办法来解决HTTP 1.1管道的缺陷:允许我们并行打开多个TCP会话。至于是多少个,大家可能已经似曾相识:4到8个不等。这就是前端工程师非常熟悉的浏览器只允许从同一个服务器并行加载4到8个资源这一认识的真正来历。

    HTTP持久连接虽然帮我们解决了TCP连接复用的问题,但是现阶段的HTTP管道却无法实现多个请求结果的交错返回,所以浏览器只能开启多个TCP连接,以达到并行地加载资源的目的。

    只能说,这是作为绕过应用协议(HTTP)限制的一个权宜之计。可以这样打一个比喻,一个水管无法同时运输多种液体,那就只能给每一种液体开通一条运输管了,至于这个水管什么时候可以智能化到同时运输不同的液体,又能保证各自完整不受干扰到达目的地并在目的地自行分类?还是那一句,期待HTTP 2.0吧。

    这里的连接数为什么是4到8个,是多方平衡的结果:这个数字越大,客户端和服务器的资源占用越多(在高并发访问的服务器中因为TCP连接造成的系统开销不可忽视),每个主机4到8个连接只不过是大家都觉得比较安全的一个数字。

    域名分区

    前面说到,浏览器和服务器之间只能并发4到8个TCP连接,也就是同时下载4到8个资源,够吗?

    看看我们现在的大部分网站,动不动就几十个JS、CSS,一次六个,会造成后面大量的资源排队等待;另外,只下载6个资源,对带宽的利用率也是很低的。

    打个比喻,一个工厂装了100根水管,每次却只能用其中6根接水,既慢,又浪费水管!

    所以,我们前端性能优化中有一个最佳实践:使用域名分区

    对啊,何必把自己只限制在一个主机上呢?我们可以手工将所有资源分散到多个子域名,由于主机名称不一样了,就可以突破浏览器的连接限制,实现更高的并行能力。

    通过这种方式“欺骗”浏览器,这样浏览器和服务器之间的并行传输数量就变多了。

    域名分区使用得越多,并行能力就越强!

    但是,域名分区也是有代价的!

    实践中,域名分区经常会被滥用。

    例如,假设你的应用面向的是2G网络的手机用户,你分配了好几个域名,同时加载十几二十多个CSS、JS,这里的问题在于:

    • 每一个域名都会多出来的DNS查询开销,这是额外的机器资源开销和额外的网络延时代价。2G网络的DNS查询可不像你公司的电脑一样,相反可能是好几秒的延迟
    • 同时加载多个资源,以2G网络那种小得可怜的带宽来看,后果往往就是带宽被占满,每一个资源都下载得很慢
    • 手机的耗电加快

    所以在一些低带宽高延时的场景,例如2G手机网络,域名分区做过了的话,不光不会带来前端性能的提升,反而会变成性能杀手。

    域名分区是一种合理但又不完美的优化手段,最合适的办法就是,从最小分区数目(不分区)开始,然后逐个增加分区并度量分区后对应用的影响,从而得到一个最优的域名数。

    连接与拼合

    我们前端性能优化中有这么一个所谓的最佳实践原则:合并打包JS、CSS文件,以及做CSS sprite。

    现在我们应该知道为什么要这样做了,实际上就是因为现在HTTP 1.1的管道太弱了,这两种技术的效果就好像是隐式地启用了HTTP 管道:来自多个响应的数据前后相继地连接在一起,消除了额外的网络延迟。

    实际上,就是把管道提高了一层,置入了应用中,也许到了HTTP 2.0时代,前端工程师就不用干这样的活了吧?(HTTP 2.0的内容下篇讲)

    当然,连接拼合技术同样有代价的。

    • 例如CSS sprite,浏览器必须分析整个图片,即便实际上只显示了其中的一小块,也要始终把整个图片都保存在内存中。浏览器没有办法把不显示的部分从内存中剔除掉。
    • 再者,既然JS、CSS合并了,带来的一般就是体积的增大,在带宽有限的环境下(例如2G)下载时间就变长,一般导致的就是页面渲染时间延后等后果。因为JavaScript 和CSS 处理器都不允许递增式执行的,对于JavaScript 和CSS 的解析及执行,则要等到整个文件下载完毕。
    打包文件到底多大合适呢?可惜的是,没有理想的大小。然而,谷歌PageSpeed团队的测试表明,30~50 KB(压缩后)是每个JavaScript 文件大小的合适范围:既大到了能够减少小文件带来的网络延迟,还能确保递增及分层式的执行。具体的结果可能会由于应用类型和脚本数量而有所不同。

    资源内嵌

    JavaScript 和CSS 代码, 通过适当的script 和style 块可以直接放在页面中,而图片甚至音频或PDF 文件,都可以通过数据URI(data:mediatype,data)的方式嵌入到页面中。

    上面的这种方式我们称为资源内嵌

    嵌入资源是另一种非常流行的优化方法, 把资源嵌入文档可以减少请求的次数。尤其在2G网络等情况中,内嵌资源可以有效地减少多次请求带来的时延。可以参考这篇文章在2G中的一些实践。

    当然,有缺点:

    • 内嵌方式的资源,不能被浏览器、CDN 或其他缓存代理作为单独的资源缓存。如果在多个页面中都嵌入同样的资源,那么这个资源将会随着每个页面的加载而被加载,从而增大每个页面的总体大小。
    • 如果嵌入资源更新,那么所有以前出现过它的页面都将被宣告无效,而由客户端重新从服 务器获取。
    • 图片等非文本性资源通过base64 编码,会导致开销明显增大:编码后的资源大小比原大小增大33%!

    Google的砖家给出一些经验:

    • 只考虑嵌入1~2 KB 以下的资源,因为小于这个标准的资源经常会导致比它自身更高的HTTP 开销
    • 如果文件很小,而且只有个别页面使用,可以考虑嵌入。理想情况下,最好是只用一次的资源
    • 如果文件很小,但需要在多个页面中重用,应该考虑集中打包
    • 如果小文件经常需要更新,就不要嵌入了
    • 通过减少 HTTP cookie 的大小将协议开销最小化

    小结

    本文介绍了HTTP 1.1在前端性能优化中的一些应用,有些是为了绕过HTTP 1.1局限性的一些不得不做的事情,比如资源合并、压缩、内嵌等,这些都可以说是HTTP 2.0来临前的一些解决问题的“黑魔法”。

    HTTP 1.1及其利用当然远远没有本文说得那么简单,我只是浓缩了一部分内容,有兴趣可以去研究《HTTP权威指南》。

    展开全文
  • WEB前端自动化优化工具-代码语法检测-代码压缩
  • 前端性能优化.pptx

    2019-07-31 13:52:39
    代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等来讲述前端性能优化的多个方式。 目录结构如下: 一、WEB性能优化相关理论 二、前端性能优化的目的 三、前端性能...
  • 前端页面优化

    千次阅读 2019-04-15 20:04:10
    前端优化是复杂的,针对方方面面的资源都有不同的方式。那么,前端优化的目的是什么 1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。 2. 从服务商角度...

    前端是庞大的,包括HTML、CSS、Javascript、Image、Flash等等各种各样的资源。前端优化是复杂的,针对方方面面的资源都有不同的方式。那么,前端优化的目的是什么

     

    1. 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。

    2. 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。

    总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。

    前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例如HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等;第二类则是代码级别的优化,例如Javascript中的DOM操作优化、CSS选择符优化、图片优化以及HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。

     

    一、页面级优化

    1. 减少HTTP请求数

    这条策略基本上所有前端人都知道,而且也是最重要最有效的。都说要减少HTTP请求,那请求多了到底会怎么样呢?首先,每个请求都是有成本的,既包含时间成本也包含资源成本。一个完整的请求都需要经过DNS寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据这样一个”漫长”而复杂的过程。时间成本就是用户需要看到或者”感受”到这个资源是必须要等待这个过程结束的,资源上由于每个请求都需要携带数据,因此每个请求都需要占用带宽。另外,由于浏览器进行并发请求的请求数是有上限的(具体参见此处),因此请求数多了以后,浏览器需要分批进行请求,因此会增加用户的等待时间,会给用户造成站点速度慢这样一个印象,即使可能用户能看到的第一屏的资源都已经请求完了,但是浏览器的进度条会一直存在。

    减少HTTP请求数的主要途径包括:

    (1). 从设计实现层面简化页面

    如果你的页面像百度首页一样简单,那么接下来的规则基本上都用不着了。保持页面简洁、减少资源的使用时最直接的。如果不是这样,你的页面需要华丽的皮肤,则继续阅读下面的内容。

     

    (2). 合理设置HTTP缓存

    缓存的力量是强大的,恰当的缓存设置可以大大的减少HTTP请求。以有啊首页为例,当浏览器没有缓存的时候访问一共会发出78个请求,共600多K数据(如图1.1),而当第二次访问即浏览器已缓存之后访问则仅有10个请求,共20多K数据(如图1.2)。(这里需要说明的是,如果直接F5刷新页面的话效果是不一样的,这种情况下请求数还是一样,不过被缓存资源的请求服务器是304响应,只有Header没有Body,可以节省带宽)

    怎样才算合理设置?原则很简单,能缓存越多越好,能缓存越久越好。例如,很少变化的图片资源可以直接通过HTTP Header中的Expires设置一个很长的过期头;变化不频繁而又可能会变的资源可以使用Last-Modifed来做请求验证。尽可能的让资源能够在缓存中待得更久。关于HTTP缓存的具体设置和原理此处就不再详述了,有兴趣的可以参考下列文章:

    HTTP1.1协议中关于缓存策略的描述

    Fiddler HTTP Performance中关于缓存的介绍

     

    (3). 资源合并与压缩

    如果可以的话,尽可能的将外部的脚本、样式进行合并,多个合为一个。另外,CSS、Javascript、Image都可以用相应的工具进行压缩,压缩后往往能省下不少空间。

     

    (4). CSS Sprites

    合并CSS图片,减少请求数的又一个好办法。

     

    (5). Inline Images

    使用data: URL scheme的方式将图片嵌入到页面或CSS中,如果不考虑资源管理上的问题的话,不失为一个好办法。如果是嵌入页面的话换来的是增大了页面的体积,而且无法利用浏览器缓存。使用在CSS中的图片则更为理想一些

     

    (6). Lazy Load Image

    这条策略实际上并不一定能减少HTTP请求数,但是却能在某些条件下或者页面刚加载时减少HTTP请求数。对于图片而言,在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续的图片。这样一来,假如用户只对第一屏的内容感兴趣时,那剩余的图片请求就都节省了。有啊首页曾经的做法是在加载的时候把第一屏之后的图片地址缓存在Textarea标签中,待用户往下滚屏的时候才”惰性”加载。

     

    2. 将外部脚本置底

    前文有谈到,浏览器是可以并发请求的,这一特点使得其能够更快的加载资源,然而外链脚本在加载时却会阻塞其他资源,例如在脚本加载完成之前,它后面的图片、样式以及其他脚本都处于阻塞状态,直到脚本加载完成后才会开始加载。如果将脚本放在比较靠前的位置,则会影响整个页面的加载速度从而影响用户体验。解决这一问题的方法有很多,在这里有比较详细的介绍(这里是译文和更详细的例子),而最简单可依赖的方法就是将脚本尽可能的往后挪,减少对并发下载的影响。

     

    3. 异步执行inline脚本

    inline脚本对性能的影响与外部脚本相比,是有过之而无不及。首页,与外部脚本一样,inline脚本在执行的时候一样会阻塞并发请求,除此之外,由于浏览器在页面处理方面是单线程的,当inline脚本在页面渲染之前执行时,页面的渲染工作则会被推迟。简而言之,inline脚本在执行的时候,页面处于空白状态。鉴于以上两点原因,建议将执行时间较长的inline脚本异步执行,异步的方式有很多种,例如使用script元素的defer属性(存在兼容性问题和其他一些问题,例如不能使用document.write)、使用setTimeout,此外,在HTML5中引入了Web Workers的机制,恰恰可以解决此类问题

     

    4. Lazy Load Javascript

    随着Javascript框架的流行,越来越多的站点也使用起了框架。不过,一个框架往往包括了很多的功能实现,这些功能并不是每一个页面都需要的,如果下载了不需要的脚本则算得上是一种资源浪费-既浪费了带宽又浪费了执行花费的时间。目前的做法大概有两种,一种是为那些流量特别大的页面专门定制一个专用的mini版框架,另一种则是Lazy Load。YUI则使用了第二种方式,在YUI的实现中,最初只加载核心模块,其他模块可以等到需要使用的时候才加载

     

    5. 将CSS放在HEAD中

    如果将CSS放在其他地方比如BODY中,则浏览器有可能还未下载和解析到CSS就已经开始渲染页面了,这就导致页面由无CSS状态跳转到CSS状态,用户体验比较糟糕。除此之外,有些浏览器会在CSS下载完成后才开始渲染页面,如果CSS放在靠下的位置则会导致浏览器将渲染时间推迟。

     

    6. 异步请求Callback

    在某些页面中可能存在这样一种需求,需要使用script标签来异步的请求数据。类似:

    Javascript:

    /*Callback函数*/  
    function myCallback(info){  
    //do something here  

    HTML:

    <script type=”text/javascript” src=”http://abc.com/cb”></script> 

    cb返回的内容:

    myCallback(‘Hello world!’); 

          像以上这种方式直接在页面上写<script>对页面的性能也是有影响的,即增加了页面首次加载的负担,推迟了DOMLoaded和window.onload事件的触发时机。如果时效性允许的话,可以考虑在DOMLoaded事件触发的时候加载,或者使用setTimeout方式来灵活的控制加载的时机。

     

    7. 减少不必要的HTTP跳转

    对于以目录形式访问的HTTP链接,很多人都会忽略链接最后是否带’/’,假如你的服务器对此是区别对待的话,那么你也需要注意,这其中很可能隐藏了301跳转,增加了多余请求。具体参见下图,其中第一个链接是以无’/’结尾的方式访问的,于是服务器有了一次跳转。

     

    8. 避免重复的资源请求

    这种情况主要是由于疏忽或页面由多个模块拼接而成,然后每个模块中请求了同样的资源时,会导致资源的重复请求

     

    二、代码级优化

    1. Javascript

    (1). DOM

    DOM操作应该是脚本中最耗性能的一类操作,例如增加、修改、删除DOM元素或者对DOM集合进行操作。如果脚本中包含了大量的DOM操作则需要注意以下几点:

    a. HTML Collection

    在脚本中document.images、document.forms、getElementsByTagName()返回的都是HTMLCollection类型的集合,在平时使用的时候大多将它作为数组来使用,因为它有length属性,也可以使用索引访问每一个元素。不过在访问性能上则比数组要差很多,原因是这个集合并不是一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会重新执行这个查询从而更新查询结果。所谓的”访问集合”包括读取集合的length属性、访问集合中的元素。

    因此,当你需要遍历HTML Collection的时候,尽量将它转为数组后再访问,以提高性能。即使不转换为数组,也请尽可能少的访问它,例如在遍历的时候可以将length属性、成员保存到局部变量后再使用局部变量。

    b. Reflow & Repaint

    除了上面一点之外,DOM操作还需要考虑浏览器的Reflow和Repaint,因为这些都是需要消耗资源的,具体的可以参加以下文章:

    如何减少浏览器的repaint和reflow?

    Understanding Internet Explorer Rendering Behaviour

    Notes on HTML Reflow

     

    (2). 慎用with

           with(obj){ p = 1}; 代码块的行为实际上是修改了代码块中的执行环境,将obj放在了其作用域链的最前端,在with代码块中访问非局部变量是都是先从obj上开始查找,如果没有再依次按作用域链向上查找,因此使用with相当于增加了作用域链长度。而每次查找作用域链都是要消耗时间的,过长的作用域链会导致查找性能下降。

    因此,除非你能肯定在with代码中只访问obj中的属性,否则慎用with,替代的可以使用局部变量缓存需要访问的属性。

     

    (3). 避免使用eval和Function

    每次 eval 或 Function 构造函数作用于字符串表示的源代码时,脚本引擎都需要将源代码转换成可执行代码。这是很消耗资源的操作 —— 通常比简单的函数调用慢100倍以上。

    eval 函数效率特别低,由于事先无法知晓传给 eval 的字符串中的内容,eval在其上下文中解释要处理的代码,也就是说编译器无法优化上下文,因此只能有浏览器在运行时解释代码。这对性能影响很大。

    Function 构造函数比eval略好,因为使用此代码不会影响周围代码;但其速度仍很慢。

    此外,使用eval和Function也不利于Javascript压缩工具执行压缩。

     

    (4). 减少作用域链查找

    前文谈到了作用域链查找问题,这一点在循环中是尤其需要注意的问题。如果在循环中需要访问非本作用域下的变量时请在遍历之前用局部变量缓存该变量,并在遍历结束后再重写那个变量,这一点对全局变量尤其重要,因为全局变量处于作用域链的最顶端,访问时的查找次数是最多的。

    低效率的写法:

    //全局变量  
    var globalVar = 1;  
    function myCallback(info){  
       for( var i = 100000; i–;){  
          //每次访问globalVar都需要查找到作用域链最顶端,本例中需要访问100000次  
          globalVar += i;  
       } 

    更高效的写法:

    //全局变量  
    var globalVar = 1;  
    function myCallback(info){  
       //局部变量缓存全局变量  
       var localVar = globalVar;  
       for( var i = 100000; i–;){  
          //访问局部变量是最快的  
          localVar += i;  
       }  
       //本例中只需要访问2次全局变量  
       globalVar = localVar;  
    }

    此外,要减少作用域链查找还应该减少闭包的使用。

    (5). 数据访问

    Javascript中的数据访问包括直接量(字符串、正则表达式)、变量、对象属性以及数组,其中对直接量和局部变量的访问是最快的,对对象属性以及数组的访问需要更大的开销。当出现以下情况时,建议将数据放入局部变量:

    a. 对任何对象属性的访问超过1次

    b. 对任何数组成员的访问次数超过1次

    另外,还应当尽可能的减少对对象以及数组深度查找。

    (6). 字符串拼接

    在Javascript中使用”+”号来拼接字符串效率是比较低的,因为每次运行都会开辟新的内存并生成新的字符串变量,然后将拼接结果赋值给新变量。与之相比更为高效的做法是使用数组的join方法,即将需要拼接的字符串放在数组中最后调用其join方法得到结果。不过由于使用数组也有一定的开销,因此当需要拼接的字符串较多的时候可以考虑用此方法。

    关于Javascript优化的更详细介绍请参考:

    Write Efficient Javascript(PPT)

    Efficient JavaScript

    2. CSS选择符

    在大多数人的观念中,都觉得浏览器对CSS选择符的解析式从左往右进行的,例如

    #toc A { color: #444; } 

    这样一个选择符,如果是从右往左解析则效率会很高,因为第一个ID选择基本上就把查找的范围限定了,但实际上浏览器对选择符的解析是从右往左进行的。如上面的选择符,浏览器必须遍历查找每一个A标签的祖先节点,效率并不像之前想象的那样高。根据浏览器的这一行为特点,在写选择符的时候需要注意很多事项,有人已经一一列举了,详情参考此处

    3. HTML

    对HTML本身的优化现如今也越来越多的受人关注了,详情可以参见这篇总结性文章

    4. Image压缩

    图片压缩是个技术活,不过现如今这方面的工具也非常多,压缩之后往往能带来不错的效果,具体的压缩原理以及方法在《Even Faster Web Sites》第10章有很详细的介绍,有兴趣的可以去看看。

    总结

    本文从页面级以及代码级两个粒度对前端优化的各种方式做了一个总结,这些方法基本上都是前端开发人员在开发的过程中可以借鉴和实践的,除此之外,完整的前端优化还应该包括很多其他的途径,例如CDN、Gzip、多域名、无Cookie服务器等等,由于对于开发人员的可操作性并不强大,在此也就不多叙述了,详细的可以参考Yahoo和Google的这些”金科玉律”。

    展开全文
  • (给达达前端加星标,提升前端技能)想要成为一名合格的Web前端工程师,Web前端性能优化是一个必须要掌握的知识,那么应该怎么进行Web前端性能优化呢?--达达前端Web前端性能优化原理问...
  • 前端优化方案

    千次阅读 2019-04-08 09:11:15
    1 优化css 1.1 避免使用CSS表达式 用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,可以用CSS表达式把背景颜色设置成按小时交替的 尽量减少标签选择器的使用...
  • web前端性能优化总结

    万次阅读 多人点赞 2016-05-21 22:26:33
     网站的划分一般为二:前端和后台。我们可以理解成后台是用来实现网站的功能的,比如:实现用户注册,用户能够为文章发表评论等等。而前端呢?其实应该是属于功能的表现。并且影响用户访问体验的绝大部分来自前端...
  • 前端开发】代码结构及性能优化大总结

    千次阅读 多人点赞 2021-06-05 13:40:19
    1、前端结构组织与文件命名规范 前端结构组织具有如下原则: 同一项目中代码的组织结构要清晰 同类型文件归类到相同的文件夹中 文件命名规则须统一并且命名要有意义 HTML 命名规范 HTML 代码所有的标签名和属性...
  • 有哪些前端性能优化的方法?

    千次阅读 2020-08-04 00:28:39
    1、页面级别的优化 (1) 减少HTTP请求 CSS精灵图 如果可以,尽量将外部的脚本、样式进行合并,多个合为一个。且CSS,JS,image都可以用相应工具进行压缩 能使用CSS替代效果的尽量少使用图片 图片懒加载。可以在某些...
  • 前端性能优化及技巧

    2021-01-19 15:43:21
    前言 为什么要优化性能对于前端工程师如此重要  在行业内有句话不知道大家有没有听说过,‘懂得性能优化并且研究过jquery源代码的人和不懂得性能优化写出来的代码对于性能的消耗会相差上百倍甚至上千倍’,现在的...
  • 主要介绍了@angular前端项目代码优化之构建Api Tree的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • web前端优化方案

    2018-07-14 16:30:20
    根据yslow建议,个人总结处理的一些web前端优化方案。
  • 前端的一些优化方法

    千次阅读 2019-06-21 23:54:12
    2.前端模板JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数。 3.用innerHTML替代DOM操作,减少DOM操作次数,优化JavaScript性能。 4.当需要...
  • 前端代码SEO优化

    千次阅读 2019-03-26 18:00:14
    head头部标签部分 <title> 标题: 只强调重点,不要重复出现关键词,各个页面的title不要设置相同的 <meta keywords> 关键词: 列举出关键词,不要过分...标签语义化,比较以下两部分代码做头部导航: ...
  • 随着前端项目不断扩大,浏览器渲染的压力变得越来越重。配置好一点的计算机可以顺利地展现页面;配置低一些的计算机渲染页面的性能就不那么可观了。性能优化部分的面试题主要考察应试者对网站性能优化的...
  • web前端性能优化提升篇

    千次阅读 2017-02-15 17:01:50
    网站的划分一般为二:前端和后台。...而前端呢?其实应该是属于功能的表现。并且影响用户访问体验的绝大部分来自前端页面。...除了后台需要在性能上做优化外,其实前端的页面更需要在性能优化上下功夫...
  • web前端性能优化.docx

    2019-12-18 11:51:16
    web前端性能优化,主要是从加载优化、gzip压缩、减少DNS查询、gulp压缩打包 部分实现代码和前后效果对比图介绍
  • 高效前端:WEB搞笑编程与优化高效前端:WEB搞笑编程与优化高效前端:WEB搞笑编程与优化高效前端:WEB搞笑编程与优化高效前端:WEB搞笑编程与优化高效前端:WEB搞笑编程与优化
  • 前端性能优化

    千次阅读 多人点赞 2018-05-19 15:53:26
    前端性能优化篇 首先附上连接:yahoo的优化原则=》https://developer.yahoo.com/performance/rules.html?guccounter=1 本文摘自《摘自高性能网站建设指南》 前端性能优化策略图(图片源自网络) 时间都去了...
  • 前端性能优化建议

    2021-01-18 17:35:25
    一说到性能优化,大家都不约而同的想起了雅虎的军规,2-5-8原则,3秒的首屏准则等等,这些规则在开发中虽然不是强制要求的,但是为了追求页面性能的完美体验,就不得不对代码进行修改和优化。 下面就与大家一同分享...
  • 每个前端工程师都应该懂的前端性能优化总结:

    万次阅读 多人点赞 2020-04-02 10:57:44
    避免浏览器中异常错误抛出 尽量避免代码出错 使用try catch做异常信息捕获 增加页面关键词优化 总结 这篇文章主要分享了一些前端性能优化的方法,从不同角度考虑,比如减少http请求,编写代码的一些优化技巧,页面...
  • 主要介绍了记一次react前端项目打包优化的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 前端SEO优化

    千次阅读 2019-04-11 15:09:00
    通过网站的结构布局设计和网页代码优化,使前端页面既能让浏览器用户能够看懂,也能让“蜘蛛”看懂。 (1)网站结构布局优化:尽量简单、开门见山,提倡扁平化结构。 建立的网站结构层次越少,越容易被“蜘蛛”...
  • Web前端:11个让你代码整洁的原则(1)
  • 前端性能优化的七种方法

    千次阅读 2020-08-06 17:26:33
    前端性能优化主要有七种方法,包括减少请求数量、减少资源大小、优化网络连接、优化资源加载、减少重绘回流、使用性能更好的API和构建优化 1、减少请求数量 1.1 图片处理 1.1.1 雪碧图 雪碧图是根据css sprite音译...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 205,356
精华内容 82,142
关键字:

前端代码优化

友情链接: FDA.rar