背景

最近做了c端的h5产品,上线后,部分用户投诉说打开很慢,经过调查发现,在网速慢的情况下,部分用户首屏展示需要5-10s,网速快的情况也要将近3s。

在对项目做了一些优化处理后,再次无缓存打开可以发现网页几乎是秒开,平均耗时在1s以内

在这里总结记录一下,基本上都是一些常规可复制的优化手段,希望能为同样想优化网页性能的你提供思路~

更多学习案例尽在我的github

这是优化前的效果:

这是优化过后的效果:


关于优化

在开始之前,我们需要明白一个原则:性能优化的最终目的是提升用户体验。

简而言之就是让用户感觉这个网站很「快」(至少不慢hh),这里的「快」有两种,一种是「真的快」一种是「觉得快」

「真的快」:可以客观衡量的指标,像网页访问时间、交互响应时间、跳转页面时间
「觉得快」:用户主观感知的性能,通过视觉引导等手段转移用户对等待时间的关注
做好这两方面都能提升用户对网站的性能评价。


目标

首先我们需要确定目标,根据场景和项目复杂度不同,制定的目标也不同,比如希望比竞品快20%,或者符合标准的"2-5-10"原则等等

这里我定下的目标是

正常网速下,2s内加载完成


指标和检测分析工具

常用指标

关于指标这块,简单介绍下常见指标:

  • FCP(First Contentful Paint):白屏时间(第一个文本绘制时间)
  • Speed Index:首屏时间
  • TTI(Time To Interactive): 第一次可交互的时间
  • lighthouse score(performance):Chrome浏览器审查工具性能评分(也可以npm install -g lighthouse,编程式调用)

分析工具

Network分析


Lighthouse分析



Webpack Bundle分析


优化方案

优化体积

优化前 chunk.js 2.3m
优化后 chunk.js 860kb

优化包

⚡ 优化Ant-design-icon体积

这一部分,由于我们在项目中只使用了几个Ant内置图标,不可能有530+KB。根据Ant文档的描述是由于其将ICON全量引入的关系导致的,说法是当前用法如果按需加载的话无法确定使用者会不会在运行时改变icon,比如配置的ICON。

所以决定去掉这部分,改成本地的svg。

优化前:529kb 优化后:20kb


⚡ 删除冗余组件

部分组件是不经常用的,但却使用了Vue.use()全局引入了。这里去掉不常用和没用到的全局引入,改为页面内import()引入

看到ant-design-select, upload只有单独的页面用到。放到页面里面去引用,不放在总包里面了。

优化前:500kb 优化后:0


⚡ 部分库按需引入

由于我们只用了,轮播图和提示窗,mint-ui按需引入。

crypto-js 因为我们只用了一个算法,就按需引入单独的sha256算法
import {HmacSHA256} from ‘crypto-js’

优化前:550kb 优化后:120kb


⚡ 使用webp

webP是谷歌推出的新图片格式(2010),同等质量下体积拳打png脚踢jpg,目前兼容性还算可以,就苹果家的表现不太理想


⚡ 优化core-js体积

core-js实际上就是浏览器新API的polyfill,项目是PC端,所以主要是为了兼容IE…

presets: [“@vue/app”]

改成
presets: [
‘@vue/app’,
[
‘@babel/preset-env’,
{
‘useBuiltIns’: ‘entry’
}
]
],

优化前:104kb 优化后 68kb


网络传输优化

⚡优化分包策略

vue-cli3的默认优化是将所有npm依赖都打进chunk-vendor,但这种做法在依赖多的情况下导致chunk-vendor过大

optimization: isProd ? {splitChunks: {chunks: 'all',maxInitialRequests: Infinity, // 默认为3,调整为允许无限入口资源minSize: 20000, // 20K以下的依赖不做拆分cacheGroups: {vendors: {// 拆分依赖,避免单文件过大拖慢页面展示// 得益于HTTP2多路复用,不用太担心资源请求太多的问题name(module) {// 拆包const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]// 进一步将Ant组件拆分出来,请根据情况来// const packageName = module.context.match(/[\\/]node_modules[\\/](?:ant-design-vue[\\/]es[\\/])?(.*?)([\\/]|$)/)[1]return `npm.${packageName.replace('@', '')}` // 部分服务器不允许URL带@},test: /[\\/]node_modules[\\/]/,priority: -10,chunks: 'initial'}}},runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` }
} : {}

⚡ Gzip压缩传输和图片打包压缩

图片压缩 并且开启gzip
gzip加速
第一步安装依赖:
npm install --save-dev compression-webpack-plugin
这样会安装最新的版本,如果你webpack版本过低,则会安装失败。
这里就需要降低compression-webpack-plugin版本,这里我使用的是5.0.1版本
npm install --save–dev compression-webpack-plugin@5.0.1
图片资源压缩

npm install --save image-webpack-loader

使用npm安装命令后,安装失败的话需要调整

cnpm --save install image-webpack-loader

这里就会看到gifsicle已经安装好了

const CompressionPlugin = require("compression-webpack-plugin")
module.exports = {
chainWebpack: config => {//最小化代码config.optimization.minimize(true);//分割代码config.optimization.splitChunks({chunks: 'all'});//开启图片压缩config.module.rule('images').test(/\.(png|jpe?g|gif|svg)(\?.*)?$/).use('image-webpack-loader').loader('image-webpack-loader').options({ bypassOnDebug: true })//开启gzip加速config.plugin('compressionPlugin').use(new CompressionPlugin({test: /\.js$|\.html$|.\css$|\.otf$|\.ttf/, // 匹配文件名threshold: 102400, // 对超过100kb的数据压缩deleteOriginalAssets: false // 不删除源文件}))},
}

⚡ 预请求预加载

<link>标签的rel属性的两个可选值。
Prefetch,预请求,是为了提示浏览器,用户未来的浏览有可能需要加载目标资源,所以浏览器有可能通过事先获取和缓存对应资源,优化用户体验。
Preload,预加载,表示用户十分有可能需要在当前浏览中加载目标资源,所以浏览器必须预先获取和缓存对应资源。


⚡ 开启HTTP2

HTTP2是HTTP协议的第二个版本,相较于HTTP1 速度更快、延迟更低,功能更多。
目前来看兼容性方面也算过得去,在国内有超过50%的覆盖率。
通常浏览器在传输时并发请求数是有限制的,超过限制的请求需要排队,以往我们通过域名分片、资源合并来避开这一限制,而使用HTTP2协议后,其可以在一个TCP连接分帧处理多个请求(多路复用),不受此限制。(其余的头部压缩等等也带来了一定性能提升)
如果网站支持HTTPS,请一并开启HTTP2,成本低收益高,对于请求多的页面提升很大,尤其是在网速不佳时


⚡ 托管至OSS + CDN加速

当应对一些弱网地区时,OSS + CDN无疑是很强力的提速手段。

海量,安全,低成本,高可靠的云存储服务。可以通过简单的REST接口,在任何时间、任何地点上传和下载数据,也可以使用WEB页面对数据进行管理。


SSR

想要更快可以使用ssr服务端渲染,关于服务端渲染可以看我的另一篇文章。

这里贴上ssr的首页加载速度,可以看到没缓存的情况下快了几倍。页面直接返回了Html内容。


体验优化

预渲染

预渲染是一个方案,使用爬虫技术。由于我们打包过后的都是一些js文件,使用一些技术(puppeteer)可以爬取到项目在chrome浏览器展示的页面,然后把它写入js,和打包文件一起。类似prerender-spa-plugin

不过这种技术的缺点也很明显,我们在打包过程中,所展示的页面是当时环境下的数据,也就是说如果首页有很多的动态获取的数据(比如说实时的股票价格),那如果采用这种方案,用户第一眼看到并不是当时数据,会认为是个错误信息


骨架屏

首屏优化,APP内常见的加载时各部分灰色色块。针对骨架屏页的自动化生成,业界已有不少解决方案。


渐进加载图片

一般来说,图片加载有两种方式,一种是自上而下扫描,一种则是原图的模糊展示,然后逐渐/加载完清晰。前者在网速差的时候用户体验较差,后者的渐进/交错式加载则能减轻用户的等待焦虑,带来更好的体验

先加载小图,模糊化渲染,图片加载完成后替换为原图,最典型的例子就是Medium,模糊化可以用filter或者canvas处理


结尾

以上就是关于指标检测 和具体优化方案,谈到优化其实还有构建优化,缓存优化等等…

性能优化影响的,不仅是用户体验,还影响了转化率、搜索引擎排名,这些因素都会对最终的流量、销量等收入造成影响

来自Google的数据表明,一个有10条数据0.4秒能加载完的页面,变成30条数据0.9秒加载完之后,流量和广告收入下降90%。

Google Map 首页文件大小从100KB减小到70-80KB后,流量在第一周涨了10%,接下来的三周涨了25%。

亚马逊的数据表明:加载时间增加100毫秒,销量就下降1%。

⚡性能优化之首屏秒开相关推荐

  1. 11s到1s,性能优化之首屏加载

    大家好,我是 漫步,今天来看看前端优化的文章,喜欢记得关注我并设为星标. 全文共6511字/词,阅读大概需要13分钟,太长不看党请直接移步

  2. 从龟速 11s 到闪电 1s,详解前端性能优化之首屏加载

    点击上方 前端瓶子君,关注公众号 回复算法,加入前端编程面试算法每日一题群 全文共6511字/词,阅读大概需要13分钟,太长不看党请直接移步

  3. 前端框架/架构,性能优化,负载均衡,首屏渲染

    前端数据结构与算法- https://zhuanlan.zhihu.com/p/27659059 > 前端重构方案 前端重构方案了解一下- https://blog.csdn.net/vM199 ...

  4. Android开发-WebView的缓存处理和性能优化 实现H5页面秒开【四】

    前言 老早之前就想总结下Webview相关的知识点了,因为互联网大潮中,很多APP都会使用到Webview,像那些不计其数的电商APP,无一例外的使用Webview:或者一些非电商APP中的像广告页面 ...

  5. 移动H5首屏秒开优化方案

    随着移动设备性能不断增强,web 页面的性能体验逐渐变得可以接受,又因为 web 开发模式的诸多好处(跨平台,动态更新,减体积,无限扩展),APP 客户端里出现越来越多内嵌 web 页面(为了配上当前 ...

  6. iOS之从OpenGL深入探究离屏渲染及性能优化

    一.探究内容 到底什么是离屏渲染?是在GPU上面还是CPU上面执行的? 为什么要有离屏渲染?什么情况下会产生离屏渲染? 帧缓冲区是什么?当前屏幕缓冲区和屏幕外缓冲区又是什么? 切换缓冲区是什么操作?真 ...

  7. Vue首屏性能优化组件

    Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...

  8. 记一次前端性能优化——vue-cli4优化首屏加载

    记一次前端性能优化--vue-cli4优化首屏加载 一.前言 vue.js是一款时下非常流行的前端框架,很多公司,例如阿里.腾讯.字节等都在积极应用vue作为前端开发框架.这就说明,熟练使用vue开发 ...

  9. 前端白屏问题_前端性能优化之白屏时间

    前言 该篇文章会为您分享在前端性能优化中非常重要的一环-白屏时间,将从白屏时间的概念.重要性以及白屏的过程一一进行阐述,同时提供性能优化的策略与实践. 一.概念 白屏时间:即用户点击一个链接或打开浏览 ...

最新文章

  1. 如何解决机器学习中数据不平衡问题
  2. Qt中rcc工具简介
  3. linux 播放器系统,在Linux上安装和使用开源视频播放器MPlayer
  4. 教你用Python爬虫自制有道翻译词典
  5. java——JMM内存模型
  6. ICMP:Internet控制报文协议
  7. azure 安全组_用户安全和Azure成本风险
  8. 20.HTTP-NG
  9. 《JavaScript高级程序设计 第三版》学习笔记 (十三)高级函数
  10. 第三章 进化算法之遗传算法及其应用
  11. LCD1602的学习与理解
  12. php根据出生日期计算年龄函数
  13. JS--统一社会信用代码校验
  14. cstimothy17-字段,属性,索引器,常量
  15. 点击图片播放音乐实现
  16. linux shell ifs,shell - IFS分隔符
  17. IPv6技术精要(第2版)Rick Graziani
  18. 服装制造企业的云ERP管理
  19. 什么是 Build in Public
  20. XStream java.lang.ClassNotFoundException 问题解决

热门文章

  1. 毕业四年后的程序员继续租房子
  2. 视频文件损坏无法播放怎么修复?
  3. 基于cuda10.0的pytorch深度学习环境配置
  4. 图扑智慧城市 | 搭建政务民生可视化管理系统
  5. 三菱FX5U以太网数据采集方案
  6. android字体加横线
  7. Java原始数据类型
  8. 决策树之五:连续变量计算过程
  9. 121. 买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的
  10. 狄利克雷分布公式_一文详解隐含狄利克雷分布(LDA)