Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

影响首屏加载的原因 #50

Open
oliver1204 opened this issue Jul 16, 2017 · 0 comments
Open

影响首屏加载的原因 #50

oliver1204 opened this issue Jul 16, 2017 · 0 comments

Comments

@oliver1204
Copy link
Owner

oliver1204 commented Jul 16, 2017

做H5开发的小伙伴们一直很关心的问题就是首屏。一般大家都知道,从纯前端角度讲,dom树的深度 会很影响加载速度,但是产品和设计的需求不会降低,尽量减少对 dom 的操作方面现有的框架 vueangular
react 等框架对尽其所能的对他们做了优化,所以,其实这方面的改动就很小了。所以从另一方面将,我们只能从网络方面入手。

思路主要就是两个方面:

  • 减少网络延迟时间
  • 高效利用缓存 CDN(减少重复的I/O,减少网络延迟)

目前最大的两个问题

1.网络延迟

有两个方面对此影响:

1、tcp慢启动。

2、数据源所在地。例如我们在杭州,如果服务器在北京,那么每次获取信息都是在北京与杭州之间来回传输,肯定比杭州到杭州的服务器之间慢很多。

2.链路无法复用

我们知道HTTP 1.0 的请求是无状态的,且每次链接都需要 TCP 3次握手后才可以得以链接。费事又费力。

对于问题一,目前大多数的解决办法是CND, 这里涉及到一些httphttp-cache缓存的知识。对于问题二,有 keep-alive , socket 等等方式。但是都会有一定的负面代价。比如说,http 本来是短链接,我们通过timeout 限制它在多少时间内不进行3次握手校验,势必 要增加server内存,预先扩容 。即使这样实际提升也只有200毫秒左右。

HTTP 2.0

http 1.0 是1999年开始使用的,一直沿用到现在。但是随着web应该不断的在更新,地位不断的在上升,各个框架不断的在优化,但是如果协议方面不做任何的优化,其实还是指标不治本。我们的服务性能还是会被底层服务所限制。

首部压缩

http 是基于文本的协议,分为 header 和 body 。由于http 1.0是无状态的,在我们发送第一个请求和第二个请求时浏览器是不知道他们之间的关系的。所以我们目前来说通常是利用 cookie 来记录一些信息。

当浏览器加载 HTML 文件中引用的静态资源 —— 如图片、外部 CSS、外部 JS 等 —— 时,若该资源所属域与当前页面相同,则会在 HTTP 头请求中加载当前域的 cookie 信息。

换句话说,如果一个页面上有50张图片,即使一个 cookie 1KB,但是如果你要加载 50 个图片(或其它静态文件),这样发送的 cookie 总量就多达 50KB 了。

不要忘记除了cookie 外还有user Agent.

这也就是为什么我之前很多人很喜欢把 cdn 域名划到主域外,这样就减少了cookie 等不必要的数据量。或者合并请求、启用 Cookie-Free 域名。但http2 就没有必要担心了,http2做了首部压缩。

http2 是有两个指针,一个是头部针和数据针。
在第一次发送http求的时候,它会有以键值队的形式建立一个表

image

:method GET
:scheme https
:host www
:path fdaf

在接下来的每次请求时都会对比这个头部指针所对应,如果没有变化则发送data指针所指的数据。
如果有变更,则发生有变更的数据指针。

http1

image

http2:

image

注意⚠:第二次是只发送变更部分,这意味着会比第一次发送的数据量更少。曲曲的例子
借用他文章中的一图:
image

解释:

  • 维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称与值的组合;
  • 维护一份相同的动态字典(Dynamic Table),可以动态地添加内容;
  • 支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding);

多路复用

多路复用和链路复用不同。

链路复用是说在tcp链路已建立的前提下,那么我就可以不用在建立新的链接了,但是原有的请求还是要按照顺序一条一条的发送。

多路复用是指在建立了一个tcp连接后,在这个连接上我可以双工的进行发送请求、接收请求等。

                                                          ----->
                                            server   <-----       client

而且是可以乱序等,不必再等一个请求结束再开始收另一个请求。这样就不会什么雪碧图啊,减少请求数量等等一系列的问题。它会高效的利用这条链路。

服务端推送

以前我们再请求一个页面时,以前会先返回一个html 文件,再返回css 和js 资源。浏览器再根据css 和js 解析html 。请注意css 和js 资源和html 文件这之间是有时间差的。

而服务器推送,服务器是知道那个html引用了哪个js,css 的,那么它一起返回给我们,前端就可以立刻渲染了。

nice ! but

虽然HTTP 2.0 没有明确指明它必须是 https (SSL),但是 就目前来看 chrome 等大多都是https的,苹果17年1月的新审核规定也要求所有 session 必须是https。

* 因为增加了TSL验证一来一回又增加了200ms * 3 = 600ms的时间
* tcp慢启动,一般的服务器初始化最多可以发送10 个 TCP 包,老一点的有6-4个,首个数据传输来回(RTT)可传输的数据上线是14kb,(前面也说了,即使带宽再大,一开始加载的速度也不会很快)。所以如果要加载的数据大于14kb,接下来它必须等待客户端应答这些数据,然后才能增加它的拥塞窗口并继续发送更多数据。。所以压缩文件体积至关重要。而http2 依旧受此限制。
尤大大 讲编译时优化

但是据腾讯开发者统计,虽然使用了https,但是用了http 2.0 后还是节约了 200-400ms的时间。

服务端渲染

现在的模式是,先请求html,再请求js、css ,再发ajax请求取回json,来渲染,最乐观的情况也需要3个RTT来回。服务端的渲染就是它发一次请求同时返回html、js、css 、json ,这都是渲染好的。

Vue.js 2.4.0 版本提供了内置的服务端渲染与异步组件支持,从而保证了在服务端渲染中也能使用异步组件,而不再是局限于路由中使用。

4 Important Changes In Vue.js 2.4.0

离线包

webview 本身

webview 本身会初始化 webkit 内核和app本身的一些东西,目前很多公司的做法是跨过webview本身,先发送请求到服务器,等webview初始化后,就已经取到了数据。

其他

图片是占带宽最大的,所以针对图片存多种格式的。webP虽然对iphone的支持率低,但是我觉得还是有必要的。

# 无其他办法怎么办?

与用户的交流,目前比较新颖的方式是Skeleton Screen

@oliver1204 oliver1204 changed the title HTTP 2.0 影响首屏加载的原因 Jul 16, 2017
@oliver1204 oliver1204 mentioned this issue Feb 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant