前端性能优化

巴拉米 等级 459 0 0

为什么要做性能优化?性能优化有多重要?网站的性能对于用户的留存率、转化率有很大的影响,直白的说,提高网站的性能可以直接提高网站带来的收益。

性能优化的分类

前端的性能优化主要分为两类:

  1. 加载时优化;
  2. 运行时优化;

例如压缩文件、使用CDN加载静态资源属于加载时优化;及时的解绑事件、减少DOM的操作属于运行时优化。

吉德林法则:遇到问题,只有先弄清楚问题,才能很好地解决问题。所以在做性能优化之前,最好先看一下网站的加载性能和运行性能。

手动检查

检查加载性能

一个网站看加载性能如何主要看首屏时间和白屏时间。

  1. 白屏时间:指输入网址,到页面开始显示内容的时间;
  2. 首屏时间:指输入网址,页面完全加载完成之后的时间;

可以将以下代码放在</head>前,就能获取白屏页面白屏时间。

<script>
    new Date().getTime() -
performance.timing.navigationStart
</script>

window.onload 事件里执行 new Date().getTime() - performance.timing.navigationStart 可以获取首屏完全加载所用时间。

检查运行性能

这里我们就用chrome的开发者工具查看运行时的性能。

打开网站,F12进入浏览器控制台,选择performance,点击左上角的灰色圆点,变为红色即开始记录了。这时可以模仿用户使用网站,在使用完毕后,点击stop,然后就能看到网站运行期间的性能报告。如果有红色块,说明有掉帧的情况;如果为绿色,说明帧率高,网页比较流畅。

在performance选项下,按ESC会弹出来一个小框,点击小框左边的三个点,把rendering勾出来。

前端性能优化
前端性能优化

第一个是高亮重绘区域,另一个是显示帧渲染信息。勾上之后,再去浏览网页,便可以实时看到网页的渲染变化。

利用工具检查

chrome工具 Lighthouse
前端性能优化

这个工具会对网站进行性能打分。

加载时性能优化

1.减少HTTP请求

一个完整的http请求要经历DNS查找,TCP握手,浏览器发出http请求,服务器接收请求,服务器处理请求并发回相应,浏览器接收相应过程。下图为一个http请求实例:
前端性能优化

名词解释:

  • Queueing: 在请求队列中的时间;
  • Stalled: 从TCP连接建立完成,到真正可以传输数据之间的时间差,此事件包括代理协商时间。
  • Proxy negotiation:与代理服务器连接进行协商所花费的时间。
  • DNS Lookup:执行DNS查找所需要的时间,页面上每个不同的域都需要进行DNS查找。
  • Initial Connection/Connecting: 建立连接所花费的时间,包括TCP握手/重试和协商SSL。
  • SSL:完成SSL握手所花费的时间。
  • Request sent: 发出网络请求所花费的时间。
  • Waiting(TTFB): TTFB是发出页面请求到接受到应答数据的第一个字节的时间。
  • Content Download: 接收响应数据所花费的时间。

可以看出真正的下载数据时间为13.05 / 204.16 = 6.39%,要提高这个比例,就要将多个小文件合并为一个大文件,从而减少HTTP请求次数的原因。

2.使用HTTP2

解析速度快

HTTP/2采用二进制格式传输数据,而非HTTP/1的文本格式,二进制协议解析起来更高效。HTTP/1的请求和响应报文,都是由起始行,首部和实体正文组成,各部分之间以文本换行符分隔。HTTP/2将请求和响应数据分隔为更小的帧,并且它们采用二进制编码。
HTTP/2中,同域名下所有的通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。

多路复用

HTTP/1中,如果想并发多个请求,必须使用多个TCP链接,且浏览器为了控制资源,还会对单个域名有6-8个的TCP链接请求限制。
HTTP/2中,不再依赖TCP链接去实现多流并行了,在HTTP/2中:

  • 同域名下所有通信都在单个TCP连接上完成
  • 单个连接可以承载任意数量的双向数据流
  • 数据流以消息的形式发送,而消息又有一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装

这一特性,使性能有了极大的提升。

优先级

在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级,数值越大优先级越低。服务器收到这样的请求后,可以优先处理。

服务器推送

HTTP2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。

服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。

服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端

3.使用服务端渲染

客户端渲染:获取HTML文件,根据需要下载javascript文件,运行文件,生成DOM,再渲染。

服务端渲染:服务端返回HTML文件,客户端只需要解析HTML。

  • 优点:首屏渲染快,SEO友好;
  • 缺点:涉及构建设置和部署的更多要求,更多的服务器负载。

4.静态资源使用CDN

内容分发网络(CDN)是一组分布在多个不同地理位置的 Web 服务器。我们都知道,当服务器离用户越远时,延迟越高。CDN 就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。

5.将css放在头部,javascript文件放在底部

所有放在 head 标签里的 CSS 和 JS 文件都会堵塞渲染。如果这些 CSS 和 JS 需要加载和解析很久的话,那么页面就会一直显示空白。所以 JS 文件要放在底部,等 HTML 解析完了再加载 JS 文件。

CSS放在头部是因为:如果CSS放在尾部,会让用户第一时间看到没有样式的页面,比较的‘难看’,为了避免这种情况发生,将CSS放在头部。

6.使用字体图标iconfont代替图片图标

字体图标就是将图标制作成一个字体,使用时就跟字体一样,可以设置属性,例如 font-size、color 等等,非常方便。并且字体图标是矢量图,不会失真。还有一个优点是生成的文件特别小。

压缩字体文件

使用fontmin-webpack插件对字体文件进行压缩,可以更进一步的减小字体的大小。

7.善用缓存,不重复加载相同资源

为了避免用户每次访问网站都得请求文件,我们可以通过添加 Expires 或 max-age 来控制这一行为。Expires设置了一个绝对时间,只要在这个时间之前,浏览器都不会请求文件,而是直接使用缓存。而 max-age 是一个相对时间,建议使用 max-age 代替Expires。

  • max-age: 设置缓存存储的周期,超过这个时间缓存被认为过期。在这个时间前,浏览器读取文件不会发出新请求,而是直接使用缓存。
  • no-cache: 表示客户端可以缓存资源,每次使用缓存资源都必须重新验证其有效性。

8.压缩文件

压缩文件可以减少文件的下载时间,提升用户的体验。

在webpack可以使用如下插件进行压缩:

  • javascript: UglifyPlugin
  • CSS: MiniCssExtractPlugin
  • HTML: HtmlwebpackPlugin

还可以使用gzip压缩,可以通过向HTTP请求头中的Accept-Encoding添加gzip标识来开启这一功能。当然,服务器也得支持这一功能。

webpack配置:

下载插件

npm install compression-webpack-plugin --save-dev

配置:

const CompressionPlugin = require('compression-webpack-plugin')

module.exports = {
    plugins: [new CompressionPlugin()]
}

9.图片优化

  • 图片延迟加载

在页面中,先不给图片设置路径,只有当图片出现在可视区域内时,再去加载真正的图片,这就是延迟加载。对于图片很多的网站,一次性的加载太多的图片会对用户的体验造成很大的影响。可以参考这篇文章 web前端图片懒加载实现

  • 降低图片质量

例如 JPG 格式的图片,100% 的质量和 90% 质量的通常看不出来区别,尤其是用来当背景图的时候。

压缩方式有两种:一种是通过在线压缩网站;一种是通过webpack插件image-webpack-plugin;

npm i -D image-webpack-loader

webpack配置

{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 10000,
                name: utils.assetsPath('img/[name].[hash:7].[ext]')
            }
        },
        {
            loader: 'image-webpack-loader',
            options: {
                bypassOnDebug: true
            }
        }
    ]
}
  • 尽可能使用CSS3效果代替图片

尽量使用CSS的效果,比如渐变、阴影等,因为代码大小通常比图片小得多;

10.按需加载代码,提取第三方库代码,减少冗余代码

  • 根据文件内容生成文件名,结合import动态引入组件实现按需加载

通过webpack配置outputfilename属性的值选项中有一个[contenthash],它将根据文件内容创建出一个hash。当文件有变化时,[contenthash]也会有变化。

output: {
  filename: '[name].[contenthash].js',
  chunkFilename: '[name].[contenthash].js',
  path: path.resolve(__dirname, '../dist'),
},
  • 提取第三方库

由于引入的第三方库一般比较稳定,不会经常改变。所以将它们单独提取出来,作为长期缓存是一个更好的选择。这里需要使用webpack4的splitChunk插件cacheGroups选项。

module.exports = {
    optimization: {
        splitChunks: {
            chunks: 'async',
            minChunks: 30000,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    }
}

缓存组因该是SplitChunksPlugin中最有趣的功能了。在默认设置中,会将 node_mudules 文件夹中的模块打包进一个叫 vendors的bundle中,所有引用超过两次的模块分配到 default bundle 中。更可以通过 priority 来设置优先级。

reuseExistingChunk:表示是否使用已有的 chunk,如果为 true 则表示如果当前的 chunk 包含的模块已经被抽取出去了,那么将不会重新生成新的。

参考文章 使用split-chunks-plugin代码分割

具体配置查看官方文档 split-chunks-plugin

收藏
评论区

相关推荐

用 webpack 4.0 撸单页/多页脚手架 (jquery, react, vue, typescript)
1.导语 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;首先来简单介绍一下webpack:现代 JavaScr
一文搞懂什么是HTTP与HTTPS
(https://blog.csdn.net/petterp/article/details/102779257)Http与Https的区别。 在最近的开发中,深感网络相关基础知识薄弱,于是趁周末好好总结一
20 张图彻底弄懂 HTTPS 的原理
前言 近年来各大公司对信息安全传输越来越重视,也逐步把网站升级到 HTTPS 了,那么大家知道 HTTPS 的原理是怎样的吗,到底是它是如何确保信息安全传输的?网上挺多介绍 HTTPS,但我发现总是或多或少有些点有些遗漏,没有讲全,今天试图由浅入深地把 HTTPS 讲明白,相信大家看完一定能掌握 HTTPS 的原理,本文大纲如下: HTTP 为什么不安全
Webpack 5.0 初体验
<p style"textalign: center;"<img class"rich_pages" dataratio"0.66640625" datas"300,640" src"https://usergoldcdn.xitu.io/2020/4/12/1716ebf44174dac8?w1080&h720&fjpeg&s
Webpack 打包资源篇
<section datatools"新媒体排版" dataid"13439" datastyletype"9" style"visibility: visible;"<p style"maxwidth: 100%; visibility: visible;"<br mpafromtpl"t" style"visibility
开发 vue3 + ts + vite / webpack 的管理系统
cooladmin 地址 演示 账户:admin 密码:123456 介绍 由来cooladmin自 2018 年初以来,一直本着快速通用开发为理念,同时看重每个页面的设计,无论在代码上还是 UI 设计上都受到广大开发者的喜爱。cool是酷的意思,admin一般的认知是
Vue进阶(幺柒柒):Vue应用Sass、Scss、Less和Stylus
Vue项目中使用预处理器,可以有效减少css代码量, 推荐使用Sass、Scss、Less预处理器。可以在创建项目的时候选择预处理器 (Sass/Less/Stylus)。如果当时没有选择,内置的 webpack 仍然会被预配置为可以完成所有的处理,也可以手动安装相应的 webpack loader: Sassnpm
Webpack 热更新以及原理
什么是热更新模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块,而无需完全刷新一般的刷新我们分两种: 一种是页面刷新,不保留页面状态,就是简单粗暴,直接 window.location.reload()。 另一种是基于 WDS (Webpackde
React.js中JSX的原理与关键实现
在开始开发之前,我们需要创建一个空项目文件夹。安装1. 初始化 npm init y 2.安装webpack相关依赖npm install webpack webpackcli D 3. 安装babelloader相关依赖 npm install babelloader @babel/core @babel/presetenv D 4.
Webpack学习整理集锦【从最基础的demo入手,自己实现一个脚手架 】
前言本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。开源网址https://github.com/maomi
webpack 基本配置
概念本 质上,webpack是一个现代 JavaScript 应用程序的 静态模块打包器(module bundler) 。当 webpack处理应用程序时,它会递归地构建一个 依 赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle 。 安装确保安装了nodejs 项目文件环境cd
https://cloud.tencent.com/developer/article/write/1830331
一、目标今天的目标是这个sign和appcode 二、步骤 Jadx没法上了app加了某梆的企业版,Jadx表示无能为力了。 FRIDADEXDumpDexDump出来,木有找到有效的信息。 Wallbreaker葫芦娃的Wallbreaker可以做些带壳分析,不过这个样本,用Frida的Spawn模式可以载入,Attach模式会失败。而直接用Objecti
Next.js 11 的 一些新特性
作者: ✏️在6 月 15 日举行的上,来自世界各地的开发者,共同见证了 Vercel 团队最新版本的发布。Next.js 11 中包含的更新和新功能对已经流行的库进行了重大改进。在本文中,我们将深入研究其中一些对用户和开发人员体验都产生影响的更新。让我们开始吧!一致性就其核心而言,一致性是一组原则或编码指南,它将一些决策责任从开发人员手中夺走。通过设置默认
vscode+vue简单安装教程
1、安装vscode、node.js。2、打开vscode终端,全局安装vuecli:npm install g vuecli用于构建项目。3、继续安装webpack(打包工具):npm install g webpack。4、安装完成创建一个文件夹用于存放项目,比如myvue,cd到该文件夹,使用项目创建命令:vue init webpack myvue。
Vue 从安装到创建项目
1.安装Node可以直接在官网中下载安装默认自动安装Node和NPM(Node Package Manager) 完成后检查安装版本:node v npm v2.安装webpack webpack全局安装npm install webpack g3.安装vue脚手架 全局安装脚手架3npm install @vue/cli g 备注