Git Product home page Git Product logo

fumble's Introduction

Hi there 👋

GitHub Stats

GitHub Streak

Profile Views

mona-whisper

fumble's People

Stargazers

 avatar

Watchers

 avatar  avatar

fumble's Issues

【实习总结】从网络性能优化历程看 HTTP2.0 多路复用 - 理论篇

以前我们谈性能优化,关键指标是页面 PLC(加载时间) ,简单的定义就是:浏览器中的加载旋转图标停止时间。

而当前,我们构建的不再是一个网页而是一个动态、交互的应用。现在我们来看看网络性能在其优化历程中是如何一步步的提高的。

先聊一聊 "样式在上,脚本在下" 的最佳实践

为什么 "样式在上,脚本在下" 是最佳实践?

要回答这个问题,我们得首先回顾一下浏览器的架构,了解解析、布局和脚本之间如何相互配合在屏幕上绘制出像素来。

qq 20170818205659

浏览器在解析 HTML 文档的基础上构建 DOM ,同时也会 CSS 对象模型,这两个模型共同创建了 渲染树,之后浏览器就会在屏幕上绘制图形。

优化运行时的渲染和脚本执行固然至关重要,但对于运行在浏览器中的应用来说,迅速而有效的获取网络资源才是第一要义

那么 HTTP 如何有效的获取网络资源?

HTTP1.1 持久连接

在 HTTP1.0 中,每个 TCP 链接开始都有三次握手,要经历一次客户端与服务器间的完整往返。

而在支持持久连接的情况下,就可以避免第二次 TCP 连接时的三次握手、消除另一次 TCP 满启动的往返,节约网络请求。

HTTP1.1 默认启用持久连接,可以在 HTTP 首部添加:

Connection: Keep-Alive

字段来明确要求服务器使用持久连接。

使用多个 TCP 连接

持久连接对连接的性能提升巨大,但浏览器在一次请求发起后呆呆的等待服务器的相应却也不是办法。

然后大多数现代浏览器支持了主机打开6个连接,这意味着:

  • 客户端可以并行分派最多6个请求;
  • 服务器可以并行处理最多6个请求;

这样感觉浏览器可以欢快的加载网络资源了。但是这样的代价、成本却提高了,CPU 占用率提高了,浏览器的开发成本也提高了。

总体来说,这还是没有从根本上解决 HTTP 的限制,是客户端对于web性能提升的一个权宜之计。

为什么限制每个主机最多6个连接,如果客户端超过了最大的连接数,那么后来的所有的客户端请求都会被阻塞。比如,在一个主机上同时打开6个并行下载,再打开第七个请求时,这个请求会挂起,直到前面的请求完成才会执行。这样的情况并不是罕见,比如在应用中,websocketServer sent event和挂起 xhr,都会占用一个 TCP 连接。

HTTP2.0 多路复用

HTTP2.0 中新的二进制分帧层将 HTTP 消息分解为互不依赖的帧,然后乱序发送,最后在另一端重新组合起来。

有点懵,通过一幅图来了解原理:

2388806631-573eeddfc6cef_articlex

HTTP2.0 把消息分解为独立帧,交错发送,然后在另一端按照每个包重新组装(有木有像坐地铁的感觉),就实现了一个连接上有多个请求和响应,从而带来了巨大的性能提升:

  • 并行交错的发送请求、发送响应,请求之间、响应之间户不影响

  • 一个连接可以并行发起多个请求和响应

  • 消除不必要的延迟,从而减少页面加载时间

等等...

参考

Web 性能权威指南
HTTP/2 for a Faster Web

【实习总结】从网络性能优化历程看 HTTP2.0 多路复用 - 实战篇

首先我们搭建一个简单的web服务

const express = require('express')
const path = require('path')
const app = express()

app.set('views', path.join(__dirname, 'view'))
app.set('view engine', 'ejs')
app.use('/public', express.static(path.join(__dirname, 'static')));
app.get('/', (req, res) => {
    res.render('index')
})
app.listen(8096, () => {
    console.log('Server running at port: 8096')
})

本地网速可能过快,建议用 chrome 模拟3g网速

浏览器请求中,我们先看看返回资源的时间轴:

image

很明显的看出先加载 HTML 文件,然后开启三个 TCP 连接并发请求 main.cssjquery_1.jsmain.js 三个文件。

还记得我们的 TCP 的最大连接数是六个吗?如果我们同时请求六个以上的文件会发生什么?

image

由上图我们可以看出,在解析完 HTML 之后,并发发起了 main.cssjquery_1.js ~ jquery_5.js 六个请求,而当 main.css 文件加载完,不在占用一个 TCP 连接,那么浏览器立即去请求了 jquery_6,以此类推。

有个细节我们需要注意一下:

image

当在地址栏输入URL后,DNS寻址开始到三次握手的时间可以计入上图的 DNS LookupInitial connection中,当持久连接开启时,这个 TCP 已经寻址和握手,在以后的重用中,都不会再 DNS 寻址和三次握手。

而当我们再打开一个 TCP 连接时,即新建的这个 TCP 连接还是会进行 DNS 寻址和三次握手。

以上两次都是浏览器在请求头中默认 connection: keep-alive ,服务器返回:
image

// 待补充

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.