Rplus / rplus.github.io

my blog~
http://rplus.github.io/
29 stars 4 forks source link

[POST] 生活化 response time #34

Open Rplus opened 8 years ago

Rplus commented 8 years ago

這篇要聊的主題是網路檔案傳輸的耗時, 以及如何用較生活化的方式來理解/記憶

通常, 網頁中傳輸檔案(assets) 若能讓使用者愈快拿到是愈好 就像肚子餓訂披薩當然會希望愈早吃到愈好


=== 所以,接下來會用外送披薩來作比喻 ===


使用者希望的是「等著吃披薩的時間要短」 那就得先來看看有哪些變因會影響「時間」

我們知道物理學中計算速率的方式就是距離除以耗時:

V(elocity) = D(istance) / T(ime)

那換言之, 耗時就等於距離除以速率:T = D / V

我們期望的是時間盡可能地小 那在這公式裡可以很簡單地看到兩種改進方向:

當然,身為披薩店總不能叫顧客搬家搬到近一點的地方 運送距離縮短,其中很常見的方式就是「開分店」 在網路上可以將 「CDN」 當作分店的管理方式 分店能有效縮短顧客的距離,所以也能夠明顯地縮短運送的時間

2. V 變大,速度加快 <- 減重

運將要加快有很多方法, 不過像是大力加油門、逆向行駛這種違規手段就先不提 一台馬力固定的披薩車要提高速度較簡單的方式就是「減輕負重

就像動畫《進擊的巨人》第 57 次牆外調查撤回牆內的過程中, 也是拋棄了所有同仁遺體才得以擺脫巨人的追殺

如果顧客只需要五張披薩,那麼又何苦一次載十張來拖慢運送速度呢?

額外的、非必要的、多餘的,都是可以省去的 這就像實作中的「minify」以及「gzip」的操作 自動化的 minify 可以輕鬆去除常見多餘的累贅 而 server 端開啟的 gzip 動態壓縮則能將資料壓得更紮實

減輕負重後,看來我們的披薩車就能更快抵達顧客地點了~


經過前面兩個的調整,我們的速率的物理公式 T = D / V 看來好像沒有能調整的地方了,是嗎?

我們的 T 的確就只能以 DV 進行調整 但,那是「單趟」的情況

3. ΣT 減少 <- 合併

顧客通常是貪婪的

「一張吃不夠,有沒有吃第二張?」 「披薩吃不夠,有沒有要吃炸雞?」

如果一次只送單份,那披薩車往返的耗時勢必會嚴重影響顧客進食時間 所以可以事先先問完要訂哪些東西,讓披薩車一次載過去

這個「整合」可以類比為同類檔案的「concatenate (concat)」 檔案的合併像是 CSS merge、JS bundle,或是 image sprite 等等 可減少眾多的請求次數,進而縮減總耗時

不過這類型的處理,在已強化了併發請求的 HTTP/2 會有不同的考量方式~


好了,看來我們一次就把顧客要的披薩跟炸雞塊都送到了呢~ 他們應該吃得很開心了才是,應該沒我們的事了吧?

不,只用貪婪來形容顧客肯定是不夠的 他們往往還是饑渴的 顧客不光只會吃、還會拉 (咳) 還會喝 不只單點披薩,也會點炸雞塊,當然也不會漏了很重的飲料

該怎麼處理「大量」的飲料需求呢?

4. 動態分批處理

以同價格來說,飲料是很重的 所以運送成本也相對較高

如果僅為了滿足訂單,就將原本運送用的小機車改成小貨車以裝入所有的飲料, 那麼前面第二點提到的減重策略的效益就不復存在了 所以改成顧客真的有需要喝飲料才附加或另外運送,會比較節省「吃披薩的等待時間」

就好比一個未知參與人數的活動 若調整為: 「只有在飲料只剩二十杯以下時,披薩店才會再送一趟飲料過來」 這樣最後頂多會多出一趟飲料的份量

這在網頁加載處理中,「Lazy loading」就是一個很常見的手法 通過預載幾張圖,而動態調整要載入的圖源, 用以加速第一次看到畫面的時間

當然,這種處理方式在應對短時間的大量需求,就會出現較混亂的狀況 使得等待時間變得較為不穩定


同樣的大量披薩需求 「一台機車載不完,你有沒有派第二台機車幫忙送?」 「一家分店做不來,你有沒有請第二家分店幫忙做?」

5. 分批訂披薩

負荷量是有限的,不管是披薩店、運送車或是顧客都是 披薩店是沒法同時做太多、 機車一次能裝的量也有上限 就連顧客也無法應付同時過多的披薩(清點、付款)

相同的,網路的 server 端或是 client 端也會有類似的限制 server 端太忙會卡住, 連 client 端的瀏覽器有同網域下載數上限 這時「domain sharding」就算是一個可以解決 client 端上限的技巧 透過將檔案請求分佈在不同 domain 的 CDN 來繞過這些限制

不過這項實踐技巧與 concat 一樣,會在 HTTP/2 狀況下需要另外的考量

另一方面,domain sharding 造成額外的 DNS lookup 耗時也是需要納入評估的部份

就好比原本打一通電話就能訂好披薩, 要改成打三四通電話,多少都會耽擱些時間的


這樣一輪規劃後,看來不論是大量或小量的狀況, 基本上,披薩店都能好好應對了呢!

最後再提一個不同軸向的考量方式:時間的「方向」 前面提的都是訂單成立,披薩店能進行調配的應對措施 接下來,向瞧瞧

6. 預約、預期購買

事前顧客就知道有吃披薩的需求而提前預訂 或是在可信度良好的基準上,預估到「有吃披薩的需求」,先送到顧客家 這麼一來,訂購電話一掛上,就能立刻按門鈴了

這種預處理的措施在現代瀏覽器也有各種處理方式來提前處理,以縮短等待或是傳輸的耗時 細節可以參考 CSS-Tricks 的分享文章:Prefetching, preloading, prebrowsing

7. 先看看冰箱 <- 時效性

這邊所列的最後一個縮短「吃披薩需要等待的時間」的技巧 就是先看看冰箱裡還有沒有剩「未過期的披薩」 如果有,那其實完全不需要出動披薩店了~ 直接從冰箱裡拿出來加熱就能享用了~

這冰箱裡的披薩你可以把它視為 client 端的 cache 當然 cache 有分很多種,304, Storage, appcache, indexedDB… 基本上就當作不同的保鮮方法囉~


Summary:

那講到這邊應該算是我目前理解的部份 不曉得看到這兒的你,是不是想吃披薩了 是不是有什麼疑問呢

若有疑問、建議或是補充、糾正 都歡迎告知~ 甘溫~

Rplus commented 8 years ago

啊啊~ 對了,我好像該開始找工作上班了 Orz

Clementtang commented 8 years ago

這篇棒棒!

kmsheng commented 8 years ago

文筆不錯喔 R+ : )

Rplus commented 8 years ago

樓上準備訂披薩了嗎? XDD

gonsakon commented 8 years ago

R+ 賽高!