Open Rplus opened 8 years ago
這篇要聊的主題是網路檔案傳輸的耗時, 以及如何用較生活化的方式來理解/記憶
通常, 網頁中傳輸檔案(assets) 若能讓使用者愈快拿到是愈好 就像肚子餓訂披薩當然會希望愈早吃到愈好
=== 所以,接下來會用外送披薩來作比喻 ===
使用者希望的是「等著吃披薩的時間要短」 那就得先來看看有哪些變因會影響「時間」
我們知道物理學中計算速率的方式就是距離除以耗時:
V(elocity) = D(istance) / T(ime)
那換言之, 耗時就等於距離除以速率:T = D / V
T = D / V
我們期望的是時間盡可能地小 那在這公式裡可以很簡單地看到兩種改進方向:
D
當然,身為披薩店總不能叫顧客搬家搬到近一點的地方 運送距離縮短,其中很常見的方式就是「開分店」 在網路上可以將 「CDN」 當作分店的管理方式 分店能有效縮短顧客的距離,所以也能夠明顯地縮短運送的時間
V
運將要加快有很多方法, 不過像是大力加油門、逆向行駛這種違規手段就先不提 一台馬力固定的披薩車要提高速度較簡單的方式就是「減輕負重」
就像動畫《進擊的巨人》第 57 次牆外調查撤回牆內的過程中, 也是拋棄了所有同仁遺體才得以擺脫巨人的追殺
如果顧客只需要五張披薩,那麼又何苦一次載十張來拖慢運送速度呢?
額外的、非必要的、多餘的,都是可以省去的 這就像實作中的「minify」以及「gzip」的操作 自動化的 minify 可以輕鬆去除常見多餘的累贅 而 server 端開啟的 gzip 動態壓縮則能將資料壓得更紮實
減輕負重後,看來我們的披薩車就能更快抵達顧客地點了~
經過前面兩個的調整,我們的速率的物理公式 T = D / V 看來好像沒有能調整的地方了,是嗎?
我們的 T 的確就只能以 D 與 V 進行調整 但,那是「單趟」的情況
T
ΣT
顧客通常是貪婪的
「一張吃不夠,有沒有吃第二張?」 「披薩吃不夠,有沒有要吃炸雞?」
如果一次只送單份,那披薩車往返的耗時勢必會嚴重影響顧客進食時間 所以可以事先先問完要訂哪些東西,讓披薩車一次載過去
這個「整合」可以類比為同類檔案的「concatenate (concat)」 檔案的合併像是 CSS merge、JS bundle,或是 image sprite 等等 可減少眾多的請求次數,進而縮減總耗時
不過這類型的處理,在已強化了併發請求的 HTTP/2 會有不同的考量方式~
好了,看來我們一次就把顧客要的披薩跟炸雞塊都送到了呢~ 他們應該吃得很開心了才是,應該沒我們的事了吧?
不,只用貪婪來形容顧客肯定是不夠的 他們往往還是饑渴的 顧客不光只會吃、還會拉 (咳) 還會喝 不只單點披薩,也會點炸雞塊,當然也不會漏了很重的飲料
(咳)
該怎麼處理「大量」的飲料需求呢?
以同價格來說,飲料是很重的 所以運送成本也相對較高
如果僅為了滿足訂單,就將原本運送用的小機車改成小貨車以裝入所有的飲料, 那麼前面第二點提到的減重策略的效益就不復存在了 所以改成顧客真的有需要喝飲料才附加或另外運送,會比較節省「吃披薩的等待時間」
就好比一個未知參與人數的活動 若調整為: 「只有在飲料只剩二十杯以下時,披薩店才會再送一趟飲料過來」 這樣最後頂多會多出一趟飲料的份量
這在網頁加載處理中,「Lazy loading」就是一個很常見的手法 通過預載幾張圖,而動態調整要載入的圖源, 用以加速第一次看到畫面的時間
當然,這種處理方式在應對短時間的大量需求,就會出現較混亂的狀況 使得等待時間變得較為不穩定
同樣的大量披薩需求 「一台機車載不完,你有沒有派第二台機車幫忙送?」 「一家分店做不來,你有沒有請第二家分店幫忙做?」
負荷量是有限的,不管是披薩店、運送車或是顧客都是 披薩店是沒法同時做太多、 機車一次能裝的量也有上限 就連顧客也無法應付同時過多的披薩(清點、付款)
相同的,網路的 server 端或是 client 端也會有類似的限制 server 端太忙會卡住, 連 client 端的瀏覽器有同網域下載數上限 這時「domain sharding」就算是一個可以解決 client 端上限的技巧 透過將檔案請求分佈在不同 domain 的 CDN 來繞過這些限制
不過這項實踐技巧與 concat 一樣,會在 HTTP/2 狀況下需要另外的考量 另一方面,domain sharding 造成額外的 DNS lookup 耗時也是需要納入評估的部份 就好比原本打一通電話就能訂好披薩, 要改成打三四通電話,多少都會耽擱些時間的
不過這項實踐技巧與 concat 一樣,會在 HTTP/2 狀況下需要另外的考量
另一方面,domain sharding 造成額外的 DNS lookup 耗時也是需要納入評估的部份
就好比原本打一通電話就能訂好披薩, 要改成打三四通電話,多少都會耽擱些時間的
這樣一輪規劃後,看來不論是大量或小量的狀況, 基本上,披薩店都能好好應對了呢!
最後再提一個不同軸向的考量方式:時間的「方向」 前面提的都是訂單成立後,披薩店能進行調配的應對措施 接下來,向前瞧瞧
事前顧客就知道有吃披薩的需求而提前預訂 或是在可信度良好的基準上,預估到「有吃披薩的需求」,先送到顧客家 這麼一來,訂購電話一掛上,就能立刻按門鈴了
這種預處理的措施在現代瀏覽器也有各種處理方式來提前處理,以縮短等待或是傳輸的耗時 細節可以參考 CSS-Tricks 的分享文章:Prefetching, preloading, prebrowsing
這邊所列的最後一個縮短「吃披薩需要等待的時間」的技巧 就是先看看冰箱裡還有沒有剩「未過期的披薩」 如果有,那其實完全不需要出動披薩店了~ 直接從冰箱裡拿出來加熱就能享用了~
這冰箱裡的披薩你可以把它視為 client 端的 cache 當然 cache 有分很多種,304, Storage, appcache, indexedDB… 基本上就當作不同的保鮮方法囉~
Summary:
pre-
那講到這邊應該算是我目前理解的部份 不曉得看到這兒的你,是不是想吃披薩了 是不是有什麼疑問呢
若有疑問、建議或是補充、糾正 都歡迎告知~ 甘溫~
啊啊~ 對了,我好像該開始找工作上班了 Orz
這篇棒棒!
文筆不錯喔 R+ : )
樓上準備訂披薩了嗎? XDD
R+ 賽高!
這篇要聊的主題是網路檔案傳輸的耗時, 以及如何用較生活化的方式來理解/記憶
通常, 網頁中傳輸檔案(assets) 若能讓使用者愈快拿到是愈好 就像肚子餓訂披薩當然會希望愈早吃到愈好
=== 所以,接下來會用外送披薩來作比喻 ===
使用者希望的是「等著吃披薩的時間要短」 那就得先來看看有哪些變因會影響「時間」
我們知道物理學中計算速率的方式就是距離除以耗時:
那換言之, 耗時就等於距離除以速率:
T = D / V
我們期望的是時間盡可能地小 那在這公式裡可以很簡單地看到兩種改進方向:
1.
D
變小,距離縮短 <- 分店當然,身為披薩店總不能叫顧客搬家搬到近一點的地方 運送距離縮短,其中很常見的方式就是「開分店」 在網路上可以將 「CDN」 當作分店的管理方式 分店能有效縮短顧客的距離,所以也能夠明顯地縮短運送的時間
2.
V
變大,速度加快 <- 減重運將要加快有很多方法, 不過像是大力加油門、逆向行駛這種違規手段就先不提 一台馬力固定的披薩車要提高速度較簡單的方式就是「減輕負重」
如果顧客只需要五張披薩,那麼又何苦一次載十張來拖慢運送速度呢?
額外的、非必要的、多餘的,都是可以省去的 這就像實作中的「minify」以及「gzip」的操作 自動化的 minify 可以輕鬆去除常見多餘的累贅 而 server 端開啟的 gzip 動態壓縮則能將資料壓得更紮實
減輕負重後,看來我們的披薩車就能更快抵達顧客地點了~
經過前面兩個的調整,我們的速率的物理公式
T = D / V
看來好像沒有能調整的地方了,是嗎?我們的
T
的確就只能以D
與V
進行調整 但,那是「單趟」的情況3.
ΣT
減少 <- 合併顧客通常是貪婪的
「一張吃不夠,有沒有吃第二張?」 「披薩吃不夠,有沒有要吃炸雞?」
如果一次只送單份,那披薩車往返的耗時勢必會嚴重影響顧客進食時間 所以可以事先先問完要訂哪些東西,讓披薩車一次載過去
這個「整合」可以類比為同類檔案的「concatenate (concat)」 檔案的合併像是 CSS merge、JS bundle,或是 image sprite 等等 可減少眾多的請求次數,進而縮減總耗時
好了,看來我們一次就把顧客要的披薩跟炸雞塊都送到了呢~ 他們應該吃得很開心了才是,應該沒我們的事了吧?
不,只用貪婪來形容顧客肯定是不夠的 他們往往還是饑渴的 顧客不光只會吃、
還會拉(咳)
還會喝 不只單點披薩,也會點炸雞塊,當然也不會漏了很重的飲料該怎麼處理「大量」的飲料需求呢?
4. 動態分批處理
以同價格來說,飲料是很重的 所以運送成本也相對較高
如果僅為了滿足訂單,就將原本運送用的小機車改成小貨車以裝入所有的飲料, 那麼前面第二點提到的減重策略的效益就不復存在了 所以改成顧客真的有需要喝飲料才附加或另外運送,會比較節省「吃披薩的等待時間」
就好比一個未知參與人數的活動 若調整為: 「只有在飲料只剩二十杯以下時,披薩店才會再送一趟飲料過來」 這樣最後頂多會多出一趟飲料的份量
這在網頁加載處理中,「Lazy loading」就是一個很常見的手法 通過預載幾張圖,而動態調整要載入的圖源, 用以加速第一次看到畫面的時間
同樣的大量披薩需求 「一台機車載不完,你有沒有派第二台機車幫忙送?」 「一家分店做不來,你有沒有請第二家分店幫忙做?」
5. 分批訂披薩
負荷量是有限的,不管是披薩店、運送車或是顧客都是 披薩店是沒法同時做太多、 機車一次能裝的量也有上限 就連顧客也無法應付同時過多的披薩(清點、付款)
相同的,網路的 server 端或是 client 端也會有類似的限制 server 端太忙會卡住, 連 client 端的瀏覽器有同網域下載數上限 這時「domain sharding」就算是一個可以解決 client 端上限的技巧 透過將檔案請求分佈在不同 domain 的 CDN 來繞過這些限制
這樣一輪規劃後,看來不論是大量或小量的狀況, 基本上,披薩店都能好好應對了呢!
最後再提一個不同軸向的考量方式:時間的「方向」 前面提的都是訂單成立後,披薩店能進行調配的應對措施 接下來,向前瞧瞧
6. 預約、預期購買
事前顧客就知道有吃披薩的需求而提前預訂 或是在可信度良好的基準上,預估到「有吃披薩的需求」,先送到顧客家 這麼一來,訂購電話一掛上,就能立刻按門鈴了
這種預處理的措施在現代瀏覽器也有各種處理方式來提前處理,以縮短等待或是傳輸的耗時 細節可以參考 CSS-Tricks 的分享文章:Prefetching, preloading, prebrowsing
7. 先看看冰箱 <- 時效性
這邊所列的最後一個縮短「吃披薩需要等待的時間」的技巧 就是先看看冰箱裡還有沒有剩「未過期的披薩」 如果有,那其實完全不需要出動披薩店了~ 直接從冰箱裡拿出來加熱就能享用了~
這冰箱裡的披薩你可以把它視為 client 端的 cache 當然 cache 有分很多種,304, Storage, appcache, indexedDB… 基本上就當作不同的保鮮方法囉~
Summary:
pre-
tech那講到這邊應該算是我目前理解的部份 不曉得看到這兒的你,
是不是想吃披薩了是不是有什麼疑問呢若有疑問、建議或是補充、糾正 都歡迎告知~ 甘溫~