1.前端性能优化有哪些方法

一、减少操作量

       1.尽量减少 HTTP 请求

          1) 合并文件,比如把多个 CSS 文件合成一个; 

           2) CSS Sprites 利用 CSS background 相关元素进行背景图绝对定位; 

       2. 不要在 HTML 中使用缩放图片

       缩放图片并没有减少图片的容量,只是控制了图片的大小。

       有时候,我能得到的图片尺寸并不那么合乎要求(我说过了,我通常不太会自己做图片),但为了在网页中显示出我希望的尺寸,我会很自然地想到通过如下的方式来图片进行缩放:

  <</span>img width="100" height="100" src="mycat.jpg" alt="My Cat" />

缩放的意思其实是说:不管mycat.jpg这个图片原始尺寸是多少,我通过明确地设置图片宽度和高度,要求它最终显示出来的尺寸是100px * 100px.很显然,浏览器下载到原始图片之后,如果原始尺寸与目标尺寸不符,就会需要对图片进行缩放(拉伸或者缩小),以便实现刚才所提到的目的。

      所以,请记住并遵守这条原则:你需要在网页中显示什么尺寸的图片,就请图片设计人员提供什么尺寸的图片,而不是在网页中进行缩放。

       3.Image压缩

         使用工具对图片进行压缩,保证质量的同时减少了图片的大小。

       4.减少对DOM的操作

          减少对DOM的操作,减少页面的重绘。


二、提前做加载操作


对域名进行预解析
例如京东的做法

预载入组件或延迟载入组件
把 CSS 放到代码页上端
CSS 放到最顶部,浏览器能够有针对性的对 HTML 页面从顶到下进行解析和渲染。
使用 new Image对象,对图片进行缓存


三、提升并行加载
切分组件到多个域 ,提升服务器的响应能力

四、JavaScript和CSS优化


从页面中剥离 JavaScript 与 CSS
剥离后,能够有针对性的对其进行单独的处理策略,比如压缩或者缓存策略。
精简 JavaScript 与 CSS
使用工具压缩JavaScript和CSS文件
脚本放到 HTML 代码页底部
减少对页面的阻塞。


五、异步加载
使用Ajax实现异步加载,例如,滚动页面加载后面的内容,这种也比较常见,即懒加载。



Web前端性能优化是一个复杂的过程,涉及到的知识点非常多,包括网页,服务器,CSS,Javascript,图片等方面。之前雅虎有总结过Web性能优化的14条原则,在这里我们做一下梳理,下面图片中的内容基本包含了所有可能的方式:

经典面试题-Web前端性能优化方法(1)

性能优化的方式

我们会对这些原则一一进行讲解,由于篇幅过长,我会分为几篇文章来写。今天就先来看看跟次数有关的几个内容

规则1-减少HTTP请求数量

图片-CSS Sprites

我们都知道图片对于页面来说是一个独立的资源,每张图片都会发送一次HTTP请求去获取。如果页面上任何大小的图片都发送一次请求,那么对于图片类型的网站性能来说将会是一个噩耗,那么我们该怎么做呢?

假想一下,如果多张类似于导航的小图片都集成在一张大图片上,只需要发送一次请求就可以得到,然后通过位置去获取具体的图片,这样是不是会减少很多次HTTP请求呢?

没错,这就是CSS Sprites(雪碧图)的由来,它主要是将多个图片合成为一张图片,然后通过位置获取具体的图片。下图就是一张雪碧图

经典面试题-Web前端性能优化方法(1)

雪碧图

在使用雪碧图时,一般会设置一个通用的类,它们有共同的background-image属性,然后具体的类通过background-position属性去获取具体的位置,如下代码所示

经典面试题-Web前端性能优化方法(1)

使用CSS Sprites图的样式





图片-Base64编码

在之前写过的一篇文章《关于图片的Base64编码,你了解吗?》中,讲过Base64编码的图片,也可以减少HTTP请求的次数。但是使用这种方式也存在弊端,太大的图片并不适合Base64编码,而且图片并不会被缓存,Base64编码的图片需要看真实环境再使用。

CSS,JS文件合并

在一个系统中我们通常会将页面的HTML,CSS样式,Javascript脚本区分开,但是也并不是说CSS和JS文件划分的越细越好,因为每个CSS和JS文件都会发送一次HTTP请求,能合并的CSS和JS文件都合并。一般一个网站会有一个通用的CSS和JS文件,然后每个页面都会有一个CSS和JS文件。

规则2-减少DNS查询次数

DNS的解析会消耗时间,如果在页面上嵌入不同域下文件比较多,例如在页面广告中嵌入的图片和脚本,在页面的首次加载时,解析这些外部的DNS会消耗一定的时间。下面是CSDN极客头条首页加载请求的JS文件,在该页面中就有很多个来自外域请求的JS文件。

经典面试题-Web前端性能优化方法(1)

外域请求的JS文件

规则3-避免页面跳转

在服务器处理完HTTP请求后,会返回HTTP响应报文,如果浏览器收到的是一个3XX的响应,则网页会进行重定向。在报文头中会包含如下信息,浏览器会根据重定向的信息重新发送一次请求,如果重定向的次数过多,则网页会一直呈现刷新状态,而用户却看不到内容,这是一中很糟糕的用户体验,因此应该避免页面太多的跳转。

经典面试题-Web前端性能优化方法(1)

响应头信息

减少DOM元素的数量

网页在渲染的过程中,会根据HTML元素去生成DOM树,然后绑定上特定的CSS样式,这就意味着页面上的DOM元素越多,就会消耗越多的渲染时间,因此应该尽可能的减少DOM元素的数量。

但是一个页面的DOM元素多少为多,还不好判定。通过以下代码可以查看一个页面中所有元素的数量

Web前端性能优化的几种方法,值得你看看

获取页面所有元素

查看了以下Google的主页面,页面看起来很简洁,不过里面也有300多个元素

Web前端性能优化的几种方法,值得你看看

Google主页面元素个数

根据域名划分内容

浏览器在加载内容时遵循这样一个原则:它会按照域名对下载内容进行划分,相同域名下的内容可以并行下载,但是对并行下载连接数会有所限制。

需要注意的是同一个网页下请求的不同域名不应该太多,因为这会造成DNS查询的问题。

一般网站的设计会选择将静态资源放在static.example.com域名下,动态内容放在www.example.com域名下。我们来看下Google主页面的设计

Web前端性能优化的几种方法,值得你看看

Google主页面资源划

减少iframe的数量

使用iframe既有利也有弊

优势

1.最常见的就是页面加载广告,使用iframe可以和页面并行加载,不会阻塞主页面

2.浏览器会对iframe进行安全沙箱保护,保证内容安全性

弊端

1.iframe的加载会阻塞主页面的onload事件

可以通过以下的方法去解决阻塞主页面的onload事件的问题

Web前端性能优化的几种方法,值得你看看

解决阻塞主页面onload问题

2.iframe与主页面共享下载连接池

在上一点中有讲到,页面对同一域名下的资源连接数有限制,而iframe与主页面是共享同一个下载连接池的,这样iframe会对主页面的连接请求进行争夺,造成主页面加载速度变慢。

虽然使用iframe也有好处,但还是应该尽量减少iframe的使用,可以使用div代替

避免404页面

在网络上,每一个HTTP请求对于性能的消耗都是昂贵的,如果发送了一个HTTP请求返回的是404,对于资源来说是一个极大的浪费。

避免404主要是针对网站开发人员来说,网站开发人员应该在上线之前进行测试,避免所有可能出现404的情况。

延迟加载

一个页面的展示如果每次都要等到所有内容都加载完毕,页面的加载速度势必会受到很大影响,这个时候延迟加载的优势就体现出来了。

延迟加载是保证页面初次加载时,所需要的最小内容集,其他的内容在需要的时候再进行加载,这可以保证页面只需加载最少的资源,加快响应速度。

JS延迟加载

Javascript文件延迟加载有几种方法,这里我就简单的表述几种

让js最后加载

在引入外部js文件时,我们将js文件放在

的结束标签之前,这样可以让js文件在最后引入,从而可以加快页面加载速度。下面这张图就是百度首页的js文件,可以看到这些文件是放在页面的底部的
经典面试题-Web前端性能优化方法之延迟加载

让js文件最后加载

使用setTimeout方法

使用setTimeout方法,动态的添加js脚本到head中

经典面试题-Web前端性能优化方法之延迟加载

setTimeout方法

Google帮助页面的推荐方案

将下面代码添加至

标签之前,然后修改defer.js为项目中具体的js文件路径。
经典面试题-Web前端性能优化方法之延迟加载

Google帮助页面推荐方案

需要注意的是这个外部引入的文件中不应该包含页面正常加载需要的js代码,而应该是一些在页面加载后才执行的js代码,例如绑定的click,change事件。

使用lazyload.js插件

lazyload.js是一款jQuery插件,使用方法如下

经典面试题-Web前端性能优化方法之延迟加载

lazyload.js插件

CSS文件延迟加载

CSS文件的延迟加载同样有几种方法,这里做下总结

使用lazyload.js插件

这里同js文件的延迟加载一样,引入lazyload.js

经典面试题-Web前端性能优化方法之延迟加载

lazyload延迟加载

使用setTimeout方法实现

我们同样可以使用setTimeout方法去实现css的延迟加载

经典面试题-Web前端性能优化方法之延迟加载

setTimeout实现css延迟加载

预加载

预加载技术主要是通过预测浏览器在未来某个时间需要用到的资源,提前进行加载,在特定的时间段内直接使用即可。作为开发者,肯定比普通用户更加了解网页资源的加载顺序,因此通过预加载技术来告知浏览器Web中需要用到的核心资源,可以提升网页的访问速度。

预加载技术包括很多个方面,包括DNS prefetching,Preconnect,Prefetch,Subresource,Prerender等,我们一一来看

DNS prefetching

DNS prefetching顾名思义,就是提前解析DNS。

开发人员可以通过代码告知浏览器尽早的解析特定DNS,当请求该域名下的文件时,就不用再解析DNS,而是可以直接使用该DNS下的文件了。这中方法在使用第三方库时显得尤为有效。

使用方法是,在

标签中添加如下一段代码
经典面试题-Web前端性能优化方法之预加载

DNS预加载

Preconnect

Preconnect类似于DNS prefetching,它会预先建立TCP握手连接,在需要的时候还会建立TLS连接。

在现代浏览器中,会尽可能的预测网站所需要的连接,通过提前连接,可以消除在真实请求时的DNS解析,TCP连接的时间。

开发者可以通过代码去告知浏览器哪些资源是可以提前连接的,代码段如下

经典面试题-Web前端性能优化方法之预加载

Preconnect提前连接

Prefetch

Prefetch是告知浏览器在未来某个时候需要用到的资源,可以提前请求并缓存下来,等到真正需要用的时候,可以直接从缓存中获取。Prefetch可以预拉取图片,css,js等资源文件。

通过以下代码我们可以实现一张图片的预拉取并缓存起来。

经典面试题-Web前端性能优化方法之预加载

Prefetch预拉取

当然,浏览器并不是在任何情况下都会去执行预拉取操作,比如在网络情况不好的情况下不会请求较大的资源,Firefox只会在空闲时去执行Prefetch操作。

Subresource

Subresource是用来指定加载资源的高优先级,使用的方法如下。

经典面试题-Web前端性能优化方法之预加载

Subresource提前加载

Subresource与Prefetch不同,Prefetch指定是未来的页面需要用到的低优先级的资源,而Subresource指定的是当前页面需要用到的高优先级的资源。因此,在指定当前页面中需要用到的资源时,推荐用Subresource,而在后续页面中用到的资源提前加载推荐用Prefetch。

Prerender

Prerender可以让浏览器提前加载指定页面上的所有资源。

Prerender我们可以这样理解:浏览器实际上会在后台开启一个隐藏的标签页,在这个标签页中会下载页面上需要的所有资源,如果用户进入了指定的链接,则这个隐藏的页面会立马显示出来,而用户是无法辨别这个页面是之前的隐藏页面还是重新开启的页面。

经典面试题-Web前端性能优化方法之预加载

Prerender预加载

并不是所有的页面都适合Prerender特性,如果用户最终未能进入指定的链接的页面,那么提前加载的很多资源文件会浪费很多的带宽。

我们可以分析一下一些比较适合使用Prerender特性的页面:

一个具有分页展示的图片集或者文字集,在我们点击下一页的时候,可以将下一页的内容使用Prerender属性预加载

注册与登录页面,新用户注册完成之后一般会选择去登录,登录页面完成之后会跳转到主页面,这两个过程就比较适合Prerender属性的预加载