【前端性能优化】

一、p95页面优化

概念

95%的概率在800ms内打开

不能优化验收标准(周访问量>500):

  1. 能使用页面或者数据缓存的已经使用缓存(不能优化页面必须达到的条件)
  2. 有缓存的页面papm平均加载时长不超过1.4s,无缓存的papm平均加载时间不超过2s(动画H5、游戏H5、视频、PDF除外)
  3. 页面请求已做分析,分析内容包含js、css、图片、请求等资源个数。Gzip后最大js、css不超过100K,最大图片不超过150K,请求个数不超过100个
  4. 已分析首次加载页面的请求个数及各个接口时间,接口超过800ms的已和后端确认不能再优化,且已做options预请求缓存处理(不能优化页面的场景之一)
  5. 第三方静态资源(视频、图片、pdf)已推进关联方优化(不能优化页面必须达到的条件)
    6.用户体验时,页面在1s内能加载首屏内容(达到此要求可不继续优化)

二、预加载

背景

以图片为例

  1. 将图片转换为base64编码的data-url集成到css文件中,避免图片资源的单独加载,但图片内联会增加css文件的大小,增加首屏渲染的时间
  2. 使用js代码创建Image实例对图片进行预加载,不仅增加了冗余代码,还需要自己控制好加载时机
preloadImage() {
    const imgList = [
        require('@/assets/imgs/error.png'),
        require('@/assets/imgs/ticket_bg.png')
    ];
    for (let i = 0; i < imgList.length; i++) {
        const newIMG = new Image();
        newIMG.src = imgList[i];
    }
}

以上两种方案能够解决我们的问题,但都存在一些缺点。
那么有没有更好的解决方案呢?
答案是preload、prefetch,一种由浏览器原生提供的预加载方案。

概念

preload 是告诉浏览器页面必定加载这些资源
prefetch 是告诉浏览器页面可能需要加载这些资源
dns-prefetch dns预获取,对于浏览器可能需要加载的资源提前进行域名解析

preload

  • 指明哪些资源是在页面加载完成后即刻需要的
  • 在浏览器的主渲染机制介入前就进行预加载,且更不易阻塞页面的初步渲染,进而提升性能
  • preload link必须设置as属性来声明资源的类型(font/image/style/script等),否则浏览器可能无法正确加载资源。
<link rel="preload" href="xxx" as="xx">

prefetch

  • 利用浏览器空闲时间来下载或预取用户在不久的将来可能访问的文档
  • 通过link标签来实现预加载
  • 在network 中可以看到size列为prefetch cache,表明这次请求的资源来自prefetch缓存
<link rel="prefetch" href="/library.js">

dns-prefetch

当浏览器从第三方获取资源时,必须先将跨域的域名解析为ip地址,即dns解析,dns解析可能导致明显的延迟,大大降低加载性能,而dns-prefetch 预解析就可以解决这个问题

还可以考虑与preconnect(预连接)相结合,因为dns域名解析为ip后,会经过tcp连接和三次握手,两者结合可以减少与第三方的连接感知。但当第三方连接很多时会适得其反,所以仅用于最关键的连接

Preload 和 Prefetch 的具体实践

webpack插件preload-webpack-plugin可以帮助我们将该过程自动化,结合htmlWebpackPlugin在构建过程中插入link标签

默认情况下,一个Vue CLI应用会为所有初始化渲染需要的文件自动生成preload提示。这些提示会被@vue/preload-webpack-plugin注入,并且可以通过chainWebpack的config.plugin(‘preload’)进行修改和删除。

const PreloadWebpackPlugin = require('preload-webpack-plugin');
...
plugins: [
  new PreloadWebpackPlugin({
    rel: 'preload'as(entry) {  //资源类型
      if (/\.css$/.test(entry)) return 'style';
      if (/\.woff$/.test(entry)) return 'font';
      if (/\.png$/.test(entry)) return 'image';
      return 'script';
    },
    include: 'asyncChunks', // preload模块范围,还可取值'initial'|'allChunks'|'allAssets',
    fileBlacklist: [/\.svg/] // 资源黑名单
    fileWhitelist: [/\.script/] // 资源白名单
  })
]
Object.keys(pages).forEach(entryName => {
      config.plugins.delete(`preload-${entryName}`)
      config.plugins.delete(`prefetch-${entryName}`)
    })

应用场景

  1. 大部分场景下无需特意使用preload
  2. 类似字体文件这种隐藏在脚本、样式中的首屏关键资源,建议使用preload
  3. 异步加载的模块(典型的如单页系统中的非首页)建议使用prefetch
  4. 大概率即将被访问到的资源可以使用prefetch提升性能和体验

三、gzip压缩

概念

gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积。

实现

  1. webpack在打包时可以借助 compression webpack plugin 实现gzip压缩
  2. 在vue cli3.0 生成的项目里,在 vue.config.js 中配置配置CompressionWebpackPlugin插件
  3. 生成的压缩文件以.gz为后缀,一般浏览器都已支持.gz的资源文件,在http请求的Request Headers 中能看到 Accept-Encoding:gzip
  4. 要使服务器返回.gz文件,还需要对服务器进行配置,根据Request Headers的Accept-Encoding标签进行鉴别,如果支持gzip就返回.gz文件
npm i -D compression-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin');
plugins.push(
    new CompressionWebpackPlugin({
        asset: '[path].gz[query]',// 目标文件名
        algorithm: 'gzip',// 使用gzip压缩
        test: new RegExp(
            '\\.(js|css)$' // 压缩 js 与 css
        ),
        threshold: 10240,// 资源文件大于10240B=10kB时会被压缩
        minRatio: 0.8 // 最小压缩比达到0.8时才会被压缩
    })
);

四、多域名CDN

cdn概念

cdn译为内容分发网络,通过在网络各节点处放置节点服务器,将网站内容发布到各个节点,让用户在距离最近的网络节点拿到所需的信息,也就是减少网络传输距离,加快响应速度

使用CDN服务的网站,只需将其域名的解析权交给CDN的负载均衡设备,CDN负载均衡设备将为用户选择一台合适的缓存服务器,用户通过访问这台缓存服务器来获取自己所需的数据

原理

  1. 用户在浏览器中输入要访问的域名。
  2. 浏览器向DNS服务器请求对域名进行解析,CDN的DNS服务器将CDN的负载均衡设备IP地址返回给用户。
  3. 用户向CDN的负载均衡设备发起内容URL访问请求。
  4. CDN负载均衡设备会为用户选择一台合适的缓存服务器提供服务。
    选择的依据包括:
    根据[用户IP地址],判断哪一台服务器距离用户最近;
    根据[用户所请求的URL中携带的内容名称],判断哪一台服务器上有用户所需内容;
    查询[各个服务器的负载情况],判断哪一台服务器的负载较小。
    基于综合分析,负载均衡设置会把缓存服务器的IP地址返回给用户。
  5. 用户向缓存服务器发出请求。
  6. 缓存服务器响应用户请求,将用户所需内容传送到用户。
    如果这台缓存服务器上并没有用户想要的内容,而负载均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉取到本地。

多域名原理

  1. 在http1.1下,各浏览器对同一域名下的并发请求数量有限,在4-8个以内,谷歌是6个
  2. 为什么有并发限制呢,因为一个请求对应一个线程,并发数量巨大会导致线程的频繁切换,产生性能问题。
  3. 当资源较多且达到并发数的时候,会阻塞后面的请求任务,等空闲再继续执行
  4. 所以可以通过多个域名来加载不同类型的资源,来解决单个域名并发限制,从而提高网页响应速度

五、异步无阻塞加载JS

同步加载js文件

先来看一个普通的 script 标签解析过程。

1
停止解析 document.
请求 a.js
执行 a.js 中的脚本
继续解析 document
异步加载 js 文件,并且不会阻塞页面的渲染

defer

1
2
不阻止解析 document, 并行下载 d.js, e.js
即使下载完 d.js, e.js 仍继续解析 document
按照页面中出现的顺序,在其他同步脚本执行后,DOMContentLoaded 事件前 依次执行 d.js, e.js。

asnyc

1
2
不阻止解析 document, 并行下载 b.js, c.js
当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在 DOMContentLoaded 事件前或者后 )

六、webp

webp是一种新的图片格式,它的体积只有 JPEG的2/3,将图片资源大量换成 webp 格式可以加快请求的速度。
webp 格式在浏览器兼容上还有一定的问题,所以需要判断浏览器是否支持 webp 格式

七、感知性能优化

1.添加加载动画

加载进度条动画
加载旋转圆圈动画
加载骨架屏动画

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值