tech share
  • tech-share
  • Engineering
    • 登录鉴权
    • SSR 页面路由
    • npm 版本号
    • 缓存
    • 数据库容灾
    • 动态效果导出 gif
    • Chrome-devtools
    • C 端 H5 性能优化
    • Docker
    • Monorepo 最佳实践
    • 技术架构演化
    • 项目规范最佳实践
    • snowpack
    • 静态资源重试
    • 前端页面渲染分析
    • Git
    • 前端重构
    • 微前端
    • 项目依赖分析
    • 前端监控原理
    • webpack
    • BS 架构与 CS 架构
    • HTTPS
    • package-lock.json 生成逻辑
    • SVN(Subversion)
    • 数据库分类
    • gulp
    • 前端架构
    • Bundle & Bundless
    • 控制反转 IoC
  • JavaScript
    • Javascript 性能
    • JavaScript 原型(2) - 原型与原型链
    • JavaScript 原型(1) - 构造函数
    • JavaScript - Promise
    • ES6 解构赋值
    • 前端离线化
    • Proxy
    • Object.defineProperty()简介
    • TypeScript
  • MachineLearning
    • GAN生成对抗网络
    • 虚拟对抗训练
    • 深度度量学习
    • 原型网络
    • PyTorch优化器
    • 隐马尔可夫模型2
    • Shapley Value 算法
    • Embarassingly Autoencoder算法
    • AutoRec算法及其后续发展
    • 深度学习常用激活函数
    • 序列预测ConvTran算法
    • 联邦学习
    • 深度学习推荐系统算法整理
    • 隐马尔可夫模型
    • 黎曼优化方法
    • FM算法
    • 机器学习常见评价指标
    • VAE算法
    • Adam优化器详解
    • Transformer算法
    • Self-attention 推荐算法
    • CNN 卷积神经网络
    • 图嵌入
    • 集成学习算法
    • RecBole开源框架
    • NCE-PLRec
    • 深度学习初始化方法
    • RNN循环神经网络
    • PyTorch数据处理
    • PyTorch安装和基本操作
    • XGBoost算法
    • NCF算法与简单MF的对比
    • 计算最佳传输
  • CSS
    • 什么是BFC
    • 纯CSS实现可拖动布局
    • 滚动穿透解决方案
  • React
    • React 生命周期
    • React Ref
    • React Hooks
    • SWR
    • React 数据流
    • React 函数式组件和类组件的区别
  • 可视化
    • OffscreenCanvas
    • Echarts 平滑曲线端点为什么不平滑
    • 颜色空间
    • 词云布局解析
    • 3D 数学基础
    • Canvas 图片处理
    • GLGL ES
    • WebGL 中绘制直线
    • Graphics API
    • 现代计算机图形学基础
    • Canvas 灰度
  • Vue
    • Vue2.x全局挂载整理
    • Vue2.6.x源码阅读
      • Vue2.6.x源码阅读 - 2.目录结构分析
      • Vue2.6.x源码阅读 - 4.源码阅读-platform
      • Vue2.6.x源码阅读 - 1.准备工作
      • Vue2.6.x源码阅读 - 5.源码阅读-core-Vue构造函数
      • Vue2.6.x源码阅读 - 7.源码阅读-core-响应式原理
      • Vue2.6.x源码阅读 - 3.源码阅读-shared
      • Vue2.6.x源码阅读 - 6.源码阅读-core-组件挂载
    • Vue + TypeScript Web应用实践
    • Vue2.x指令
    • nextTick()的使用
    • vue-cli2.x 的使用与项目结构分析
    • Vue响应式原理及总结
    • VueX的使用
    • Electron-Vue + Python 桌面应用实践
    • Vite
    • Vue组件通信整理
    • 记录一个问题的探索过程
  • Linux
    • memcg
  • GameDev
    • 游戏中的几种投影视图
    • 从零开始写软渲染器06
    • 从零开始写软渲染器05
    • 从零开始写软渲染器04
    • 从零开始写软渲染器03
    • 从零开始写软渲染器02
    • 从零开始写软渲染器01
    • 从零开始写软渲染器00
    • 现代游戏常用的几种寻路方案(一)
  • Node
    • NPM Dependency
    • Node 优势
    • Node Stream
    • Node 模块系统
  • HTML
    • html5语义与结构元素
  • 跨端
    • Flutter 介绍
  • Golang
    • Golang 基础
  • AR
    • SceneKit
由 GitBook 提供支持
在本页
  • 页面性能指标
  • 定义
  • 量化
  • 服务端页面直出
  • 渲染流程
  • 性能分析
  • 极端场景优化
  • Ajax 前端渲染页面
  • 渲染流程
  • 性能分析
  • 极端场景优化
  • Bigpipe
  • 渲染流程
  • 性能分析
  • React SSR
  • API
  • 极端场景优化
  • NSR
  • 对比
  • 适用场景
  • 网络优化
  • Queue
  • DNS

这有帮助吗?

  1. Engineering

前端页面渲染分析

页面的渲染经历了服务端页面直出,ajax 请求

页面性能指标

定义

  1. 白屏时间:用户打开页面到页面出现东西为止

  2. 首屏时间:首屏所有内容呈现花费的时间

  3. 用户可操作时间: 用户可以正常点击/操作的时间

  4. 页面完成时间:所有脚本执行完成,等待用户输入

量化

定义 T 值:表示一个过程的耗时,例如一次数据处理,或者一次网络请求。

  • 一次网络请求,总耗时为一个 T

  • 一次服务端处理,包含拉去数据,数据处理,模版渲染,总耗时为一个 T

  • HTML 解析执行,为一个 T

  • 脚本执行渲染过程,为一个 T

服务端页面直出

通过服务端返回完整 HTML 进行渲染。

渲染流程

  1. 服务端下载 HTML

  2. 数据获取

  3. 数据处理以及返回

  4. 页面渲染,输出 HTML

性能分析

  • 白屏时间 2T-4T(两次网络交互,两次数据处理)

  • 首屏时间 5T (多一次 HTML 渲染执行)

  • 用户可操作时间 5T

  • 页面完成时间 5T

极端场景优化

如果数据拉取时间过长,会导致白屏时间过长。 优化上可以将 response write 的形式先将 loading 渲染到页面上,用户体验会好很多。

Ajax 前端渲染页面

渲染流程

  1. 下载 HTML

  2. 服务端渲染,输出基本 HTML

  3. 解析渲染执行 HTML

  4. 脚本执行

  5. Ajax 数据请求

  6. 服务端获取数据

  7. 服务端处理数据

  8. 返回 Ajax

  9. 渲染页面内容

性能分析

  • 白屏时间 2T(一次网络交互,一次数据处理) 1-2

  • 首屏时间 3-4T (多一次 HTML 渲染执行,或者再加一次脚本渲染 loading) 1-4

  • 用户可操作时间 7T(多两次网络时间+1 次数据处理+脚本渲染)1-9

  • 页面完成时间 8T+ 1-9+

极端场景优化

如果数据拉取时间过长,会导致白屏时间过长。 优化上可以用 js 渲染内容占位,或者直接在 HTML 内加入。

Bigpipe

根据模块依赖关系来决定渲染顺序,理论上可以同时渲染所有模块。复杂度会高一些。 可以实现将重要的模块先渲染,后续模块再渲染。 这种思想也可用于预加载数据,后端请求数据,然后不断在 HTML 插入脚本保存数据。

渲染流程

性能分析

  • 白屏时间 1-2T

  • 首屏时间 2-3T

  • 用户可操作时间 2-3T

  • 页面完成时间 2-3T

React SSR

React SSR 在渲染时 2 阶段直接渲染出 HTML,Ajax 方式是 4 阶段才能得到页面

API

  • renderToStaticMarkup

  • renderToString

  • renderToStaticNodeStream

  • renderToNodeStream

极端场景优化

  1. 服务端 接收到页面请求之后,异步输出一个“框架”,loading 页或者占位。

  2. 服务端 与此同时,获取数据。

  3. 客户端 渲染完毕首屏之后是 pending 状态,此时没有任务可执行。加载 react 和业务代码开始让客户端执行。(最好什么框架都不用,此时让客户端等待)

  4. 服务端 拉取到数据之后有两种方式处理成异步模块,按需 thunk 输出。 选择一: 处理数据按照 UI 模块按需输出 json。对应到客户端的 dispatch action 或者渲染方法调用。 选择二: 将数据渲染成 html 模块。对应到客户端的 insert 方法。

  5. 客户端 接收到 thunk 模块,调用执行。

  6. 服务端 send 文档结束标识,结束渲染。

NSR

native side render

在客户端上做的类似 ssr 的事情,根据离线的 js bundle 与预加载的 json 数据进行组合,提前渲染出 HTML 页面,在进行类似下一页的操作时可以实现秒开。

对比

指标

直出

Ajax

bigpipe

ssr

白屏时间

2T/4T

2T

1-2T

2T

首屏时间

5T

3T/4T

2-3T

3T

用户可操作时间

5T

7T

2-3T

7T

页面完成时间

5T

8T+

2-3T

8T+

适用场景

直出:静态/表单页面,不依赖数据 Ajax:白屏/首屏耗时少,应用广泛,成本适中 Bigpipe:指标最佳,成本最高 SSR:性能与 SSR 差异不大,但是灵活性最高。单页首屏优化,复杂度略高

网络优化

在浏览器的初次请求与第二次请求差别比较大的地方有 DNS 寻址和初始化 TCP 连接。

Queue

浏览器进行请求时,会根据一些规则对请求进行排队,排队主要的依据有:

  • 等待高优先级请求完毕

  • 同域最大 TCP 连接限制(chrome 是 6 个)

  • 浏览器正在快速的分配磁盘缓存

优先级

  1. head 中的 css 是 highest,script 是 high

  2. async script 是 low

  3. 异步请求默认优先级是 high,普通文本类型优先级最低

如何影响优先级

  1. new Image().src = "请求地址" // low

  2. navigator.sendBeacon("请求地址", {}) // lowest

  3. preload 预加载 匹配未来的加载需求,是强制浏览器执行的指令。在适当的情况下,重复利用同一资源。比如字体文件,比较大的 css 文件。图片等。

  4. prefetch 预提取

    抢占用户下一步可能进行的操作并为其做好准备。当前页面完成加载后,且带宽可用的情况下,这些资源将在 Chrome 中以 Lowest 优先级被提取。

  5. dns-prefetch 预解析 DNS

    preconnect 的子集,仅做 DNS 查询

  6. preconnect 预连接

    当前页面大概率会链接到另外一个地址,告知浏览器方便的时候建立链接,以便下次命中缓存以及节省时间。但是浏览器可能因为没有找到合适的时机而忽略。

DNS

DNS Lookup

  1. 浏览器缓存

  2. 系统缓存

  3. HOSTS

  4. DNS Server

HTTPDNS

HTTPDNS 利用 HTTP 协议与 DNS 服务器交互,代替了传统的基于 UDP 协议的 DNS 交互,绕开了运营商的 Local DNS,有效防止了域名劫持,提高域名解析效率。另外,由于 DNS 服务器端获取的是真实客户端 IP 而非 Local DNS 的 IP,能够精确定位客户端地理位置、运营商信息,从而有效改进调度精确性。

优点

Local DNS 劫持:由于 HttpDns 是通过 IP 直接请求 HTTP 获取服务器 A 记录地址,不存在向本地运营商询问 domain 解析过程,所以从根本避免了劫持问题。

平均访问延迟下降:由于是 IP 直接访问省掉了一次 domain 解析过程,通过智能算法排序后找到最快节点进行访问。

用户连接失败率下降:通过算法降低以往失败率过高的服务器排序,通过时间近期访问过的数据提高服务器排序,通过历史访问成功记录提高服务器排序。

上一页静态资源重试下一页Git

最后更新于4年前

这有帮助吗?