前端页面性能优化

前言

最近参加了两次社招,发现社招面试都会问到性能优化以及框架原理。当中性能优化即使我知道好几种,然而我面试时总是很容易想不起来,只答出了两三种。因此,写一篇博客来对性能优化做一下研究,加深理解。

1、压缩 合并

对于 前端性能优化 自然要关注 首屏 打开速度,而这个速度,很大因素是花费在网络请求上,那么怎么减少网络请求的时间呢?

  • 减少网络请求次数
  • 减小文件体积
  • 使用 CDN 加速

所以 压缩、合并 就是一个解决方案,当然可以用 gulp 、 webpack 、 grunt 等构建工具 压缩、合并。

使用webpack压缩js:

    plugins: [
        new UglifyJSPlugin(),    //打包后文件压缩
    ]

如果是webpack4,可以直接使用:

 mode: 'production' 

用于生产环境,webpack会自动压缩。

使用webpack压缩css,

new OptimizeCSSAssetsPlugin({
    assetNameRegExp: /\.css\.*(?!.*map)/g,  //注意不要写成 /\.css$/g
    cssProcessor: require('cssnano'),
    cssProcessorOptions: {
        discardComments: { removeAll: true },
        // 避免 cssnano 重新计算 z-index
        safe: true,
        // cssnano 集成了autoprefixer的功能
        // 会使用到autoprefixer进行无关前缀的清理
        // 关闭autoprefixer功能
        // 使用postcss的autoprefixer功能
        autoprefixer: false
    },
    canPrint: true
}),

2、缓存

HTTP与缓存相关的头部信息

http协商缓存VS强缓存

缓存这东西,第一次必须获取到资源后,然后根据返回的信息来告诉如何缓存资源,可能采用的是强缓存,也可能告诉客户端浏览器是协商缓存,这都需要根据响应的header内容来决定的。

浏览器缓存包含两种类型,即强缓存(也叫本地缓存)和协商缓存,浏览器在第一次请求发生后,再次请求时:

  • 浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通信;在firebug下可以查看某个具有强缓存资源返回的信息,例如本地firebug查看的一个强缓存js文件。
  • 如果没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服务器根据请求中的相关header信息来比对结果是否协商缓存命中;若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容

强缓存与协商缓存的区别,可以用下表来进行描述:

 获取资源形式状态码发送请求到服务器
强缓存 从缓存取 200(from cache)否,直接从缓存取
协商缓存 从缓存取 304(not modified)是,正如其名,通过服务器来告知缓存是否可用

1、强缓存

强缓存是直接从缓存中获取资源而不经过服务器;与强缓存相关的header字段有两个:

1)expires

当客户端第一次访问一个文件资源的时候,服务端在返回资源内容的同时也返回了:

Expires: Mon, 1 Aug 2016 22:43:02 GMT

也就是服务端告诉浏览器,先把这个文件缓存起来,在这个过期时间之前,该文件都不会变化了。

下一次浏览器又要访问这个资源,并且访问的时间在Mon, 1 Aug 2016 22:43:02 GMT之前,那浏览器就不去服务器那边获取文件了,而是直接从缓存中取文件。

2)Cache-Control

由于Expires给定的是绝对时间,而客户端的系统时间可以由用户任意修改,比如Expires设定的过期时间是

Mon, 1 Aug 2016 22:43:02 GMT

现在用户把系统时间改为

Tue, 2 Aug 2016 22:43:02 GMT

则缓存会被判为过期(虽然实际上还没到那个时间)。因此在HTTP1.1中引入了Cache-Control,这就是一个相对时间,比如

Cache-Control: max-age=80

那就是说这份缓存的有效期是80秒,而没有给定过期的绝对时间。

由于Cache-Control是HTTP1.1中才有的,因此可能会有Expires和Cache-Control同时出现的情况,这时以Cache-Control为准。

2、协商缓存

协商缓存都是由服务器来确定缓存资源是否可用的,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段

1)Last-Modified/If-Modified-Since

  • 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间
     
  • 浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
     
  • 服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header
     
  • 浏览器收到304的响应后,就会从缓存中加载资源
     
  • 如果协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified的Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值

2)Etag/If-None-Match

这两个值是由服务器生成的每个资源的唯一标识字符串,只要资源有变化就这个值就会改变;其判断过程与Last-Modified/If-Modified-Since类似,与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值