简述一次网页浏览行为的过程

100
TaoAlpha
2014-11-261475 words5 minutes to read

原文其实是讲述我们应该如何为性能做更好的考虑, 其中简单介绍了一个request从发出到结果展现的整个过程, 尤其是其在移动网络和常规网络的区别非常有趣, 所以特定分享以下.

我们的上网行为, 简单来说就是一个浏览器和一个网络服务器之间的数据交换. 而从我们点了确认/提交/Go之后, 到页面开始进行加载, 这个过程基本就是一个请求啦. 拆解一下呢, 我们初始的请求会带着一些参数从浏览器出发发送到一个DNS服务器上去, 它会把URL解析为一个IP地址来找到我们这个URL指向的主机, 然后又DNS向主机发送请求, 获取指定的主机内容, 再返回给我们的浏览器.

Diagram showing how data moves between browsers and servers.

整个过程就是如此了. 这基本是我们常规的设备通过wifi或者有限网络浏览网络的全过程了. 那么对于一个连接到移动网络的设备而言, 会多出一步了: 浏览器首先会把请求发送给信号基站, 由信号基站转发给DNS, 然后开始正常的网络请求循环. 而这个多余的过程, 即便是以3G速度而言, 也需要一定的时间, 相对于网络中以百万分之一毫秒来计算, 这个时间绝对不短. 大致算下来, 移动设备联网过程会比Wifi要慢2s之多.

Diagram showing how data moves on a mobile network.

2s看起来比较短, 但实际上对于连300ms的延迟都能感觉到的用户而言, 2s绝对是个灾难性的影响了. 这也是为什么移动网一直比不上wifi的原因了.

不过幸运的是, LTE和4G的慢慢普及, 相信这种差别一定会降低很多, 以后的访问速度一定会快很多的.

至于说请求返回浏览器后到页面真正完整展示出来的过程, 其实是浏览器的渲染过程了, 这个很多时候取决于浏览器本身的渲染引擎和机制了. 通常来说, 除了本身的HTML外, 主要有CSS和JS两个资源需要加载, 通常来说, css会优先加载, 在html文档渲染前就会完成加载, 从而不影响HTML的视觉展现, 而JS, 则通常可以后加载. 不过JS和CSS的加载都会影响页面的展示, 通常来说, 两者加载和执行的过程中, 页面是不会渲染展示的, 这一过程称之为Blocking. 当然这个过程你是可以中断的,尤其是中断js的加载很多时候不会影响到页面的视觉效果(前提是js不涉及DOM操作), 这也是为什么有时候你的loading菊花转着转着你叉掉了页面还是会加载出来的原因.

Diagram showing CSS and JavaScript blocking.

不过, 图片元素通常是不会被blocking的, 浏览器不会等待一个图片元素加载完成后才进行页面渲染~ 所以经常出现页面加载后, 图片没显示完整的现象.

这种blocking的机制主要是为了防止裸露的HTML带给用户的糟糕体验, 毕竟如果css在html之后加载, 那么无样式的html会先渲染展示, 然后样式加载完在reflow, 感觉就很痛苦了... 这种闪一下的现象通常叫做: Flash of unstyled content(FOUC). 所以现在浏览器通常都采取blocking的方式来保证用户看到的页面的视觉效果. 而blocking对js而言主要是为了应对document.write这个函数, 其实根本来说也是为了一次性让用户看到比较完整, 好看的内容. 当然, 现在其实很多人都不推荐大家使用document.write这个函数, 毕竟js经常会导致更多的blocking时间, 但是毕竟有人再用... 而且浏览器又没办法提前判断js中用没用这个函数...

恩, 基本上, 从一个请求发出到页面加载的过程就是这样了~ 如果想要提高性能, 自然也就从这里面涉及的各个方面着手喽~