Web性能優化 | 如何提高首屏載入速度?

在 FrontJS 的使用反饋中,頁面和資源的載入速度是很多用戶密切關注的數據,想要提高載入速度,就需要不斷的對網站進行優化。相信大家都有在瀏覽網頁時遇到過頁面載入不完全的問題。作為網站的「建造人」,我們不僅是開發者,同時也是用戶。當我們在網頁上看到各種紅叉和長時處於 loading 狀態的信息時,會瞬間失去瀏覽頁面的興緻,變得不耐煩起來——尤其是首屏,載入的快與慢直接影響著用戶的使用體驗及滯留時間。

相對於移動端的首屏,Web端想讓用戶看到的信息更多更豐富,頁面難免會大而「重」,首屏作為用戶與網站的第一眼互動,「秒開」變得至關重要。今天就來談談如何對首屏時間進行性能優化。

  • 什麼是首屏?

以800×600像素尺寸為標準,當瀏覽器載入頁面後看到第一眼的顯示內容為首屏;從開始載入到瀏覽器頁面顯示高度達到600像素且此區域有內容顯示的時間為首屏顯示時間(當然這個標準隨著技術進步在不斷變化)。以下圖的京東首頁為例,對於電商網站而言,營銷活動的banner、輪播圖、賬戶信息、分類檢索等供用戶自主選擇的主要內容全部集中在首屏,所以對首屏的載入速度要求極高。

  • 大公司是如何進行首屏優化的?

仍然以京東為例:

當我們打開京東的網站(不要滾動滑鼠和鍵盤),右鍵查看源代碼會發現京東首頁的DOM樹出奇的簡單,頁面DOM中多含有mod_lazyload的類。

<div class="J_f J_lazyload J_f_lift mod_lazyload need_ani chn" id="portal_8" data-backup="basic_8" data-source="cms:basic_8" data-tpl="portal_tpl">

再看下 localstorage

尤其在查看鍵名類似於 URL 的鍵值對時,會發現它們的值中多存在一串完整的類似於html的內容。

{"dom":"{%var liftTxtArr = pageConfig.liftTxtArr,clstagPrefix = h|keycount|2016|41a, i;%}<ul class="lift_list">{% for (i = 0; i < liftTxtArr.length; i++) { %}<li class="J_lift_item lift_item{%= (i===0) ? lift_item_first : %}" clstag="{%= clstagPrefix + (i < 9 ? 0 : ) + (1+i) %}"><a href="javascript:;" class="lift_btn"><span class="lift_btn_txt">{%= liftTxtArr[i] %}</span></a></li>{% } %}<li class="J_lift_item J_lift_item_top lift_item lift_item_top" clstag="{%= clstagPrefix + (i < 9 ? 0 : ) + (1+i) %}"><a href="javascript:;" class="lift_btn"><span class="lift_btn_txt">頂部<i class="lift_btn_arrow"><!--&#xe606;--></i></span></a></li></ul>","style":".lift{display:none;position:fixed;z-index:100;-moz-box-shadow:0 0 4px rgba(0,0,0,.2);box-shadow:0 0 4px rgba(0,0,0,.2);background-color:#918888}.lift_item{border-top:1px solid #b1aaaa;-webkit-transition:background-color .1s;-moz-transition:background-color .1s;transition:background-color .1s}.lift_item_first{border-top:none}.lift_btn{*cursor:pointer;overflow:hidden;display:block;width:24px;padding:10px 5px;line-height:14px;text-align:center;color:#fefefe;-webkit-transition:color .1s;-moz-transition:color .1s;transition:color .1s}.lift_item:hover,.lift_item_on{position:relative;border-bottom:1px solid #d70b1c;margin-bottom:-1px;border-color:#d70b1c;background-color:#d70b1c}.lift_item:hover .lift_btn,.lift_item_on .lift_btn{color:#fff}.lift_item_top,.lift_item_top:hover{border-top:1px solid #f6f6f6;background-color:#5e4a4a;border-bottom:0;margin-bottom:0}.lift_item_top .lift_btn{color:#fff}.lift_btn_arrow{display:block;width:0;height:0;margin:auto;border-style:solid;border-width:4px;border-color:#5e4a4a #5e4a4a #fff}.o2_mini .lift{display:none}","version":"062a40dffff4da26"}

由上面的結構可知,京東已經將它們的頁面結構放到了localstorage。由此可見,這只是它頁面其中一個模塊的內容。分析到這裡已經很明顯了,京東通過前端緩存和非同步載入已經完美的實現了首屏快速載入,在Web端達到了秒開的級別。

京東首先只載入框架然後將框架內容與模版綁定,用戶滾動時,一旦該框架內容部分進入了視窗,則請求對應的 data-tpl 地址,拿到渲染這個模塊所需要的腳本和數據,不過這中間還有一層本地緩存 localstorage,如果在本地緩存中匹配到了對應的 hash string 內容,則直接渲染,否則請求到數據之後更新本地緩存。localstorage 中的 version 會在頁面載入時候,與後端文件 hash相對比,hash不變直接取localstorage中的內容(當然也可以使用cookie判斷版本)。

如果數據和初始化腳本包裝在一起,雖然節約了一個請求,但一旦數據變化,整個腳本都得重新載入。將數據和腳本分離,腳本可以長期緩存在本地,單獨請求數據,這個量會小很多。直接改變上面的 version 版本號便可以讓瀏覽器重新請求最新腳本。

從上面可以看出,任何一個模塊的改動,在前端只會引起一個較小的載入變化,加上 http 的緩存策略,伺服器的壓力也是很小的。

看了上面的內容,相信大家已經對京東關於首屏優化的方案有了一個大致的瞭解,下面我們再整理一下關於首屏顯示速度優化細節上的內容:

  • CSS靜態文件在哪裡?

為了追求速度,京東的首頁是沒有 CSS 外鏈的,相信對於我們來說,也是老生常談的前端優化了。

有人可能會問,如果沒有 CSS 外鏈,那一整個頁面的 CSS 是否會增加頁面的體積?其實上面已經提到,將頁面切分為模塊化載入,對應模塊下的 CSS 交給 js 或 jsonp 請求返回。

  • js文件怎麼載入?

如果外部 CSS 資源較小,可以直接將這些內容插入到HTML文檔中,這稱為「內嵌」。通過這種方式內嵌較小 CSS 資源,瀏覽器可以繼續呈現網頁。請注意,如果CSS文件較大,完全內嵌CSS可能會對瀏覽器構建和渲染DOM樹增加不少壓力。如果 CSS 文件較大,您需要識別和內嵌呈現首屏內容所需的 CSS,並暫緩載入其餘樣式,直到首屏內容顯示之後為止。

京東採用請求的方式減少了與伺服器交互的時間。

<script src="//misc.360buyimg.com/??/jdf/lib/jquery-1.6.4.js,/jdf/2.0.0/ui/ui/1.0.0/ui.js,/mtd/pc/index/gb/lib.min.js,/mtd/pc/base/1.0.0/base.js,/mtd/pc/common/js/o2_ua.js,/mtd/pc/index/home/index.min.js,/mtd/pc/index/home/init.min.js"></script>

  • js文件怎麼執行?

懶載入也就是延遲載入,有交互才執行。js文件有需要時才載入,並不是再打開頁面時一次性全部載入完成。

  • 圖片如何處理?

圖片在其他屏(非首屏)都採用懶載入的模式,這樣既能節省流量,也能減少請求數或延遲請求數。

當訪問一個頁面的時候,先把 img 元素或是其他元素的背景圖片路徑替換成一張大小為1*1px圖片的路徑(這樣就只需請求一次,俗稱佔點陣圖),只有當圖片出現在瀏覽器的可視區域內時,才設置圖片正真的路徑,讓圖片顯示出來。用這樣的方式,可以使頁面載入速度變快,從而減輕伺服器的壓力,同時優化用戶體驗。當訪問一個頁面的時候,先把 img 元素或是其他元素的背景圖片路徑替換成一張大小為1*1px圖片的路徑(這樣就只需請求一次,俗稱佔點陣圖),只有當圖片出現在瀏覽器的可視區域內時,才設置圖片正真的路徑,讓圖片顯示出來。用這樣的方式,可以使頁面載入速度變快,從而減輕伺服器的壓力,同時優化用戶體驗。

  • 伺服器需要做什麼?
  1. 少量靜態文件的域名,圖片與iconfont均是放在同一個域下,減少DNS的解析事件,最好做到域名收斂。
  2. 模塊化介面的支持。
  3. 首屏內容最好做到靜態緩存。

版權聲明:

*本文在轉載時有刪改

原作者:一半水一半冰

出處:cnblogs.com/jingh/p/653


推薦閱讀:
相關文章