共计 4669 个字符,预计需要花费 12 分钟才能阅读完成。
download: 小程序音乐我的项目开发实战 coderwhy
Web 前端性能优化自查清单
前言
一份简洁、纯正的 Web 前端性能优化清单。每个优化点都蕴含有概念、实操和参考资料。面试、实战两相宜。
这是一个大工程。在正式开始之前,先对立下语言,廓清每一部分的目标和要求,避免跑偏。
概念:把官话翻译成能看懂、能记住的人话,原则上易读性 > 专业性
实操:本人操作一遍,不做云玩家;记录外围实现,不便 CV
参考资料:信息起源选用一手材料,以便保障信息的完整性、准确性和时效性。除非看一手的了解不了……
一、网络层面
- DNS 预解析
概念
DNS-prefetch 是一种 DNS 预解析技术。它会在申请跨域资源之前,事后解析并进行 DNS 缓存,以缩小真正申请时 DNS 解析导致的申请提早。对于关上蕴含有许多第三方连贯的网站,成果显著。
实操
增加 ref 属性为“dns-prefetch”的 link 标签。个别放在在 html 的 head 中。
<link rel=”dns-prefetch” href=”//xxx.download.com”>
复制代码
href 的值就是要预解析的域名,对应前面要加载的资源或用户有可能关上链接的域名。
备注
同理,也有“TCP/IP 预连贯”,叫 preconnect。参考资料中有残缺的形容。 - 利用浏览器缓存
概念
浏览器缓存是浏览器寄存在本地磁盘或者内存中的申请后果的备份。当有雷同申请进来时,间接响应本地备份,而无需每次都从原始服务器获取。这样不仅晋升了客户端的响应效率,同时还能缓解服务器的拜访压力。
其间,约定何时、如何应用缓存的规定,被称为缓存策略。分为强缓存和协商缓存。
整个缓存执行的过程大抵如下:
①. 申请发动,浏览器判断本地缓存,如果有且未到期,则命中强缓存。浏览器响应本地备份,状态码为 200。控制台 Network 中 size 那一项显示 disk cache;
②. 如果没有缓存或者缓存已过期,则申请原始服务器询问文件是否有变动。服务器依据申请头中的相干字段,判断指标文件新鲜度;
③. 如果指标文件没变更,则命中协商缓存,服务器设置新的过期工夫,浏览器响应本地备份,状态码为 304;
④. 如果指标文件有变动,则服务器响应新文件,状态码为 200。浏览器更新本地备份。
上述过程有几个关键点
如何判断缓存是否过期?
浏览器读取缓存的申请后果中响应头的 Expires 和 Cache-Control,与以后工夫进行比拟。
其中,Expires 是 HTTP 1.0 的字段,值是一个是相对工夫。
Expires: Tue, 18 Jan 2022 09:53:23 GMT
复制代码
比拟相对工夫,有一个弊病,它依赖计算机时钟被正确设置。
为了解决这个问题,HTTP1.1 新增了 Cache-Control 字段,它的值是一个是绝对工夫。
Cache-Control: max-age=60 // 单位是秒
复制代码
如何判断文件是否变动?
首先能够通过比拟 最初批改工夫。
// 缓存后果的 响应头
Last-Modified: Mon, 10 Jan 2022 09:06:14 GMT
// 新申请的 申请头
If-Modified-Since: Mon, 10 Jan 2022 09:06:14 GMT
复制代码
浏览器取出缓存后果中 Last-Modified 的值,通过 If-Modified-Since 上送到服务端。与服务器中指标文件的最初批改工夫做比拟。
再者能够通过比拟 Etag。
Etag 实体标签是附加到文档上的任意标签(援用字符串)。它们可能蕴含了文档的序列号或版本名,或者是文档内容的校验和及其他指纹信息。当发布者对文档进行批改时,会批改文档的实体标签来阐明这是个新的版本。
从响应头的 ETag 取值,通过申请头的 If-None-Match 上送,与服务器指标文件的 Etag 标签比对。
// 缓存的 响应头
ETag: “61dbf706-142”
// 上送的 申请头
If-None-Match: “61dbf706-142”
复制代码
和下面一样,新增的字段也是为了解决前一种计划的某些缺点:
有些文档可能会被周期性地重写 (比方,从一个后盾过程中写入),但理论蕴含的数据经常是一样的。只管内容没有变动,但批改日期会发生变化。
有些文档可能被批改了,但所做批改并不重要,不须要让世界范畴内的缓存都重装数据 (比方对拼写或正文的批改)。
有些服务器无奈精确地断定其页面的最初批改日期。
有些服务器提供的文档会在亚秒间隙发生变化(比方,实时监视器),对这些服务器来说,以一秒为粒度的批改日期可能就不够用了。
如果两个版本的字段同时存在,怎么办?
出于浏览器兼容方面的思考,个别两组字段会被同时应用。他们没有优先级一说,取并集。
同时呈现时,只有当两个条件都满足,才会命中相应缓存。
实操
缓存是 web 服务器和浏览器的外围能力,支流的 web 服务框架 nginx、koa-static 等都内置有上述缓存策略的实现。开箱即用,无需额定编程或配置。
以 Nginx 举例。强缓存的配置字段是 expires,它承受一个数字,单位是秒。
server {
listen 8080;
location / {
root /Users/zhp/demo/cache-koa/static;
index index.html;
# 留神 try_files 会导致缓存配置不失效
# try_files $uri $uri/ /index.html;
expires 60;
}
}
复制代码
理论工作中的确配置一下就好了,但这体现不出什么知识点。为了加深印象,我这用 koa 简陋的模仿了一下,算是对下面那些知识点的验证。
上面是一个极简的动态资源服务,不带缓存的。
app.use(async (ctx) => {
// 1. 依据拜访门路读取指定文件
const content = fs.readFileSync(./static${ctx.path}
, “utf-8”);
// 2. 设置响应
ctx.body = content;
});
复制代码
这种状况,无论拜访多少次都是不进缓存的。
当初,在响应头加上强缓存所需的 Exprise 和 Cache-Control 字段
app.use(async (ctx) => {
// 1. 依据拜访门路读取指定文件
const content = fs.readFileSync(./static${ctx.path}
, “utf-8”);
// 2. 设置缓存
ctx.response.set(“Cache-Control”, “max-age=60”);
ctx.response.set(‘Exprise’, new Date(new Date().getTime()+60*1000));
// 3. 设置响应
ctx.body = content;
});
复制代码
查看 Network,响应头会多出上面两个字段,且距离 60 秒内的申请会走缓存,合乎预期。
Expires: Tue, 18 Jan 2022 10:05:09 GMT
Cache-Control: max-age=60
复制代码
备注
抱着援用一手权威材料的想法,扒了《HTTP 权威指南》,但读感着实差强人意。老手倡议《图解 HTTP》起手,要敌对很多。
参考资料
《HTTP 权威指南》
HTTP 缓存机制
Nginx 中文文档
- 动态资源 CDN
概念
CDN 的全称是 Content Delivery Network,即内容散发网络。CDN 是构建在现有网络根底之上的智能虚构网络,依附部署在各地的边缘服务器,通过核心平台的负载平衡、内容散发、调度等功能模块,使用户就近获取所需内容,升高网络拥塞,进步用户拜访响应速度和命中率。
外围效用总结起来就两点:
①. 通过负载平衡技术,为用户的申请抉择最佳的服务节点;
②. 通过内容缓存服务,进步用户拜访响应速度。
实操
一般玩家:抉择一个 CDN 服务商,看它提供的应用文档。通过配置域名和源站,代理到本人的动态资源服务器。
高级玩家:自建 CDN 服务器,balabal……
参考资料
阿里云 CDN 疾速入门
- 开启 Gzip
概念
gzip 是 GNUzip 的缩写,最早用于 UNIX 零碎的文件压缩。HTTP 协定上的 gzip 编码是一种用来改良 web 应用程序性能的技术,web 服务器和客户端(浏览器)必须独特反对 gzip。gzip 压缩比率在 3 到 10 倍左右,能够大大节俭服务器的网络带宽。
实操
实际操作过程中分为动静压缩和动态压缩。
动静压缩。指当收到申请后,服务器实时压缩而后输入数据流。服务器寄存的是 css/js 文件。
Nginx 的 httpGzip 模块,反对该性能。次要配置如下:
开启或者敞开 gzip 模块
gzip on;
设置容许压缩的页面最小字节数。倡议设置成大于 1k 的字节数,小于 1k 可能会越压越大。
gzip_min_length 1024;
匹配 MIME 类型进行压缩,(无论是否指定)”text/html” 类型总是会被压缩的。
gzip_types text/plain application/x-javascript text/css text/html application/xml;
复制代码
动态压缩。服务器一开始寄存的就是曾经压缩好的文件,当承受申请后间接响应压缩资源,而不是收到申请后才压缩。
应用 Webpack + Nginx 的实现:
①. 装置并利用 compression-webpack-plugin 压缩插件
// ## 装置 ##
// 留神高版本会报错 Cannot read property ‘tapPromise’ of undefined
npm i –save-dev compression-webpack-plugin@5.0.1
// ## webpack 配置 ##
// vue.config.js
const CompressionPlugin = require(“compression-webpack-plugin”);
module.exports = {
configureWebpack:{
plugins: [new CompressionPlugin()
]
}
}
复制代码
②. 执行构建 npm run build
打包实现后,在 dist 目录下会多出.gz 结尾的压缩文件
③. Nginx 配置开启 gzip_static
http{
gzip_static on;
server {
listen 8082;
location / {root /Users/zhp/demo/demo-externals/dist;}
}
}
复制代码
后果验证
在 Response Header 中看到有 Content-Encoding: gzip,阐明服务器配置失效;
在 Network 的 Size 列看数据比服务器上源文件要小,阐明浏览器反对,Gzip 失效。
备注
gzip_static 的优先级高于 gzip。当 gzip 和 gzip_static 都开启时,nginx 会优先匹配.gz 文件,而后才走动静压缩。
参考资料:
你真的理解 gzip 吗?
www.npmjs.com/package/com…
- 应用高版本的 HTTP 协定
概念
从 1.0 到 1.1 再到现在的 2.0,HTTP 协定在继续迭代中,变的更快更强。
其间的变更内容多且硬核,这里出于解释高版本劣势的目标,简略的列举一二,HTTP/1.1 的长久连贯和管道化技术、2.0 的多路复用和首部压缩。
长久连贯
HTTP 协定的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连贯。为了缩小了 TCP 连贯的反复建设和断开所造成的额定开销。HTTP/1.1 和一部分的 HTTP/1.0 想出了 长久连贯(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的办法。长久连贯的特点是,只有任意一端 没有明确提出断开连接,则放弃 TCP 连贯状态。