Skip to content

性能优化实现措施 ​

性能优化的重要性

Web 性能包含了服务器请求和响应、加载、执行脚本、渲染、布局和绘制每个像素到屏幕上的整体过程。在用户感知的有效范围内,实时加载、及时响应、流畅交互和视觉稳定,是促使用户持续性使用网站与消费的重要保障。提升性能,不仅可以增强用户体验,更能吸引用户、留住用户,最后提高网站转化率,从而实现营收的增长。网站速度每提高一秒钟,移动用户转化率最高可提高 27%。

RAIL性能模型 ​

RAIL 是一种以用户为中心的性能模型,代表 Web 应用生命周期的四个不同方面:响应、动画、空闲和加载。它提供了一种考虑性能的结构。该模型将用户体验分解到按键操作(例如,点击、滚动、加载)中,帮助您为每个操作定义性能目标。

  • 响应:在50毫秒内处理事件。
  • 动画:在10毫秒内生成一帧。
  • 空闲:最大限度增加空闲时间。
  • 加载:2秒内交付内容并交互。
# 资源文档
> Chrome DevTools技术文档:https://developer.chrome.com/docs/devtools/overview/


# 注意访问网络问题,有时候需要关掉代理,有时候需要调整不同代理路线
+ 性能优化: <https://web.dev/>


分析运行时性能:https://developer.chrome.com/docs/devtools/performance/

性能框架剖析:https://aerotwist.com/blog/the-anatomy-of-a-frame/
https://aerotwist.com/blog/
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Houdini


最大限度减少主线程工作 https://developer.chrome.com/docs/lighthouse/performance/mainthread-work-breakdown/?utm_source=lighthouse&utm_medium=devtools
Lighthouse: 优化网站速度  https://developer.chrome.com/docs/devtools/lighthouse/#main




> 性能优化:https://developers.google.com/speed/docs/insights/LeverageBrowserCaching
> 重排优化:https://developers.google.com/speed/docs/insights/browser-reflow
> 快速加载优化:https://web.dev/fast/#prioritize-resources
> 提高网站性能的技术:https://web.dev/fast/#optimize-your-images

> 渲染性能优化之渲染的5个阶段:https://github.com/FrankKai/FrankKai.github.io/issues/195

> 渐进式加载:https://developer.mozilla.org/zh-CN/docs/Web/Progressive_web_apps/Loading

> Web 性能:https://developer.mozilla.org/zh-CN/docs/Web/Performance
> 新一代性能指标 Web Vitals:https://jishuin.proginn.com/p/763bfbd64948
> JavaScript 性能:https://developer.mozilla.org/zh-CN/docs/Learn/Performance/JavaScript
> Web 性能:https://developer.mozilla.org/zh-CN/docs/Web/Performance
> CSS 性能优化:https://developer.mozilla.org/zh-CN/docs/Learn/Performance/CSS
> CSS 和 JavaScript 动画性能:https://developer.mozilla.org/zh-CN/docs/Web/Performance/CSS_JavaScript_animation_performance
> 性能衡量指标:https://developer.mozilla.org/zh-CN/docs/Learn/Performance/Measuring_performance
> 关键渲染路径:https://developer.mozilla.org/zh-CN/docs/Web/Performance/Critical_rendering_path

> 页面速度优化 PageSpeed Tools:https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent

> 技术博客:https://lifesinger.wordpress.com/
> 前端性能的几个基础指标:https://segmentfault.com/a/1190000005784687
> Web 性能优化-首屏和白屏时间:https://lz5z.com/Web%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96-%E9%A6%96%E5%B1%8F%E5%92%8C%E7%99%BD%E5%B1%8F%E6%97%B6%E9%97%B4/
> https://web.dev/metrics/

> lighthouse:https://github.com/GoogleChrome/lighthouse
> 衡量性能:https://web.dev/lighthouse-performance/
> 客户端性能:http://taligarsiel.com/ClientSidePerformance.html
> 加快网站速度的最佳实践:https://developer.yahoo.com/performance/rules.html

> 优化 Web 字体渲染性能:https://www.igvita.com/2014/01/31/optimizing-web-font-rendering-performance/
> 性能优化专项:https://www.igvita.com/
> 高性能浏览器网络:https://hpbn.co/?utm_source=igvita&utm_medium=referral&utm_campaign=igvita-homepage

> 使用 WebP 图像:https://web.dev/i18n/zh/serve-images-webp/
> 用视频替换动画 GIF 以加快页面加载速度:https://web.dev/replace-gifs-with-videos/
> 使用图像 CDN 优化图像:https://web.dev/i18n/zh/image-cdns/
> Web 的浏览器级图像延迟加载:https://web.dev/browser-level-image-lazy-loading/

> 优化页面加载:https://webkit.org/blog/166/optimizing-page-loading-in-web-browser/
> Web 检查器参考:https://webkit.org/web-inspector/

> FOUC 问题:https://webkit.org/blog/66/the-fouc-problem/

> PRPL 模式:https://web.dev/apply-instant-loading-with-prpl/

> 计算样式:https://www.w3.org/TR/1998/REC-CSS2-19980512/cascade.html#computed-value

> 制作快速加载的 HTML 页面:https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Howto/Author_fast-loading_HTML_pages


# 性能优化
> https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery
> https://developers.google.com/speed/docs/insights/about
> https://developers.google.com/speed/docs/insights/rules

> web-vitals指标JS库:https://github.com/GoogleChrome/web-vitals
> web-vitals指标:https://web.dev/i18n/zh/vitals/

> 首字节时间(TTFB):https://web.dev/ttfb/
> 首次内容渲染(FCP):https://web.dev/i18n/zh/fcp/
> 最大内容绘制(LCP):https://web.dev/lcp/ | https://web.dev/i18n/zh/optimize-lcp/
> 首次输入延迟 (FID) :https://web.dev/i18n/zh/fid/ | https://web.dev/i18n/zh/optimize-fid/
> 可交互时间 (TTI):https://web.dev/i18n/zh/tti/
> 总阻塞时间 (TBT):https://web.dev/i18n/zh/tbt/
> 累积布局偏移 (CLS):https://web.dev/i18n/zh/cls/ | https://web.dev/i18n/zh/optimize-cls/
> 与下一个绘制交互(INP):https://web.dev/inp/


> 高性能动画:https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/
> CSS 触发器:https://csstriggers.com/


# 性能检测常用工具
> WebPageTest网站监测神器:   ysungod@163.com | Mi_12356.  
> YSlow:
> PageSpeed tools:



# ############################################## #
# 
# 前端性能整体解决方案(分三个方向执行) | 加载机制 | 执行时机 | 操作响应
# 性能问题:加载阻塞 • 响应延迟 • 执行
# 
> 优化关键:解析环节 | 加载环节 | 执行环节
> 优化核心:充分运用用户空闲时间与浏览器空闲时间去预加载可能被用户激活的资源文件
> 加载机制:按需加载 | 异步加载 | 同步加载 | 并行加载 | 预先加载
> 执行时机:优先执行 | 延迟执行 | 预执行
> 优化目标:首屏秒开 | 首屏视口加载速度 | 弱网环境
# ############################################## #
# 
# 第一方向:检测与排查资源可行性、资源容量、资源大小,实现资源配置的合理化与最优化
> 类库、插件、图片等基础资源的大小问题,尤其是第三方插件的依赖性与大小
> 加载机制:优先按需加载,避免项目不断扩展无限极导致项目核心依赖代码量的增加
# 具体执行措施
> 最大化压缩所有JS、CSS、HTML、图片、媒体等资源
> 所有资源统一按需加载,针对后置依赖的资源统一采用第二方向的技术措施来优化
> 首屏加载优先,优先加载与执行首屏所依赖的资源
> 延迟加载核心业务非必须的资源






##### 网页加载性能分析
> 

##### 网页整体性能分析
> 



###


## 内存检测分析




###

## V8代码分析器




###


## 加载阻塞

### 空间通道阻塞

### 网络速率阻塞





###


## 响应延迟

### 任务执行耗时

### 交互卡顿缓慢






###


## 音频资源
>  



## 视频资源
> 




## 音频资源性能优化
> 



## 移动端性能优化





## 白屏优化措施
> 
### require.js示例



## webpack性能优化





## React性能优化





## Vue性能优化




## 第五章 渲染帧
> 

::: warning 注意事项
对于每秒 60 帧的速率,浏览器有 16.7 毫秒的时间来执行脚本、重新计算样式和布局(如果需要)以及重新绘制正在更新的区域。
:::

### 帧率 (FPS)
> Frames Per Second(FPS),即每秒传输帧数,是浏览器能够重新计算、布局和绘制内容到显示器的速度,是页面运行时每秒帧数的实时估计,是测量用于保存、显示动态视频的信息数量。
+ 每秒钟帧数越多,所显示的动作就会越流畅。
+ 每秒帧数或fps是在一秒钟内可以重新绘制多少帧。
+ 网站计算机图形的目标帧速率是 60fps,电影的帧速率通常为 24 fps。

### 绘制帧吞吐量
> 

### GPU raster(GPU光栅)
> 

### GPU memory(GPU内存)
> 

### 跳帧(掉帧/丢帧)
> 

### 16ms
> 

### 渲染时机
> 






# 
# 第二方向:充分利用浏览器的特征与特性,优化资源调度机制,处理资源的加载机制与执行时机
> 并发请求约束:各种浏览器对并发请求数量的约束限制问题
> 充分利用<link rel="" href="url">标签的REL属性
  <!--充分利用浏览器的空闲时间去最优化调度用户浏览网页所依赖的资源:预解析 • 预连接 • 预获取 • 预渲染 • 预加载-->
  <!--预解析-->
  <link rel="dns-prefetch" href="url" /> 
  <!--预连接-->
  <link rel="preconnect" crossorigin href="url" /> 
  <!--预获取 | prefetch(预测页面)subresource(当前页面)-->
  <link rel="prefetch" crossorigin as="script" href="url" />   <link rel="subresource" href="url" /> 
  <!--预渲染 | prerender(大众浏览器)next(Firefox特有属性)-->
  <link rel="prerender" href="url">  <link rel="next" href="url" /> 
  <!--预加载-->
  <link rel="preload" href="url" />

> 充分利用<script></script>标签的相关属性
  <script src="url" defer="defer" crossorigin="anonymous"></script>  <!--异步加载-->
  <script src="url" async="async" crossorigin="anonymous"></script>  <!--延迟执行-->

> 充分利用DOMContentLoaded、window.onload与document.readyState的关键性机制
  document.addEventListener('DOMContentLoaded', function() {}, false);
  window.onload = function() {};
# 具体执行措施


# 
# 第三方向:代码优化,主要考虑时间上的耗时性与硬件依赖的损耗性
> 执行HTML代码与CSS代码的重绘与渲染的频率问题与耗时问题
> 执行JS代码的解释性问题与耗时问题
> 代码容量大小的加载问题:满足同样需求与性能的基础上,优化代码容量的大小问题
# 具体执行措施
> 


# --------------------------------------- #
# 〔首屏秒开〕
# --------------------------------------- #
> 首屏加载和按需加载,非首屏内容滚屏加载,保证首屏内容最小化
> 模块化资源并行下载


# --------------------------------------- #
# [图片优化]
# --------------------------------------- #
# 资源文档
> 图片优化:https://www.runoob.com/w3cnote/web-image-optimization.html

# webP
> 兼容性:Safari、iOS不支持
> 兼容方案
body.webp
document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') === 0 



CSS 和 JavaScript 等重要资源应该尽早在文档中出现;
应该尽早交付 CSS,从而解除渲染阻塞并让 JavaScript 执行;
非关键性 JavaScript 应该推迟,以避免阻塞 DOM 和 CSSOM 构建;
HTML 文档由解析器递增解析,从而保证文档可以间隙性发送,以求得最佳性能。


# 资源预取和排定优先次序
> 文档、CSS 和 JavaScript 解析器可以与网络协议层沟通,声明每种资源的优先级:初始渲染必需的阻塞资源具有最高优先级,而低优先级的请求可能会被临时保存在队列中。
# DNS预解析
> 对可能的域名进行提前解析,避免将来 HTTP 请求时的 DNS 延迟。预解析可以通过学习导航历史、用户的鼠标悬停,或其他页面信号来触发。
# TCP预连接
> DNS 解析之后,浏览器可以根据预测的 HTTP 请求,推测性地打开 TCP 连接。如果猜对的话,则可以节省一次完整的往返(TCP 握手)时间。
# 页面预渲染
> 某些浏览器可以让我们提示下一个可能的目标,从而在隐藏的标签页中预先渲染整个页面。这样,当用户真的触发导航时,就能立即切换过来。







# --------------------------------------- #
# IO网络传输优化
# --------------------------------------- #






# --------------------------------------- #
# CPU与GPU计算性能优化
# --------------------------------------- #






# 没有绝对的优化,只有相对的优化
# 所有的优化核心:网络传输、CPU、内存、进程、线程



# 资源连接与图片拼合
> 合并图片后,虽然能够将少HTTP请求, 降低网络开销
> 缺陷:内存占用,浏览器必须分析整个图片,即便实际上只显示了其中的一小块,也要始终把整个图片都保存在内存中。

# 域名分区
> 优势:绕开浏览器对同一域名的请求并发数限制;可以改用IP,而不是域名
> 缺陷:增加DNS解析查询次数、TCP建立连接开销
> 会因为额外的 DNS 查询和 TCP 慢启动而影响性能。



# 优化措施
> 网络环境优化
> 浏览器机制优化
> 资源加载机制优化
> 资源执行时机优化
> 代码层优化
> 缓存策略优化


# 网络环境优化
> 升级HTTP2.0

# 浏览器机制优化
> DNS预解析、页面预渲染、字面与加载
<link rel="dns-prefetch" href="//hostname_to_resolve.com"> 
<link rel="subresource" href="/javascript/myapp.js"> 
<link rel="prefetch" href="/images/big.jpeg"> 
<link rel="prerender" href="//example.org/next_page.html"> 

# 资源加载机制优化
> CND加速配置
> 在不影响性能消耗的情况减少http请求,合并http请求
> 均衡减少DNS查询与域名分区、持久连接
> 资源压缩Gzip、图标拼合
> JS模块化、代码分割
> 按需加载

# 资源执行时机优化
> script的defer与async机制

# 代码层优化
> GPU渲染加速,充分利用CSS3高级属性
> 避免页面回流与重绘
> 禁止DOM反复操作

# 缓存策略优化
> from disk cache、from memory cache
<meta http-equiv="Pragma" content="cache">
<meta http-equiv="Cache-control" content="public">

基础性通用优化措施 ​

静态资源CDN部署 ​

nginx配置gZip压缩加速 ​

html {
  # Gzip压缩配置
  gzip  on;
  gzip_min_length 1k;
  gzip_buffers 4 16k;
  gzip_http_version 1.0;
  gzip_comp_level 2;
  gzip_types text/plain application/javascript application/css text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
  gzip_vary off;
  gzip_disable "MSIE [1-6]\.";
}

按需加载 ​

页面路由按需加载

{
  path: '/',
  name: 'Index',
  component: () => import(/* webpackChunkName: "RouterIndex" */ '@/views/index.vue'),
}

模块代码按需加载

import { module } from 'module.ts';

module();

HTTP/2、HTTP/3配置优化措施 ​

HTTP/3兼容性有待改善,此处省略HTTP/3配置。

server {
  listen          443 ssl http2 default_server;
  server_name      www.ysunlight.com;
  ssl_certificate      /etc/nginx/www.ysunlight.com.crt; 
  ssl_certificate_key  /etc/nginx/www.ysunlight.com.key; 
}

优化请求加载资源通道阻塞 ​

避开拥塞窗口限制:如果所需的数据量超出了初始拥塞窗口的限制(通常是 14.6kB 压缩后大小),系统就需要在您的服务器和用户的浏览器之间进行更多次的往返。如果用户使用的是延迟时间较长的网络(例如移动网络),该问题可能会显著拖慢网页加载速度。因此,合理保持在14.6kB大小范围内,将在很大程度减少数据传输往返。

合理排定资源请求加载优先级 ​

  • 优先级高的、必要性的、非阻塞性的资源置前请求加载。
  • 优先级低的、非必要性的、阻塞性的资源延迟请求加载。
  • 优先级高的、非必要性的、阻塞性的资源推测性请求加载。

代码冗余量清洗与删除 ​

借助webpack与V8内部分析器进行代码冗余或质量审查。

优化执行过程阻塞 ​

  • 合理规划第一屏首次加载数据在第一个事件循环完成后输出。
  • 利用网页渲染引擎规则合理规避正常渲染周期,例如回流、重绘等基本问题。
  • 优化内存泄露与主线程事务阻塞等问题。

八大性能指标优化措施 ​

首字节时间(TTFB)优化 ​

  • 避免多页重定向。
  • 预连接到跨域资源所需的源。
  • 将您的来源提交到HSTS 预加载列表以消除 HTTP 到 HTTPS 重定向延迟。
  • 使用 HTTP/2或HTTP/3。
  • 考虑为尚未指定减少数据使用偏好的用户进行快速页面导航的预测性预取。
  • 在可能和适当的情况下,使用服务器端生成 (SSG) 而非 SSR 进行标记。

首次内容渲染(FCP)优化 ​

  • 消除阻塞渲染的资源。
  • 缩小 CSS。
  • 移除未使用的 CSS。
  • 预连接到所需的来源。
  • 减少服务器响应时间 (TTFB)。
  • 避免多个页面重定向。
  • 预加载关键请求。
  • 避免巨大的网络负载。
  • 使用高效的缓存策略服务静态资产。
  • 避免 DOM 过大。
  • 最小化关键请求深度。
  • 确保文本在网页字体加载期间保持可见。
  • 保持较低的请求数和较小的传输大小。

最大内容绘制(LCP)优化 ​

  • 使用 PRPL 模式做到即时加载:推送(或预加载)最重要的资源、尽快渲染初始路线、预缓存资源、延迟加载其他路由和非关键资源。
  • 优化关键渲染路径
  • 优化您的 CSS
  • 优化您的图像
  • 优化网页字体
  • 优化您的 JavaScript(针对客户端渲染的网站)

页面阻塞总时长(TBT)优化 ​

  • 减少第三方代码的影响
  • 减少 JavaScript 执行时间
  • 最小化主线程工作
  • 保持较低的请求数和较小的传输大小,通过代码拆分来减少 JavaScript 载荷,移动未使用代码,按需加载等。
  • 高效加载第三方 JavaScript

累积布局位移(CLS)优化 ​

  • 始终在您的图像和视频元素上包含尺寸属性,或者通过使用CSS 长宽比容器之类的方式预留所需的空间。
<img src="" width="" height="" alt="" title="" />
  • 除非是对用户交互做出响应,否则切勿在现有内容的上方插入内容。
  • 首选转换动画,而不是触发布局偏移的属性动画,这样能够增强用户对动画的渐变性过渡体验。

可交互时间(TTI)优化 ​

  • 缩小 JavaScript
  • 预连接到所需的来源
  • 预加载关键请求
  • 减少第三方代码的影响
  • 最小化关键请求深度
  • 减少 JavaScript 执行时间
  • 最小化主线程工作
  • 保持较低的请求数和较小的传输大小

与下一个绘制交互(INP)优化 ​

  • 使用postTaskAPI适当地确定任务的优先级。
  • 当浏览器空闲时安排非必要的工作requestIdleCallback。
  • 使用性能分析器来评估离散交互(例如,切换移动导航菜单)并找到需要优化的长任务。
  • 审核您网站中的第三方 JavaScript 以查看它是否影响页面响应能力。

首次输入延迟 (FID)优化 ​

  • 减少第三方代码的影响
  • 减少 JavaScript 执行时间
  • 最小化主线程工作
  • 保持较低的请求数和较小的传输大小

减少主线程工作量 ​

脚本评估 ​

  • 优化第三方 JavaScript
  • 使输入处理程序去除抖动
  • 使用 Web Worker

样式和布局 ​

  • 缩小样式计算的范围并降低其复杂性
  • 避免大型、复杂的布局和布局抖动

渲染 ​

  • 坚持仅使用合成器的属性并管理层数
  • 降低绘制的复杂性并减少绘制区域
  • 解析 HTML 和 CSS
  • 提取关键 CSS
  • 缩减 CSS 大小
  • 推迟非关键 CSS

脚本解析和编译 ​

  • 通过代码拆分减少 JavaScript 载荷
  • 移除未使用的代码

垃圾回收 ​

  • 使用 measureMemory() 监控网页的总内存用量

消除阻塞性资源 ​

WebAssembly技术优化 ​

Service Workers技术优化 ​

Web Workers技术优化 ​

注意事项

当来自多个程序的多个代码对象尝试同时运行的时候,一切都可能变得很慢甚至被阻塞,更不要说浏览器还需要时间来渲染和绘制网站和 UI、处理用户事件等。

解决方案 ​

使用 web workers 可以让主线程另起新的线程来运行脚本,这能够缓解上面的情况。一个设计良好的网站或应用会把一些复杂的或者耗时的操作交给 worker 去做,这样可以让主线程除了更新、布局和渲染网页之外,尽可能少的去做其他事情。

浏览器缓存措施 ​

所有的服务器响应都应指定一种缓存政策,以帮助客户端确定是否以及何时能够重用之前获取的响应。

缓存注意

该资源是否可被缓存、可由谁缓存、可缓存多长时间,以及(如果适用)如何在缓存政策到期后对该资源进行有效的重新验证。

缓存优化指南 ​

  • 指定最佳的 Cache-Control 政策
  • 使缓存的响应失效和更新缓存的响应
  • 缓存核对清单

优化关键渲染路径CRP ​

优化关键渲染路径可以缩短首次渲染的时间。提升页面加载速度需要通过被加载资源的优先级、控制它们加载的顺序和减小这些资源的体积。

请求数量 ​

通过异步重要资源的下载来减小请求数量。

域名分片(Domain sharding) ​

由于浏览器限制了每个域(domain)的活动连接数。为了可以同时下载超过该限制数的资源,域名分片(domain sharding)会将内容拆分到多个子域中。当使用多个域来处理多个资源时,浏览器能够同时下载更多资源,从而缩短了页面加载时间并改善了用户体验。
就性能而言,域名分片的问题在于每个域都需要额外的 DNS 查找成本以及建立每个 TCP 连接的开销。

注意事项

由于 HTTP/2 没有限制并发请求(unlimited concurrent requests),因此启用 HTTP/2 后,就没必要再使用域名分片来解决并发限制了。

文件体积 ​

优化必须的请求数量和每个请求的文件体积。

资源优先级 ​

通过区分关键资源的优先级来优化被加载关键资源的顺序,来缩短关键路径长度。

呈现网页首屏内容 ​

建议:为提高网页加载速度,请限制用于呈现网页首屏内容的数据(HTML 标记、图片、CSS 和 JavaScript)的大小。

  • 合理地构建 HTML,以便首先加载关键的首屏内容

以使来自服务器的初始响应发送必要数据,从而立即呈现网页的关键部分并暂缓呈现其余部分。 这可能意味着,您必须将 CSS 拆分为两个部分:一个负责调整内容 ATF 部分的样式的内嵌部分,以及一个可暂缓呈现的部分。

  • 减少资源所用的数据量
  • 移除会阻止内容呈现的 JavaScript

浏览器必须先通过解析 HTML 标记来构建 DOM 树,然后才能呈现网页。 在此过程中,每当解析器遇到脚本时,它都必须先停止解析 HTML 并执行该脚本,然后才能继续解析。对于外部脚本,系统还会强制解析器等待相应资源下载完毕(这可能会产生一次或多次网络往返过程并导致网页的首次呈现时间延迟)。

  • 内嵌 JavaScript
  • 异步加载 JavaScript
  <script async src="main.js">
  • 延迟加载 JavaScript
  <script defer src="main.js">

如果某些脚本对于初次呈现网页不是必不可少的,此类脚本的加载和执行便可被推迟到初次呈现网页后或网页的其他关键部分加载完毕后。这样做有助于减少资源争用并提高性能。

  • 评估 在服务器上呈现 JavaScript 模板以加快首次呈现速度,然后在网页加载完毕后使用客户端模板。

FOUC无样式内容闪烁 ​

FOUC(Flash Of Unstyled Content),即无样式内容闪烁,IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。

HTML文档性能优化 ​

14KB 规则 ​

JavaScript性能优化 ​

基础性JS优化措施 ​

  • 使用 PRPL 模式应用即时加载
  • 通过代码拆分减少 JavaScript 负载
  • 删除未使用的代码
  • 缩小和压缩网络负载
  • 为现代浏览器提供现代代码以加快页面加载速度
  • 发布、发布和安装现代 JavaScript 以获得更快的应用程序
  • CommonJS 如何让你的包变大

脚本外链加载与执行机制 ​

defer属性 ​

延迟执行,加载完成,延迟到所有脚本执行完毕后,即文档解析完成,即在DOMContentLoaded事件完成时前执行

<script defer src=""></script>

async属性 ​

异步加载,加载完成就执行

<script async src=""></script>

查找对象属性技术的优化 ​

在原型链上查找属性时,原型链上的每个可枚举属性都会被枚举出来,这对性能造成很大的消耗。

  • 使用hasOwnProperty判断是否存在该属性,因为hasOwnProperty 是 JavaScript 中唯一一个处理属性并且不会遍历原型链的方法。
function Person() {}
console.log(Person.hasOwnProperty('sex'));
  • 使用Object.entries()、Object.keys()、Object.values()
  • 注意for...of与for...in的区别
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // 输出:0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // 输出:0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // 输出:3, 5, 7
}

谨慎扩展原生原型 ​

原生原型不应该被扩展,除非它是为了与新的 JavaScript 特性兼容,以及支持 JavaScript 引擎的新特性,如 Array.forEach等。

Tree Shaking ​

Tree shaking 是一个通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code) 行为的术语。
优化建议:将代码未实际运用的冗余代码删除掉,从而有效减少下载效率与解析效率。

运用技巧 ​

ES2015 模块打包工具 rollup 静态模块打包工具 webpack

优化您的第三方JS资源 ​

如果第三方出现服务器问题并且无法交付资源,则渲染将被阻止,直到请求超时,这可能是 10 到 80 秒之间的任何时间。

第三方 JavaScript 性能 ​

任何大量的JavaScript 都会降低性能。但由于第三方 JavaScript 通常不在您的控制范围内,它可能会带来额外的问题。了解第三方 JavaScript 如何影响性能以及您可以采取哪些措施来防止它降低您的网站速度。

  • 网络:第三方脚本通常会增加网络开销
    • 触发额外的网络请求
    • 拉入未优化的图像和视频
    • HTTP缓存不足,导致频繁获取网络资源
    • 服务器资源压缩不足
    • 由不同的第三方嵌入引入的框架和库的多个实例
  • 渲染:如果它在关键渲染路径中同步完成,它会延迟文档其余部分的解析。

识别慢速第三方 JavaScript ​

  • 减少 JavaScript 执行时间:Lighthouse减少 JavaScript 执行时间审计突出显示需要很长时间来解析、编译或评估的脚本。
  • 避免巨大的网络负载:Lighthouse Avoid huge network payloads审计识别网络请求——包括来自第三方的请求——可能会减慢页面加载时间。

高效加载第三方 JavaScript ​

  • 如果它没有为您的网站增加明确的价值,请将其删除。
  • 优化加载过程。
    • 针对 <script> 标记使用 async 或 defer 属性
      <script async src="script.js">
      <script defer src="script.js">
    • 建立与所需来源的早期连接,例如使用<link>中的preconnect、dns-prefetch等。
      <link rel="preconnect" href="http://example.com">
      <link rel="dns-prefetch" href="http://example.com">
    • 延迟加载:如果它们不重要或低于首屏(即,如果用户必须滚动才能查看它们),则延迟加载是提高页面速度和绘制指标的好方法。
      • 将 loading 属性用于延迟加载图像和 iframe 是 JavaScript 技术的绝佳替代方案,并且最近 Chrome 76 中开始可用!
        <img src="image.png" loading="lazy" alt="…" width="200" height="200">
      • Intersection Observer 是一种浏览器 API,可高效检测元素何时进入或退出浏览器视口,并可用于实现此技术。
        var io = new IntersectionObserver(
          entries => { console.log(entries); },
          { /* Using default options. Details below */}
        );
        io.observe(element);
      • lazysizes 是一个流行的 JavaScript 库,用于延迟加载图像和 iframes 。它支持 YouTube 嵌入和小部件。它还具有针对 IntersectionObserver 的可选支持。
    • 优化您使用第三方脚本的方式
      • 第三方 CDN 托管
        • 是因为它们与您的其他资源不在同一来源,所以从公共 CDN 加载文件会产生网络成本。浏览器需要执行 DNS 查找,建立新的 HTTP 连接,并在安全来源上与供应商的服务器执行 SSL 握手。
        • 当您使用来自第三方服务器的文件时,您几乎无法控制缓存。依赖其他人的缓存策略可能会导致不必要地频繁从网络重新获取脚本。
      • 自托管第三方脚本
        • 减少 DNS 查找和往返时间。
        • 改进 HTTP 缓存头。
        • 利用 HTTP/2 服务器推送。
      • 使用服务工作程序缓存来自第三方服务器的脚本
        • 可以让您更好地控制缓存,同时仍能获得第三方 CDN 的好处。
        • 可以控制从网络重新获取脚本的频率,并可以创建一种加载策略,以限制对非必要第三方资源的请求,直到页面到达关键用户时刻。
        • 使用 preconnect 建立早期连接也可以在一定程度上降低网络成本。

CSS性能优化 ​

在 CSS 中选择器的性能优化,提升仅仅是毫秒级的,因为浏览器解析CSS的时间超级快,快到可以忽略选择器优化。

基础性性能优化 ​

  • 推迟非关键 CSS
  • 缩小 CSS
  • 提取关键 CSS
  • 使用媒体查询优化 CSS 背景图像

阻塞渲染优化 ​

浏览器会阻塞渲染,直到它解析完全部的样式,但不会阻塞渲染它认为不会使用的样式,例如打印样式表。通过基于媒体查询将CSS分成多个文件,可以防止在下载未使用的CSS期间阻止渲染。

<!-- blocking -->
<link rel="stylesheet" href="styles.css"> 
<!-- not blocking -->
<link rel="stylesheet" href="print.css" media="print"> 
<!-- not blocking on large screens -->
<link rel="stylesheet" href="mobile.css" media="screen and (max-width: 480px)">

在GPU 上呈现动画 ​

浏览器针对处理CSS动画和不会很好地触发重排(因此也导致重新绘制)的动画属性进行了优化。为了提高性能,可以将被动画化的节点从主线程移到GPU上。

在GPU 上呈现动画

分层确实可以提高性能,但是它以内存管理为代价,因此不应作为 web 性能优化策略的一部分过度使用。

合理使用will-change 属性 ​

CSS will-change 属性告诉浏览器元素的哪些属性需要修改,使浏览器能够在元素实际更改之前设置优化,通过在实际更改前执行耗时的工作以提升性能。

合理使用font-display 属性 ​

根据 @font-face 规则,font-display 属性定义了浏览器如何加载和显示字体文件,允许文本在字体加载或加载失败时显示回退字体。可以通过依靠折中无样式文本闪现使文本可见替代白屏来提高性能。

合理使用contain 属性 ​

CSS的 contain属性允许作者指示元素及其内容尽可能独立于文档树的其余部分。 这允许浏览器针对DOM的有限区域而不是整个页面重新计算布局,样式,绘画,大小或它们的任意组合。

禁止不必要的回流 ​

基础性资源性能优化 ​

  • 内容交付网络 (CDN)
  • 优先考虑资源
  • 预加载关键资产以提高加载速度
  • 尽早建立网络连接以提高感知页面速度
  • 预取资源以加快未来导航
  • 带有音频和视频预加载的快速播放

Web 字体渲染性能优化 ​

基础性性能优化 ​

  • 在字体加载期间避免不可见的文本
  • 优化 WebFont 加载和渲染
  • 减小 Web 字体大小

优先优化页面关键渲染路径 ​

为了让字体渲染得更快,我们需要优化页面的关键渲染路径。

优化 Chrome M33 中的字体获取 ​

Chrome M33 进行了一项重要的优化,将显着提高字体渲染性能。

M33示例时间线

  • 样式计算在页面生命周期的约 840 毫秒内完成。
  • 布局在约 1040 毫秒时触发,之后立即发送字体请求。

优化措施:当样式计算在页面生命周期的约 840 毫秒内完成后,立即发送字体请求,而无需非要等待布局完成后再发送字体请求。

优化网络字体 ​

使用字体加载事件 API 优化网络字体,字体加载事件 API允许我们管理和定义字体的加载方式和时间——我们可以随意安排字体下载,我们可以指定字体的渲染方式和时间等等。
字体加载事件 API 让我们可以完全控制使用哪些字体、何时交换它们(即它们是否应该阻止渲染)以及何时下载它们。
我们直接在 JavaScript 中构造了一个FontFace对象并触发立即获取——我们可以在页面顶部内联此代码段,并完全避免阻塞 CSSOM 和 DOM。

使用 Web Font Loader库 ​

var font = new FontFace("FontA", "url(http://mysite.com/fonts/fontA.woff)", {});
font.ready().then(function() {
  // font loaded.. swap in the text / define own behavior.
});

font.load(); // initiate immediate fetch / don't block on render tree!

网络字体性能检查表 ​

  1. 审核您的字体使用情况并保持精简。
  2. 确保优化字体资源 - 请参阅Google Web Fonts 技巧。
  3. 使用资源计时来检测您的字体资源:测量 → 优化。
  4. 优化每种字体的传输延迟和初始提取时间。
  5. 优化你的关键渲染路径,消除不必要的 JS 等。
  6. 花一些时间使用字体加载事件 API。

图片资源性能优化 ​

优化图片通常可以卓有成效地减少字节数和改进性能:浏览器需要下载的字节数越少,对客户端带宽的争用就越少,浏览器下载内容并在屏幕上呈现内容的速度就越快。
如果您可以消除一个图像资源,该资源相对于页面上的 HTML、CSS、JavaScript 和其他资产通常需要大量字节,那么这始终是最佳优化策略。

注意事项

优化图片之前,要注意编码的数据的类型、图片格式功能、质量设置、分辨率等等。此外,是否最好以矢量格式提供某些图片、是否可通过 CSS 实现所需的效果,以及如何为每类设备传送已进行相应调整的资源。如果您使用第三方工具,则请注意:倘若您的图片在此之前已进行了充分的优化,转换后的图片可能会变大。如果发生这种情况,请使用您的原始图片。

选择正确的图像格式 ​

  • 矢量格式非常适合由简单几何形状(如徽标、文本或图标)组成的图像,但是,当场景复杂时(例如,照片),描述所有形状的 SVG 标记量可能高得令人望而却步。
  • 光栅图像不具有分辨率或缩放独立的相同特性——当您放大光栅图像时,您会看到锯齿状和模糊的图形。因此,您可能需要以不同的分辨率保存多个版本的光栅图像,以便为您的用户提供最佳体验。另一方面,光栅图像带来了更大的挑战,因为它们在每个像素的基础上对图像数据进行编码。因此,像素数越大,光栅图像的文件大小就越大。

几种较旧图像格式的考虑 ​

  • GIF:将调色板限制为最多 256 种颜色,并创建比<video>元素大得多的文件大小。
  • PNG:不应用任何有损压缩算法,将产生最高质量的图像,但文件大小比其他格式要大得多。
  • SVG:如果图像资产包含由几何形状组成的图像,请考虑将其转换为矢量 (SVG) 格式。
  • JPEG:使用有损和无损优化的组合来减小图像资源的文件大小。
  • AVIF:AVIF是最年轻但最高效的高级图像压缩编解码器。相同的图像质量AVIF文件大小比JPEG小10倍。

选择正确的压缩级别 ​

图像通常占网页上下载的大部分字节,并且还经常占据大量视觉空间。因此,优化图像通常可以为您的网站带来最大的字节节省和性能改进:浏览器必须下载的字节越少,客户端带宽的竞争就越少,浏览器下载和呈现有用的速度就越快屏幕上的内容。

使用 Imagemin 压缩图像 ​

运行 Lighthouse 以检查通过压缩图像来改善页面加载的机会。

用视频替换动画GIF ​

用视频替换动画 GIF 以加快页面加载速度,使用 Lighthouse 检查您的网站是否有可以转换为视频的 GIF,如果您有任何可以转换的 GIF,您应该会看到“将视频格式用于动画内容”的建议。

<video autoplay loop muted playsinline>
  <source src="my-animation.webm" type="video/webm">
  <source src="my-animation.mp4" type="video/mp4">
</video>

提供响应式图像 ​

向移动设备提供桌面尺寸的图像可导致数据量比实际需求高出 2-4 倍。应取代这种“一刀切”的方法,转而为不同的设备提供不同的图像。

良好建议

两个图像调整工具是 sharp npm package 和 ImageMagick CLI 工具。

提供多个图像版本 ​

src:使得此代码向不支持srcset 和 sizes 属性的浏览器提供帮助。
srcset:是以逗号分隔的图像文件名及其宽度或密度描述符的列表。
sizes:告诉浏览器图像显示时的宽度。但是,尺寸属性对显示大小没有影响;您仍然需要 CSS。

<img src="flower-large.jpg" srcset="flower-small.jpg 480w, flower-large.jpg 1080w" sizes="50vw">

提供尺寸正确的图像 ​

相对单位:将图像大小调整为适用于所有设备的大小。
绝对单位:调整图像大小以匹配其显示的大小。 适配单位:使用srcset和sizes属性为不同的图像提供不同的显示密度。

使用 WebP 图像 ​

WebP 图像比对应的 JPEG 和 PNG 图像要小——文件大小通常减小 25–35%。这可以减小页面大小并提高性能。

使用图片 CDN 优化图片 ​

图像内容分发网络 (CDN) 在优化图像方面非常出色。切换到图像 CDN 可以节省 40-80% 的图像文件大小。

图像优化清单 ​

  • 首选矢量格式:矢量图像与分辨率和比例无关,这使得它们非常适合多设备和高分辨率世界。
  • 缩小和压缩 SVG 资产:大多数绘图应用程序生成的 XML 标记通常包含可以删除的不必要的元数据;确保您的服务器配置为对 SVG 资产应用 GZIP 压缩。
  • 比旧的光栅格式更喜欢 WebP:WebP 图像通常比旧图像小得多。
  • 选择最佳光栅图像格式:确定您的功能要求并选择适合每个特定资产的格式。
  • 尝试光栅格式的最佳质量设置:不要害怕调低“质量”设置,结果通常非常好,字节节省也很重要。
  • 删除不必要的图像元数据:许多光栅图像包含有关资产的不必要的元数据:地理信息、相机信息等。使用适当的工具去除这些数据。
  • 提供缩放图像: 调整图像大小并确保“显示”大小尽可能接近图像的“自然”大小。特别要密切注意大图像,因为它们在调整大小时占最大的开销!
  • 自动化、自动化、自动化:投资于自动化工具和基础设施,以确保您的所有图像资产始终得到优化。

视频资源性能优化 ​

延迟加载视频 ​

对于由用户启动回放的视频(即不自动播放的视频),可能需要在 <video> 元素上指定 preload 属性。

<video controls preload="none" poster="one-does-not-simply-placeholder.jpg">
  <source src="one-does-not-simply.webm" type="video/webm">
  <source src="one-does-not-simply.mp4" type="video/mp4">
</video>

对于代替动画 GIF 的视频,合理使用poster 属性与playsinline 属性。
使用其他延迟加载库,例如vanilla-lazyload、lozad.js、yall.js、react-lazyload等。

网页性能规则 ​

34 条影响网页性能的规则 ​

  • 尽量减少HTTP请求次数
  • 减少DNS查找次数
  • 避免跳转
  • 可缓存的AJAX
  • 推迟加载内容
  • 推迟加载内容
  • 预加载
  • 减少DOM元素数量
  • 根据域名划分页面内容
  • 使iframe的数量最小
  • 不要出现404错误
  • 使用内容分发网络
  • 为文件头指定Expires或Cache-Control
  • Gzip压缩文件内容
  • 配置ETag
  • 尽早刷新输出缓冲
  • 使用GET来完成AJAX请求
  • 把样式表置于顶部
  • 避免使用CSS表达式(Expression)
  • 使用外部JavaScript和CSS
  • 削减JavaScript和CSS
  • 减少DOM访问
  • 开发智能事件处理程序
  • 减小Cookie体积
  • 对于页面内容使用无coockie域名
  • 优化图像
  • 优化CSS Spirite
  • 不要在HTML中缩放图像
  • favicon.ico要小而且可缓存
  • 保持单个内容小于25K
  • 打包组件成复合文本

Released under the MIT License.