你尚未登录,仅允许查看本站部分内容。请登录使用邀请码注册
markate

从FE的角度上再看输入url后都发生了什么 14个回复 专栏 @ HTML

markate 发布于 3 年前

前面看了大神 @nwind 一篇《从输入url到页面加载完成都发生了什么事情》。这篇文章让我在近期追查一个页面请求blocking的问题的过程中深有受益。 顺便写一下从FE的角度上看,从输入url到页面加载完成都发生了什么事情。 通过 chrome://net-internals/#events,我们以随便打开的一个页面作为样例,可以看到浏览器都做了以下事情:

1、拉取浏览器cache,判断是否需要更新,如果不需要更新则从缓存获取内容直接渲染。判断是否更新的主要依据有:Expires时间、cache设置,浏览器的设置。浏览器拉取缓存的这部分工作主要体现在如下event上:

t=698049 [st=  3]      URL_REQUEST_DELEGATE  [dt=0]
t=698049 [st=  3]      HTTP_CACHE_GET_BACKEND  [dt=0]
t=698049 [st=  3]      HTTP_CACHE_OPEN_ENTRY  [dt=0]
t=698049 [st=  3]      HTTP_CACHE_ADD_TO_ENTRY  [dt=0]
t=698049 [st=  3]      HTTP_CACHE_READ_INFO  [dt=1]

2、发送页面header请求

t=698050 [st=  4]     +HTTP_STREAM_REQUEST  [dt=282]
t=698332 [st=286]        HTTP_STREAM_REQUEST_BOUND_TO_JOB
 --> source_dependency = 207138 (HTTP_STREAM_JOB)

这里我们看到发送header请求花费了282毫秒的时间,那么这个期间都发生了什么事情?我们打开events ID为207138的记录详细查看内容:

t=698050 [st=  0] +HTTP_STREAM_JOB  [dt=282]
               --> original_url = "http://stackoverflow.com/"
               --> priority = "HIGHEST"
               --> url = "http://stackoverflow.com/"
t=698050 [st=  0]   +PROXY_SERVICE  [dt=0]
t=698050 [st=  0]      PROXY_SERVICE_RESOLVED_PROXY_LIST
                   --> pac_string = "DIRECT"
t=698050 [st=  0]   -PROXY_SERVICE
t=698050 [st=  0]    HOST_RESOLVER_IMPL  [dt=1]
                 --> source_dependency = 207139 (HOST_RESOLVER_IMPL_REQUEST)
t=698051 [st=  1]    TCP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET
                 --> host_and_port = "stackoverflow.com:80"
t=698051 [st=  1]   +SOCKET_POOL  [dt=280]
t=698331 [st=281]      SOCKET_POOL_BOUND_TO_CONNECT_JOB
                   --> source_dependency = 207142 (CONNECT_JOB)
t=698331 [st=281]      SOCKET_POOL_BOUND_TO_SOCKET
                   --> source_dependency = 207146 (SOCKET)
t=698331 [st=281]   -SOCKET_POOL
t=698332 [st=282]    HTTP_STREAM_JOB_BOUND_TO_REQUEST
                 --> source_dependency = 207135 (URL_REQUEST)
t=698332 [st=282] -HTTP_STREAM_JOB

从上面的内容上看,这个期间主要发生了以下几个事情:
(1)、浏览器向os询问server的ip地址
(2)、OS发送DNS寻址,并且返回ip以及端口
(3)、建立tcp连接(这一步我们可以查看207146的event ID)其有内容如下,可以发现这个期间消耗时间:280毫秒

t=698051 [st=    0] +SOCKET_ALIVE  [dt=20570]
                 --> source_dependency = 207142 (CONNECT_JOB)
t=698051 [st=    0]   +TCP_CONNECT  [dt=280]
                   --> address_list = ["198.252.206.16:80"]
t=698051 [st=    0]      TCP_CONNECT_ATTEMPT  [dt=280]
                     --> address = "198.252.206.16:80"
t=698331 [st=  280]   -TCP_CONNECT
                   --> source_address = "172.22.75.118:18555"

(4)、页面通过tcp连接发送http头请求 (备注:目前有的电脑chrome的http请求是建立在QUIC连接上, 可惜我查了下我的chrome的QUIC不可用:chrome://net-internals/#quic)

QUIC Enabled: false
HTTPS Over QUIC Enabled: false
Origin To Force QUIC On: :0
Packet Pacing Enabled: false
Persist Server Config Information Enabled: false
Consistent Port Selection Enabled: true
QUIC sessions
None

发送header的请求如下:

                     --> byte_count = 746
                     --> hex_encoded_bytes =
47 45 54 20 2F 71 75 65 73 74 69 6F 6E 73 2F 32 34 37 39 38   GET /questions/24798
                       30 31 36 2F 68 74 74 70 2D 72 65 71 75 65 73 74 2D 6E 65 74   016/http-request-net
                       2D 65 72 72 6F 72 2D 31 30 31 2D 65 72 72 2D 63 6F 6E 6E 65   -error-101-err-conne
                       63 74 69 6F 6E 2D 72 65 73 65 74 20 48 54 54 50 2F 31 2E 31   ction-reset HTTP/1.1
                       0D 0A 48 6F 73 74 3A 20 73 74 61 63 6B 6F 76 65 72 66 6C 6F   ..Host: stackoverflo
                       77 2E 63 6F 6D 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 6B   w.com..Connection: k
                       65 65 70 2D 61 6C 69 76 65 0D 0A 41 63 63 65 70 74 3A 20 74   eep-alive..Accept: t
                       65 78 74 2F 68 74 6D 6C 2C 61 70 70 6C 69 63 61 74 69 6F 6E   ext/html,application
                       2F 78 68 74 6D 6C 2B 78 6D 6C 2C 61 70 70 6C 69 63 61 74 69   /xhtml+xml,applicati
                       6F 6E 2F 78 6D 6C 3B 71 3D 30 2E 39 2C 69 6D 61 67 65 2F 77   on/xml;q=0.9,image/w
                       65 62 70 2C 2A 2F 2A 3B 71 3D 30 2E 38 0D 0A 55 73 65 72 2D   ebp,*/*;q=0.8..User-
                       41 67 65 6E 74 3A 20 4D 6F 7A 69 6C 6C 61 2F 35 2E 30 20 28   Agent: Mozilla/5.0 (
                       57 69 6E 64 6F 77 73 20 4E 54 20 36 2E 31 3B 20 57 4F 57 36   Windows NT 6.1; WOW6
                       34 29 20 41 70 70 6C 65 57 65 62 4B 69 74 2F 35 33 37 2E 33   4) AppleWebKit/537.3
                       36 20 28 4B 48 54 4D 4C 2C 20 6C 69 6B 65 20 47 65 63 6B 6F   6 (KHTML, like Gecko
                       29 20 43 68 72 6F 6D 65 2F 33 35 2E 30 2E 31 39 31 36 2E 31   ) Chrome/35.0.1916.1
                       35 33 20 53 61 66 61 72 69 2F 35 33 37 2E 33 36 0D 0A 52 65   53 Safari/537.36..Re
                       66 65 72 65 72 3A 20 68 74 74 70 3A 2F 2F 73 74 61 63 6B 6F   ferer: http://stacko
                       76 65 72 66 6C 6F 77 2E 63 6F 6D 2F 75 73 65 72 73 2F 33 35   verflow.com/users/35
                       35 39 30 33 31 2F 6D 61 72 6B 61 74 65 3F 74 61 62 3D 73 75   59031/markate?tab=su
                       6D 6D 61 72 79 0D 0A 41 63 63 65 70 74 2D 45 6E 63 6F 64 69   mmary..Accept-Encodi
                       6E 67 3A 20 67 7A 69 70 2C 64 65 66 6C 61 74 65 2C 73 64 63   ng: gzip,deflate,sdc
                       68 0D 0A 41 63 63 65 70 74 2D 4C 61 6E 67 75 61 67 65 3A 20   h..Accept-Language: 
                       7A 68 2D 43 4E 2C 7A 68 3B 71 3D 30 2E 38 0D 0A 43 6F 6F 6B   zh-CN,zh;q=0.8..Cook
                       69 65 3A 20 5F 5F 71 63 61 3D 50 30 2D 38 34 35 37 30 39 34   ie: __qca=P0-8457094
                       36 30 2D 31 33 38 37 33 36 39 30 39 35 37 32 35 3B 20 5F 5F   60-1387369095725; __
                       75 74 6D 61 3D 31 34 30 30 32 39 35 35 33 2E 35 37 33 34 35   utma=140029553.57345
                       30 34 34 37 2E 31 33 38 37 33 36 39 30 39 36 2E 31 33 38 39   0447.1387369096.1389
                       31 36 31 35 32 35 2E 31 33 38 39 33 34 37 35 33 33 2E 31 31   161525.1389347533.11
                       3B 20 73 67 74 3D 69 64 3D 63 33 39 39 62 65 63 36 2D 63 38   ; sgt=id=c399bec6-c8
                       62 63 2D 34 61 36 31 2D 61 35 39 37 2D 31 36 30 64 38 62 63   bc-4a61-a597-160d8bc
                       35 66 62 32 36 3B 20 75 73 72 3D 74 3D 32 45 59 58 47 78 72   5fb26; usr=t=2EYXGxr
                       55 43 73 67 37 26 73 3D 79 5A 33 30 6B 57 71 42 70 45 53 66   UCsg7&s=yZ30kWqBpESf
                       3B 20 5F 67 61 3D 47 41 31 2E 32 2E 35 37 33 34 35 30 34 34   ; _ga=GA1.2.57345044
                       37 2E 31 33 38 37 33 36 39 30 39 36 0D 0A 49 66 2D 4D 6F 64   7.1387369096..If-Mod
                       69 66 69 65 64 2D 53 69 6E 63 65 3A 20 54 68 75 2C 20 31 37   ified-Since: Thu, 17
                       20 4A 75 6C 20 32 30 31 34 20 30 38 3A 32 35 3A 33 34 20 47    Jul 2014 08:25:34 G
                       4D 54 0D 0A 0D 0A                                             MT....

(5)在522毫秒以后接收完成了服务器返回的header

t=698332 [st=286]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=522]
t=698854 [st=808]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS

(6)、接收完header后,浏览器得到了返回的请求类型(200、304......)、服务器资源是否有更新(如果没有更新直接从cache获取缓存渲染)等信息

3、在138毫秒后浏览器分段(如果页面小不一定分段)接收完了页面内容,如果页面需要进行缓存则将页面缓存起来,同时对页面进行解码(包括gzip解压等)。

HTTP_TRANSACTION_READ_BODY  [dt=24]
.........此处省略多个HTTP_TRANSACTION_READ_BODY和 HTTP_CACHE_WRITE_DATA.......
t=698854 [st=946]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=698854 [st=946]      HTTP_CACHE_WRITE_DATA  [dt=0]
t=698855 [st=946]      HTTP_CACHE_WRITE_INFO  [dt=0]
t=698855 [st=946]      URL_REQUEST_DELEGATE  [dt=0]

4、根据返回的数据类型(html类型、图片类型、声音…)进行页面渲染

通过对单个请求的分析,可以从另一个方面知道页面的性能瓶颈在哪里

如:对div.io的网站的单页请求响应如下:

11978: URL_REQUEST
http://div.io/topic/457
Start Time: 2014-07-17 22:17:15.106

t=  29 [st=   0] +REQUEST_ALIVE  [dt=3836]
t=  29 [st=   0]    URL_REQUEST_DELEGATE  [dt=0]
t=  29 [st=   0]    URL_REQUEST_START_JOB  [dt=7]
                --> load_flags = 144834817 (ENABLE_LOAD_TIMING | MAIN_FRAME |      MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                --> method = "GET"
                --> priority = "HIGHEST"
                --> url = "http://div.io/topic/457"
t=  36 [st=   7]   +URL_REQUEST_START_JOB  [dt=395]
                --> load_flags = 144834817 (ENABLE_LOAD_TIMING | MAIN_FRAME | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                --> method = "GET"
                --> priority = "HIGHEST"
                --> url = "http://div.io/topic/457"
t=  37 [st=   8]      URL_REQUEST_DELEGATE  [dt=1]
t=  38 [st=   9]      HTTP_CACHE_GET_BACKEND  [dt=0]
t=  38 [st=   9]      HTTP_CACHE_DOOM_ENTRY  [dt=1]
t=  39 [st=  10]      HTTP_CACHE_CREATE_ENTRY  [dt=0]
t=  39 [st=  10]      HTTP_CACHE_ADD_TO_ENTRY  [dt=0]
t=  39 [st=  10]      URL_REQUEST_DELEGATE  [dt=0]
t=  39 [st=  10]     +HTTP_STREAM_REQUEST  [dt=3]
t=  42 [st=  13]        HTTP_STREAM_REQUEST_BOUND_TO_JOB
                    --> source_dependency = 11988 (HTTP_STREAM_JOB)
t=  42 [st=  13]     -HTTP_STREAM_REQUEST
t=  42 [st=  13]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=1]
t=  42 [st=  13]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS
                    --> GET /topic/457 HTTP/1.1
                        Host: div.io
                        Connection: keep-alive
                        Cache-Control: no-cache
                        Pragma: no-cache
                        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
                        User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)
                        Referer: http://div.io/user/24
                        Accept-Encoding: gzip,deflate,sdch
                        Accept-Language: zh-CN,zh;q=0.8
                        Cookie: [636 bytes were stripped]
t=  43 [st=  14]     -HTTP_TRANSACTION_SEND_REQUEST
t=  43 [st=  14]     +HTTP_TRANSACTION_READ_HEADERS  [dt=387]
t=  43 [st=  14]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=387]
t= 430 [st= 401]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                    --> HTTP/1.1 200 OK
                        Server: nginx/1.6.0
                        Content-Type: text/html; charset=UTF-8
                        Transfer-Encoding: chunked
                        Connection: keep-alive
                        X-Powered-By: PHP/5.5.14-2+deb.sury.org~precise+1
                        Cache-Control: no-cache
                        Date: Thu, 17 Jul 2014 14:17:14 GMT
                        X-Frame-Options: SAMEORIGIN
                        Set-Cookie: [393 bytes were stripped]
t= 430 [st= 401]     -HTTP_TRANSACTION_READ_HEADERS
t= 430 [st= 401]      HTTP_CACHE_WRITE_INFO  [dt=0]
t= 430 [st= 401]      HTTP_CACHE_WRITE_DATA  [dt=0]
t= 430 [st= 401]      HTTP_CACHE_WRITE_INFO  [dt=0]
t= 430 [st= 401]      URL_REQUEST_DELEGATE  [dt=0]
t= 431 [st= 402]   -URL_REQUEST_START_JOB
t= 431 [st= 402]    URL_REQUEST_DELEGATE  [dt=0]
t= 431 [st= 402]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t= 431 [st= 402]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 431 [st= 402]    HTTP_TRANSACTION_READ_BODY  [dt=6]
t= 437 [st= 408]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 437 [st= 408]    HTTP_TRANSACTION_READ_BODY  [dt=10]
t= 447 [st= 418]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 447 [st= 418]    HTTP_TRANSACTION_READ_BODY  [dt=9]
t= 456 [st= 427]    HTTP_CACHE_WRITE_DATA  [dt=1]
t= 457 [st= 428]    HTTP_TRANSACTION_READ_BODY  [dt=13]
t= 470 [st= 441]    HTTP_CACHE_WRITE_DATA  [dt=3]
t= 473 [st= 444]    HTTP_TRANSACTION_READ_BODY  [dt=29]
t= 502 [st= 473]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 502 [st= 473]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t= 510 [st= 481]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 510 [st= 481]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t= 518 [st= 489]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 518 [st= 489]    HTTP_TRANSACTION_READ_BODY  [dt=9]
t= 527 [st= 498]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 527 [st= 498]    HTTP_TRANSACTION_READ_BODY  [dt=72] 
t= 599 [st= 570]    HTTP_CACHE_WRITE_DATA  [dt=1]
t= 600 [st= 571]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t= 608 [st= 579]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 608 [st= 579]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t= 616 [st= 587]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 616 [st= 587]    HTTP_TRANSACTION_READ_BODY  [dt=12]
t= 628 [st= 599]    HTTP_CACHE_WRITE_DATA  [dt=1]
t= 629 [st= 600]    HTTP_TRANSACTION_READ_BODY  [dt=3]
t= 632 [st= 603]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 632 [st= 603]    HTTP_TRANSACTION_READ_BODY  [dt=9]
t= 641 [st= 612]    HTTP_CACHE_WRITE_DATA  [dt=0]
t= 641 [st= 612]    HTTP_TRANSACTION_READ_BODY  [dt=366]
t=1007 [st= 978]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1007 [st= 978]    HTTP_TRANSACTION_READ_BODY  [dt=1]
t=1008 [st= 979]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1008 [st= 979]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=1008 [st= 979]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1009 [st= 980]    HTTP_TRANSACTION_READ_BODY  [dt=124]
t=1133 [st=1104]    HTTP_CACHE_WRITE_DATA  [dt=2]
t=1135 [st=1106]    HTTP_TRANSACTION_READ_BODY  [dt=41]
t=1176 [st=1147]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1176 [st=1147]    HTTP_TRANSACTION_READ_BODY  [dt=10]
t=1186 [st=1157]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1186 [st=1157]    HTTP_TRANSACTION_READ_BODY  [dt=6]
t=1192 [st=1163]    HTTP_CACHE_WRITE_DATA  [dt=1]
t=1193 [st=1164]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t=1201 [st=1172]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1201 [st=1172]    HTTP_TRANSACTION_READ_BODY  [dt=8]
t=1209 [st=1180]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1209 [st=1180]    HTTP_TRANSACTION_READ_BODY  [dt=9]
t=1218 [st=1189]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1218 [st=1189]    HTTP_TRANSACTION_READ_BODY  [dt=389]
t=1607 [st=1578]    HTTP_CACHE_WRITE_DATA  [dt=1]
t=1608 [st=1579]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=1608 [st=1579]    HTTP_CACHE_WRITE_DATA  [dt=1]
t=1609 [st=1580]    HTTP_TRANSACTION_READ_BODY  [dt=0]
t=1609 [st=1580]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=1609 [st=1580]    HTTP_TRANSACTION_READ_BODY  [dt=546]
t=2155 [st=2126]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=2155 [st=2126]    HTTP_TRANSACTION_READ_BODY  [dt=10]
t=2165 [st=2136]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=2165 [st=2136]    HTTP_TRANSACTION_READ_BODY  [dt=1698]
t=3863 [st=3834]    HTTP_CACHE_WRITE_DATA  [dt=1]
t=3864 [st=3835]    HTTP_TRANSACTION_READ_BODY  [dt=1]
t=3865 [st=3836]    HTTP_CACHE_WRITE_DATA  [dt=0]
t=3865 [st=3836] -REQUEST_ALIVE

div.io页面(不计算外链),最耗时间的:

接收body部分 花了 3433 毫秒,这与应用层响应时间、网速、服务器出口带宽有关

Tcp连接建立花了387毫秒(这与dns解析,网速有关)

备注:本篇文章仅写了单请求在chrome上的解析流程。

登录后回复,如无账号,请使用邀请码注册