- 蘇格團隊
- 做者:Jason
因爲業務的須要,筆者最近須要實現一個大量圖片同時加載的需求。在實現這個需求的過程當中,筆者遇到了不少的坑,也總結了一些優化方案。這裏將筆者使用或準備使用的優化方案總結一下。前端
在描述如何解決問題,咱們如今先來申明,問題是什麼? 筆者的需求大概是在某個頁面顯示 1~1000張,200~500k大小的圖。好消息是這些圖片來源於本地硬盤而非網絡。(不然這個問題就要變成優化網絡....)promise
因爲不是純前端的項目,筆者能夠從本地文件夾中讀取文件。而後一段代碼劈里啪啦的就出現了。緩存
const fileList = this.props.fileList;
return (
<div className="list-wrapper">
{
fileList.map((file) => {
<img className="img-item" src={file.src}>
})
}
<div>
)
複製代碼
就在筆者滿心歡喜的認爲這個需求基本搞定了,該去樓下加雞腿的時候。無情的現實狠狠的抽了我一巴掌。隨着網頁的刷新,一張純白的畫面展現在了個人面前,而後只見圖片一點一點的從上面加載出來。 我不由陷入了沉思,是CPU跑不動道了仍是內存飄了?在一想,我這電腦都這個表現,真要上線了,這客戶能忍受嗎?不對,就這表現,沒上線前產品小姐姐就的把我ko了...bash
這種場景下想必你們第一反應也是懶加載。 簡單介紹一下圖片懶加載。常見的圖片懶加載方案是指頁面加載時只渲染屏幕可見區域及周圍的圖片。當頁面滾動時再加載須要顯示的圖片。
出於提升效(tou)率(lan)的目的,筆者在網上找了個比較好用的懶加載庫而後引入項目。 然而,狀況並不樂觀。由於該需求場景下每一張圖片的寬高都是 50*50,那麼在PC端常見的 1080p 的設備上首屏須要顯示的圖片達到了400+張。
即使咱們忽視這個問題,當用戶滾動網頁速度很快時圖片加載的體驗也是不ok的。因此懶加載並非萬能的。服務器
首先咱們要知道,在硬件性能不變且CPU調度不能更積極的前提下。理論上咱們沒法減小圖片渲染的時間。因此咱們只能想辦法調整圖片渲染的方式來提升用戶的體驗。 因此咱們採用預加載的方式。網絡
const fileList = this.props.fileList;
fileList.forEach((element) => {
let img = new Image();
img.src = element.src;
img.onload = () => {
// 渲染這張圖
...
}
})
複製代碼
固然咱們也可使用img.decode()方法對圖片進行解碼,它會返回一個promise對象。app
img.decode().then(() => {
// 渲染這張圖
...
})
複製代碼
採用了這套方案後,圖片會一張又一張的加載。然而,加載的速度實在是不敢恭維。若是用戶想看最後那張圖片,那他只能在哪裏進行長久的等待...性能
衆所周知,3 = 1 + 2。 因此方案三就是方案一和方案二的結合體。 首先咱們加載一張圖片未加載時的底圖(佔位)。然後咱們繼續採用方案二的方式進行圖片逐個的預加載。 當用戶滾動圖片時,咱們便改變下一站預渲染的圖片爲用戶可見區域的第一張。 然而,狀況仍是不樂觀。當用戶的滾動條勻速直線不停的往下運動時,效果依然不好。優化
綜合上面幾種方案,基本能優化的咱們都已經優化了。那如繼續何提升用戶的體驗呢?彷佛,咱們只能從圖片自己去下手?
上文也提到,在我所面臨的需求場景下一張圖片的顯示寬高爲50 * 50。 而圖片的大小爲200~500k。因此咱們能夠採用縮率圖的方式,先渲染一張3~5k大小的縮略圖,等用戶點擊圖片查看詳情時再去渲染大圖。 採用縮略圖的狀況下咱們再使用方案三進行優化,性能表現幾乎就能夠知足這個場景下用戶的需求了。ui
固然,上面的幾種優化方案只是我在某個項目中使用。咱們仍然能夠採用例如圖片漸進式加強,CDN緩存,圖片壓縮,設立單獨的資源服務器等諸多方式。圖片的加載優化自己也是一個前端老生常談的問題,業內已經有太多太多的解決方案。若是你有更好的方案,你也能夠在下面留言告訴我。謝謝觀看。