学习
实践
活动
专区
工具
TVP
写文章

web前端性能优化

作为一个男程序猿,很多的时候其实并不希望听到Quickly ,3秒之类的词,但是在访问网站时却希望在手指挥动的那一毫秒就能看到结果,今天就浅谈网页访问最重要的体验,怎么极速呈现用户访问的页面

前端优化的目的是什?

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

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

要想做优化,先要理解web请求的过程: 浏览器本身是一个客户端,当你输入URL的时候,首先浏览器会去请求DNS服务器,通过DNS获取相应的域名对应的IP,然后通过IP地址找到IP对应的服务器后,要求建立TCP连接,等浏览器发送完HTTP Request(请求)包后,服务器接收到请求包之后才开始处理请求包,服务器调用自身服务,返回HTTP Response(响应)包;客户端收到来自服务器的响应后开始渲染这个Response包里的主体(body),等收到全部的内容随后断开与该服务器之间的TCP连接。

用Chrome浏览器打开我们直播间网站,并打开开发者工具Network窗口,下图就是我们站点资源的加载图

整个资源加载并渲染出来时间大约是2秒左右(比较好的用户体验应该是在3秒以内),这个时间用户应该还比较接受,在没有优化之前 整个这个时间大约为4秒左右,右边小框是整个请求在这个阶段耗费的时间

Stalled 从HTTP连接建立到请求能够被发出送出去(真正传输数据)之间的时间花费。包含用于处理代理的时间,如果有已经建立好的连接,这个时间还包括等待已建立连接被复用的时间。

Queuing 排队的时间花费。

Request sent 发起请求的时间。

Waiting (Time to first byte (TTFB)) 是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了TCP连接时间,发送HTTP请求时间和获得响应消息第一个字节的时间。

Content Download 获取Response响应数据的时间花费。

知道了网站请求的过程,下面就看怎么优化,前端优化又分为网络请求优化,代码级别的优化

一 减少请求量

静态文件(js,css)的合并压缩打包,虽说图片压缩是不必说的事情,但是总会有些时候你会发现一些网站的图片尺寸很大,这个需要处理,而且必须处理,大部分的压缩过的图片大小会比原来减少30%以上,使用base64编码,这些都能直接减少网络请求,目前我们已经使用的gulp来构建前端项目,并开发基于cdn自动上传,静态文件压缩合并等功能,具体详情后续章节我们组的老司机会陆续发表文章

静态文件不要放网站服务器,尽量使用其他域名的CDN(contentdistribute network,内容分发网络,他的本质就是一种缓存策略,将数据缓存在网络中的各个的节点,用户以最快速度获取最近节点的数据资源),另外cdn不跟主站域名一致时,因为主站域名里通常会设置一些cookie信息,而静态资源域名是不需要设置cookie;每次访问主站域名服务器资源会自动上传cookie,这是设置跟主站域名不同的一个重要原因,目前我们项目中静态资源基本是全量上cdn

静态CDN域名最好使用2-4个, 原因是浏览器对max connections 有限制,如果所有资源都在统一cdn上,当达到max connections 后面的资源就需要等待,如果网站请求的资源较多就需要等待,例如你的网站静态资源是60个,假设浏览器每次访问同一个域名的最大并发是6个,每个资源请求都是是100ms,如果只放一个域名的cdn上那么总共30个资源需要1 s,如果这些资源平均放两个不同域名的cdn上,全部请求只要花费500ms

静态类文件设置缓存,浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中。缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页(这就是为什么每次用360加速器优化时会显示一大堆浏览器临时文件) 浏览器访问资源缓存流程如下图.

lazyload,只显示首屏页面,其它内容需要时再加载,比如列表页、头像图片lazyload.

合理的使用异步请求,异步请求不会影响页面的load,另外,我们发送Ajax请求时候,应该缓存一些非实时不太重要的数据,比如用户头像.

二.代码编写也需要注意以下问题

减少重绘,在HTML页面完成展现之后,动态改变页面元素或调整CSS样式都会引起浏览器重绘,性能的损耗直接取决于动态改变的范围:如果只是改变一个元素的颜色之类的信息则只会重绘该元素;而如果是增删节点或调整节点位置则会引起其兄弟节点也一并重绘。

以上会执行3次重绘,而通过CSS代替javascript多次执行则只进行一次重绘。

减少重绘并不是说不要重绘,而是要注意重绘范围:改动的DOM元素越深则影响越小,所以尽量深入节点改动;对某些DOM样式有多重变动尽量合并到一起修改。

避免节点深层级嵌套 深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。浏览器会把整个HTML文档的结构存储为DOM“树”结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。如下代码,完全能够去掉div或span其中一个标签。

页面HEAD中设置缓存, 通常不设置缓存的情况下,每次刷新页面都会重新读取服务器的文件,而如果设置缓存之后,所有文件都可以从本地取得,这样明显极大提高了页面效率。 当然,如果你的项目代码有变更,因为客户端缓存了文件就得不到最新的文件,势必造成显示错误。基于这个问题的解决方案就是给链接文件加一个唯一后缀,,就会向服务器请求最新文件。

HTML+CSS3+js尽量用各自自特有的属性来完成效果 让三元素各司其职才能做出高性能的网页:HTML是页面之本也是内容之源,有了它就能跟CSS和js交互;CSS3属性功能越来越强大,能做很多动画如js做的事情如渐变、移动等动态效果但现在的CSS3也能完成js实现的效果,就尽量将工作交给css,这样会获得更好的性能。

避免使用Iframe 使用iframe并不会增加同域名下的并行下载数,浏览器对同域名的连接总是共享浏览器级别的连接池,在页面加载过程中iframe元素还会阻塞父文档onload事件的触发。并且iframe是html标签中最消耗资源的标签,它的开销比DIV、SCRIPT、STYLE等DOM高1~2个数量级(但其实我们代码中还有iframe)。

避免空链接属性 如

这样的设置方式是非常不可取的,即使链接为空,在旧的浏览器也会以固定步骤发送请求信息。 也不可取,如果是a标签最好的方式是在链接中加一个空的js代码

显式设置图片的宽高

如果HTML里的图片没有指定尺寸(宽和高),或者代码描述的尺寸与实际图片的尺寸不符时,浏览器则要在图片下载完成后再“回溯”该图片并重新显示,这会消耗额外时间。

渐进式增强设计

渐进式增强设计的通俗解释就是:首先写一段满足所有浏览器的基本样式,再在后面针对不同高级浏览器编写更漂亮的样式

如下代码,所有浏览器都支持background-color: #2067f5;满足了浏览器基本现实需求,而后面的background-image: -webkit-gradient等则为不同高级浏览器使用,只要浏览器识别就能执行这段代码(不识别,CSS也不会报错只会直接忽略)。

最后css和js也需要避免耗费性能的写法

CSS具体应用注意点

目前前端动画效果越来越多,使用CSS3编写动画效果时,开启GPU硬件加速提升网站动画渲染性能-webkit-transform:transition3d和-webkit-transform:translateZ其实是为了渲染3D样式,但我们设置值为0后,并没有真正使用3D效果,但浏览器却因此开启了GPU硬件加速模式。这种GPU硬件加速在当今PC机及移动设备上都已普及,在移动端的性能提升是相当显著地,所以建议大家在做动画时可以尝试一下开启GPU硬件加速。

css减少查询层级及范围:如.header .logo要好过.header .top .logo;如.header>li要好过.header li;

避免TAG标签与CLASS或ID并存:如a.top、button#submit;

Javscript具体应用注意点

尽量少用全局变量;

使用事件代理绑定事件,如将事件绑定在body上进行代理;

避免频繁操作DOM节点;

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

减少对象查找,如a.b.c.d这种查找方式非常耗性能,尽可能把它定义在变量里;

类型转换:把数字转换成字符串使用”” + 1,浮点数转换成整型使用Math.floor()或者Math.round();

对字符串进行循环操作,譬如替换、查找,应使用正则表达式;

避免脚本阻塞加载

当浏览器在解析常规的script标签时,它需要等待script下载完毕,再解析执行,而后续的HTML代码只能等待。CSS文件引入要放在头部,因为这是HTML渲染必备元素。为了避免阻塞加载,应把脚本放到文档的末尾,而CSS是需要放在头部的。

HTTP/2 对比HTTP/1 的优势

以上都是针对HTTP/1进行的优化,随着越来越多浏览器对HTTP/2的支持,HTTP/2对web性能有很大的提升,HTTP 2.0将只用于https://网址,而 http:// 网址将继续使用HTTP/1。根据IETF(The Internet Engineering Task Force )发布的官方技术标准 HTML2.0有以下关键特性

头部压缩;

请求/响应管线化;

多路复用请求;

对请求划分优先级;

服务器推送流(即Server Push技术);

HTTP/2具有的特性使它相比HTTP/1x有以下优势。

每个服务器只用一个连接。HTTP/2对每个服务器只使用一个连接,而不是每个文件一个连接。这样,就省掉了多次建立连接的时间,这个时间对TLS尤其明显,因为TLS连接费时间。

HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能

HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决该问题。

多路复用,直白的说就是所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然能利用一个连接完成多次请求,但是多个请求之间是有先后顺序的,后面发送的请求必须等待上一个请求返回才能发送响应。这会很容易导致后面的请求被阻塞,而 HTTP/2 做到了真正的并发请求,每个 Frame Header 都有一个 Stream ID 就是被用于实现该特性。每次请求/响应使用不同的 Stream ID。就像同一个 TCP 链接上的数据包通过 IP:PORT 来区分出数据包去往哪里一样。通过 Stream ID 标识,所有的请求和响应都可以欢快的同时跑在一条 TCP 链接上了。 当流并发时,就会涉及到流的优先级和依赖。优先级高的流会被优先发送。图片请求的优先级要低于 CSS 和 SCRIPT,这个设计可以确保重要的东西可以被优先加载完。

Server Push:服务端能够更快的把资源推送给客户端。通常,只有在浏览器请求某个资源的时候,服务器才会向浏览器发送该资源。Server Push则允许服务器在收到浏览器的请求之前,主动向浏览器推送资源。比如说,网站首页引用了一个CSS文件。浏览器在请求首页时,服务器除了返回首页的HTML之外,可以将其引用的 CSS文件也一并推给客户端。有些人对Server Push存在一定程度上的误解,认为这种技术能够让服务器向浏览器发送“通知”,甚至将其与WebSocket进行比较。事实并非如此,Server Push只是省去了浏览器发送请求的过程。只有当“如果不推送这个资源,浏览器就会请求这个资源”的时候,浏览器才会使用推送过来的内容。如果浏览器本身就不会请求某个资源,那么推送这个资源只会白白消耗带宽。

加速TLS交付。HTTP/2只需一次耗时的TLS握手,并且通过一个连接上的多路利用实现最佳性能。HTTP/2还会压缩首部数据,省掉HTTP/1.x时代所需的一些优化工作,比如拼接文件,从而提高缓存利用率。

适合内容混杂的页面。HTTP/2特别适合混合了HTML、CSS、JavaScript、图片和有限多媒体的传统页面。浏览器可以优先安排那些重要的文件请求,让页面的关键部分先出现,快出现。

HTTP/1 时代,我们为了节省昂贵的 HTTP 连接(TCP 连接),采用了各种优化手段。但是,有了 HTTP/2 的多路复用和头部压缩,HTTP 连接变得可以随心所欲了,本文提到的这些连接数优化手段确实可以退休了,使用HTTP/2可以让Web开发者省很多事,因为不用再做那些针对HTTP/1.x的优化工作了。但是目前HTTP/1还没退出历史舞台,如何在每种情况下,都能给用户提供最好的体验,需要更加深入的优化研究和更加精细的优化策略。由此可见,在很长一段时间内,WEB 前端的性能优化非但不会落幕,反而会更加重要

参考引用

Hypertext Transfer Protocol version 2.0 HPACK: Header Compression for HTTP/2

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180208G0UM4R00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

关注

腾讯云开发者公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券