前段時間優化一個公司歷史老專案的Web效能,卻引出了一系列的問題,讓我反思良多。
我通過Chrome的Lighthouse工具可以看出一些效能引數和問題反饋,我逐一對其進行優化。
根據資源請求的不同,大致可以分為前端資源效能和後端程式效能兩個方面。
先分析一下前端資源吧:
- Defer offscreen images。
Chrome給出的建議是:
Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive. Learn more.
意思是可以考慮延遲載入一些圖片或者隱藏一些圖片在所有關鍵資源完成載入後再考慮載入,通過延遲載入來降低互動時間。
lazy-load的實現方法很多,開源框架推薦:lazysizes。
當然也可以使用npm方式安裝:
npm install lazysizes
使用方式很簡單,先引入lazysize到需要的頁面:
<script src="lazysizes.min.js" async=""></script>
然後給需要被lazyload的img標籤上加新的屬性,如下:
<img
data-sizes="auto"
data-src="image2.jpg"
data-srcset="image1.jpg 300w,
image2.jpg 600w,
image3.jpg 900w" class="lazyload" />
特別要注意,有時候太多background方式載入的圖片也會影響效能,lazysizes也可以處理這樣的圖片。方法如下,使用data-bg屬性即可:
<div class="lazyload" data-bg="/path/to/image.jpg"></div>
- Reduce JavaScript execution time
解決這個問題方法很多,第一個想到的就是壓縮資源。
比如壓縮js和css檔案,可以考慮使用webpack工具或者gulp來壓縮大資原始檔,合併一些檔案資源請求。
還可以通過預載入來提高響應速度,可以在最重要的js資原始檔的引入上加入預載入,程式碼如下:
<link rel="preload" as="style" href="css/style.css">
通過增加preload
最後還可以非同步載入資源,非同步不會阻塞主程式,程式碼調整也很小:
<script src="xxx" async></script>
除此之外JavaScript的執行時間過長還有可能是有大量邏輯運算,有很多頁面把一些邏輯判斷和計算都交給前端去計算,這樣也不利於渲染,建議還是把複雜邏輯和計算儘可能交給後端去處理,讓前端渲染更加“輕量”。
3. Backend response
資料介面返回有時候也很拖累響應時間,因為一些前端結構需要根據返回的資料進行組裝新的頁面結構。
這裡可以考慮找到效能真正的瓶頸,到底是資料庫查詢導致的慢,還是業務邏輯不清晰導致的冗餘,或者其他原因。
我遇到的是因為老專案的資料庫操作類不是單例,會每次產生一個資料庫連線控制程式碼,且該頁面複雜又多的sql查詢。
我勇敢地修改著10多年曆史的程式碼,編寫了單例模式的操作類,然後增加了必要的快取機制。
然而後面我遇到了問題,首先單例類在一些特殊情形下不滿足之前的程式碼需求,導致奇特的資料庫報錯,而async屬性導致一些js檔案無法同步載入到位,而有一些依賴這些資源的php檔案執行報錯。
最終在同事的幫助下,恢復了服務,我也再一次體會到了任何一種效能提升都要謹慎,特別是對一個古老的專案。
前人不敢動的程式碼,可能是深淵。
PS:我的公眾號 成都有娃兒會同步釋出該文章,也可以關注哦!