How gmail loading SS bar works

Source: Internet
Author: User

When you log on to Gmail, a progress bar is displayed, showing the loading progress.

I thought it was a simulated result first, but I observed it carefully and found that the progress bar actually reflected the loading and downloading progress, without relying on the network conditions.

So I am very curious, because there is no ApI in javascript to check the download progress of documents (this is also forbidden by js security mechanisms), and only loading starts and loading is available, loading completed (or loading error) status. So how does gmail implement real-time monitoring of the load percentage?

You can use firebug to monitor the download of files when logging on to gmail. You can find a get request that returns html text. The file size is more than 300 kb, and find a function like this:

Function _ B _prog (pct) {top ["pr"] = pct; if (_ B _thumbStyle _ = undefined) {var thumb = top.doc ument. getElementById ("lpt"); _ B _thumbStyle _ = thumb? Thumb. style: null} if (_ B _thumbStyle _) {_ B _thumbStyle _. width = Math. round (pct * 0.99) + "%"; if (pct = 100) _ B _thumbStyle _ = null} this function is defined after the html body. The definition shows that the progress bar is dynamically implemented by this function.

Next, let's look at the <script> label of a large segment. The label contains compressed js. You can find the _ B _prog (pct) statement at the end of each <script> definition, and the parameter is from 1

Until 100, as shown below:

<Script> var JS_START_TIME = (new Date). getTime (), GLOBALS = top. GLOBALS; if ("o_6IqNZ5hNQ.zh_CN ."! = GLOBALS [4]) top. location. replace (top. location. href. split ("#") [0]); function _ B _log (imp, opt_val) {var p = "imp =" + imp; if (arguments. length> 1) p + = "& val =" + opt_val; _ B _logImg _ ("jsystemic", p)} var loadTimes = [GLOBALS [0], GLOBALS [1], JS_START_TIME]; function _ B _record () {loadTimes. push (new Date ). getTime ()} var _ B _thumbStyle _; function _ B _prog (pct) {top ["pr"] = pct; if (_ B _thumbStyle _ = undefined) {var thumbdesktop.doc ument. getEleme NtById ("lpt"); _ B _thumbStyle _ = thumb? Thumb. style: null} if (_ B _thumbStyle _) {_ B _thumbStyle _. width = Math. round (pct * 0.99) + "%"; if (pct = 100) _ B _thumbStyle _ = null} function _ B _err (e) {var state = loadTimes. join ("-"); _ B _logImg _ ("jserr", "jsstate =" + encodeURIComponent (state) + "& jsmsg =" + encodeURIComponent (e )); _ B _handleError (e)} function _ B _handleError (e) {throw e;} function _ B _logImg _ (v, p) {(new Image ). src = "? Ui = 2 & view = "+ v +" & "+ p +" & ik = "+ GLOBALS [9] +" & random = "+ (new Date ). getTime ()} window. onerror = function (message, url, line) {_ B _err (message)}; _ B _prog (1); </script> <script> .... function Ala (B) {var a = []; if (B) for (; B. isValidRow ();). push (B. field (0), B. next (); return a} function Bla (B) {return B & B. isValidRow ()? B. field (0): l} function linoleic (B) {if (B & B. isValidRow () {for (var a ={}, c = B. fieldCount (), d = 0; d <c; d ++) a [B. fieldName (d)] = B. field (d); return a} else return l} function Dla (B) {var a = []; if (B & B. isValidRow () for (var c = B. fieldCount (), d = 0; d <c; d ++) a [d] = B. field (d); return a} function Ela (B, a, c, d) {if (c. length = 0 | d> = c. length) return B .exe cute (a); else {if (ka (c [d]) return B .exe cute (a, c [d]); c = Array. prototype. slice. call (c, d); re Turn B .exe cute (a, c)} function Fla (B, a, c, d, e) {B = Ela (B, a, d, e ); try {return c (B)} finally {B & B. close ()} function Gla (B, a) {var c, d; c =? "ROLLBACK": "COMMIT"; d =? "Beforerollback": "beforecommit"; var e = B. dispatchEvent (new yla(d1_1_if(e1_ B .ia.exe cute (c), B. ka = 0, d =? "Rollback": "commit", B. dispatchEvent (new yla (d); return e} function ll (B) {a: {var a = B. nb; if (B. ma) if (B. ka = 0) {B. ba =! 1; B. dispatchEvent (new yla ("beforebegin" cannot BEGIN B .ia.exe cute ("BEGIN" + a); B. eb = Hla [a]; B. ka = 1; try {B. dispatchEvent (new yla ("begin" ))}catch(c){ B .ia.exe cute ("ROLLBACK"), B. ka = 0, h (c)} B =! 0; break a} else B. Ba? H (Error ("= 106"): Hla [a]> B. eb? H (Error ("= 107"): B. ka ++; B =! 1} return B} function ml (B) {if (B. ma) if (B. ka <= 0 & h (Error ("= 108"), B. ka = 1) {var a = Gla (B, B. ba); return! B. Ba & a} else B. ka --; return! 1} function Ila () {} function Jla (B, a) {this. aa = B; this. ea = a} function Kla (B) {ri (this); this. ta = B} var Lla = GLOBALS [0], Mla = GLOBALS [2], ol = GLOBALS [3], hf = GLOBALS [4], Nla = GLOBALS [5], pl = GLOBALS [6], ql = GLOBALS [7], Ola = GLOBALS [8], rl = GLOBALS [9], sl = GLOBALS [10], pla = GLOBALS [11], Qla = GLOBALS [12], Rla = GLOBALS [14], tl = GLOBALS [15], ul = GLOBALS [16], sla = GLOBALS [17], Tla = GLOBALS [18], vl = GLOBALS [19], Ula = GLOBALS [20], mja = GLOBALS [21], Vla = GLOBALS [22], Wla = GLOBALS [24], Xla = GLOBALS [25], Yla = GLOBALS [26], Zla = GLOBALS [27], ama = GLOBALS [28], bma = GLOBALS [29], cma = GLOBALS [30]; _ B _prog (13)} catch (e) {_ B _err (e)} </script>...

Until

<Script>... hL. prototype. eR = function $ cvb (a, c) {var d = this. ha, e = []; e [0] = w (). toString (16); e [2] = "0"; e [18] = [a]; e [24] = c; e = new Dr ("^ act ", e); this. insertNode (mBa (d, e)}; V (TLb, Er); TLb. prototype. aa = function $ dvb (a, c) {var d = this. kn. ua. ic (); if (Zr (d) & a = "iu") {vr (this. kn. qj (); d = this. kn. ua; random (d); gra (d); d = this. kn; wr (d. fe); d. ua. SC. ea (); try {for (var e = 1, f; f = c [e]; e ++) {var g = new Dr ("^ act ", f), I = mBa (d. ua, g); d. fe. jb (ne W LC (g. yr () [0]). dw (); var k = d. fe, m = I. get (). yr () [0] [17]; if (m) for (var q = 0, u = j; u = m [q]; q ++) k. cO (u [8]) & (fb (m, q), q --); d. fe. insertNode (I)} d. fe. ba (); d. aa =! 0} finally {if (d. Ua. SC. aa (), f = d. Fe, f. Se = d) f. Se = l} return! 0} return! 1}; TLb. prototype. ea = function $ evb (a) {var c = this. kn. ua. ic (); Zr (c) & a = 0 & this. kn. qj (). dispatchEvent ("Oe")}; V (ULb, PAa); ULb. prototype. aa = function $ fvb () {return Zr (this. yi. ic ())? New hL (this. yi): l}; V (VLb, HCa); VLb. prototype. ea = function $ gvb (a, c) {var d =. getItem (); c. yO = d. sh ("^ act")}; VLb. prototype. aa = function $ hvb (a) {if (. yO) {var c = new S;. yO? Uj ({Kc: "GV", title: "Buzz"}, c): c. append ("& nbsp;"); return c. toString () }}; O (N. ja (), "t"); R (N. ja (), "t"); _ B _prog (100)} catch (e) {_ B _err (e)} </script> the result is obvious, the progress bar shows the progress by calling the progress function every time a js is loaded.

However, when loading html, it is usually not followed by a download and loading, but it will be loaded and executed after the entire file is downloaded, in this way, the download progress is not monitored in real time.

The key is that gmail does not use static resources for client download, but returns html through servlet-like technology.

A server push technique is used here to call PrintWriter at the end of each </script> tag. flush (). After this method, the server output stream will be pushed to the customer service immediately, but the output stream is not closed. You can call flush () again next time (), in this way, resources can be pushed to the client one by one to achieve progress monitoring, instead of simulating the process from 0% as in the current webQQ, then waiting, and then suddenly increasing to 100%.


 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.