本文做者:ziven 鄭成忠前端
原創聲明:本文爲閱文前端團隊 YFE 成員出品,請尊重原創,轉載請聯繫公衆號 ( id: yuewen_YFE ) 獲取受權,並註明做者、出處和連接。程序員
前端重構程序員是一個關注代碼同時還要留意體驗的異類。代碼的優化雖然難,可是有比較多的性能測試工具去證實優化的成果。然而體驗這種東西,咱們又要如何去證實它的好與壞呢?web
1、視覺體驗優化chrome
2、數據證實體驗效果瀏覽器
今天我着重會基於「webnovel」PC站點從以上兩點給你們介紹,如何從體驗的角度去作重構的優化,並如何用數據去證實你的優化是有效果的。緩存
咱們要作體驗的優化,首先要咱們要知道什麼纔是好的體驗。服務器
不知道哪裏聽過這麼一句話,「 好的體驗,就是感受不到在體驗 」。這句話聽起來很矛盾,可是卻和業界公認的體驗小紅書「 Don’t make me think 」的理念同樣。你想用戶來「 webnovel 」是來看小說的,不是來稱讚咱們網頁體驗作得多麼優秀的。當用戶開始關注到咱們網站體驗的時候,那正是說明咱們的體驗很差的時候。框架
那用戶在什麼地方容易感覺到咱們網站的體驗呢?工具
第一個地方就是頁面加載的時候。這裏咱們明顯能夠看到「 webnovel 」的 Logo 和三個小圖標在頁面刷新的時候,會有一瞬間從無到有的過程。性能
咱們「 webnovel 」站點是面向全球海外用戶的,跳出了國內兼容 IE 瀏覽器的怪圈,因而在小圖標這塊咱們選擇了瀏覽器兼容性要求高,可是呈現效果卻更好的SVG圖標「 SVG 屬於矢量圖標,在能保證體積更小的狀況下,還能在放大縮小的時候不失真 」。咱們將 Iconfont 「來自阿里的在線圖標管理工具 」自動幫咱們生成的 JS 代碼引用到頁面中,結果就出現了上面的呈現效果。
這個原理其實很簡單,咱們 SVG 圖標的 DOM 結構是在 JS 執行以後動態添加到咱們的標籤內部的。因此就會出現先呈現頁面,再呈現圖標的效果。因而咱們很天然的想到,直接將 JS 生成的 DOM 結構放到咱們的內部,來解決這個問題。
可是很傻很天真,在拷貝 DOM 結構的時候咱們發現,這個 SVG 代碼量也太多了,直接放到頁面內部會大大增長咱們 HTML 的代碼量,影響整個頁面呈現的速度,這個感受是撿了芝麻丟西瓜。
最後咱們採用的解決方案是,把 SVG 圖標作了拆分,首屏的顯示的圖標咱們採用直接添加 DOM 的方式,其它剩餘的圖標仍是選擇 JS 動態加載老方法。這樣首屏以外的圖標即便有閃動用戶也很難看到。因而咱們解決了首屏圖標閃動的問題,也避免了 SVG 圖標代碼量的問題。用戶感知不到圖標的閃動,也就不會花時間去思考咱們頁面加載是快是慢的體驗問題了。
提早加載首屏數據,能必定程度上加強咱們用戶刷新和跳轉頁面時候的體驗。
第二個地方的就是咱們數據請求的時候。當咱們切換TAB的時候,能明顯看到一個 Loading 的效果。用戶的動做觸發數據請求,在等待的過程咱們用 Loading 來告知用戶這一狀態,以減弱用戶等待的焦慮。這實際上是一個對於數據加載,加強體驗常規的作法。
但是無論咱們的數據請求多麼的快,用戶都仍是能明顯能看到這個 Loading 的效果。這並非咱們想要的。
咱們這邊處理的辦法是,在用戶鼠標放到這個按鈕的時候,咱們認爲用戶是有了點擊的意願,因而咱們就提早發起了數據請求的操做。當用戶按下這個按鈕的時候,咱們的數據請求的整個過程可能已經結束,而這也就意味着咱們的 Loading 狀態已經消失。此時用戶就能直接看到咱們加載好的數據了。也就是說頗有可能,在整個過程當中用戶是看到不到咱們的 Loading 狀態的。這不就是咱們想要的體驗上的優化嗎?
利用用戶操做的空閒時間,提早作一些預處理,不失爲一個加強數據請求體驗的好辦法。
咱們都知道,圖片和圖標都是屬於展現性的元素,特別是像咱們 「 webnovel 」網站設計師很用心製做的書封,咱們天然會願意選擇體積更大可是質量更高的高清圖。爲了不影響正文的展現,咱們又不得不選擇了相似圖片 Lazyload 的機制,讓這個圖片延遲加載。
可是能夠明顯看到這和以前的數據加載的 Loading 邏輯同樣,須要一個表示 Loading 態的佔位圖。等圖片加載完成,佔位圖會一瞬間被咱們的高清書封替換,因而此時就出現了咱們不指望的閃動。
當用戶一看到閃動,他們就會去思考你這個加載是快仍是慢。可是咱們要的是 「Don’t make me think 」。咱們不但願讓用戶去思考除開咱們產品以外的東西。因此咱們得想個辦法弱化甚至去除這種閃動。
講到這裏呢就不得不科普如下咱們瀏覽器自己就有的圖片緩存機制了。在必定時間段內你瀏覽器訪問過的圖片,會被瀏覽器緩存。當你再一次看到這個圖片的時候,這個圖片就直接讀取瀏覽器緩存的內容一瞬就打開,不會有閃動問題。
因而咱們就想是否是能夠利用這個機制,解決以前閃動的問題。可是如今難點是,咱們詳情頁的書封是比首頁的書封大的。由於尺寸不同因此是不一樣的圖片,因而就沒有緩存這個概念。
若是咱們讓詳情頁也用首頁的書封,詳情頁小圖被拉伸就會看起來很模糊。若是首頁用詳情頁的大書封,首頁的圖片數據加載開銷又太大。
咱們這邊採用的解決方案是,三層疊加法。咱們把佔位圖,小書封,大書封,按照上圖的層級完美的疊在了同一個位置。當用戶從首頁進入到咱們詳情頁的時候,咱們佔位圖和小書封都是直接使用瀏覽器緩存瞬間呈現的,由於小書封是疊在佔位圖之上的,因此用戶是看不到佔位圖的。而此時大書封正在加載,當大書封加載好了以後,就會蓋在小書封之上。等用戶仔細看這個書封的時候,這個大書封其實頗有可能已經加載完成。
從上圖的GIF能夠看出,整個過程就從以前的佔位圖到大書封的閃現,變成了如今的小書封到大書封的漸變。其實這是很難被用戶發現的。
看到這裏可能有同窗會問說,既然這裏都看不到佔位圖,爲何還須要加載這個圖呢?其實緣由很簡單,由於不是每一個人都是從首頁進入到詳情頁的。有可能用戶是直接打開的這個連接。那麼此時佔位圖就回到了最初的邏輯。先看到佔位圖而後再看到書封。固然我也得認可對於這樣的用戶,咱們實際上是多加載了一個小書封的資源的。可是對於體驗上的優化來講,這一點資源的消耗我我的認爲仍是能夠接受的。
還有一個好玩兒的點是,在這個地方由於同時加載了,佔位圖,小書封,大書封,它們做爲圖片也都會被瀏覽器緩存,當用戶跳轉到其它頁面的時候,若是有相同的圖片,那又是瞬開的。這樣咱們就充分的利用了瀏覽器緩存,讓用戶在咱們網站上的體驗獲得了進一步的提高。
圖片緩存,讓網站體驗比好更好。
視覺層的體驗優化是所見即所得的,你能夠很快的看到優化的成果。可是有不少由於瀏覽器差別,或者用戶差別引發的體驗問題,咱們無法直觀和快速的去證實體驗優化的效果。咱們就得靠數據去證實了。
要用數聽說話,首先咱們得有數據,而這個數據的收集工具咱們海外 PC 站用的則交給了來自 Google 的 Analytics。這邊給你們講關於這個的一個有趣故事。
有一天我在用 webpagetest 「 一個全球知名的測試網站加載速度的工具 」測試咱們 「 webnovel 」頁面的時候我看到了這樣一個結果。
你們注意看那個最長的綠色,看到了吧,一個 DNS 加載怎麼比後面的 SSL + CSS 加載 + CSS渲染還要長?CSS 但是強制阻塞咱們頁面渲染的重要元素,它要是慢了,你網站作再多優化都沒有用。這個你讓人怎麼忍?
怎麼辦呢?咱們選擇了一個暴力可是有效的辦法,直接把 CSS 合併到咱們的 HTML 文件中 「 CSS 內聯到 HTML 內部 」。CSS 文件都沒有了,看你還怎麼 DNS、SSL … 哇!好棒,我拿着這個去找老大邀功。老大啪啪給我提了兩個點就把我打懵了。
第一, 你這個明顯是首次加載頁面時候的效果,對於大多數這個 CSS 文件已經有緩存的用戶,你如何證實,這個優化對他們是又用的?
第二,「 webnovel 」是面向全球的網站,你又如何證實,這個優化對全部地區的用戶的優化力度 ?
是啊我要怎麼證實?「 webnovel 」全球這麼多的用戶,我就用一份 「 webpagetest 」 的測試報告去涵蓋全部的終端和用戶羣體,顯示是不具備公信力的。而且我又要如何證實這個優化的力度是多少?
此時中國好同事出現了,個人前端邏輯小夥伴幫我在框架機內部作了一個隨機預處理的AB樣本輸出。道理很簡單,就是讓 50% 的用戶是用原始的方式加載咱們的 CSS ,另外 50% 的用戶使用咱們 CSS 內聯到 HTML 內部的方式。這樣我只須要加個標識符區別一下這兩個樣本,上報到 GA 「 Google Analytics 」 ,而後 GA 會自動幫咱們統計和處理這些樣本,最後我只須要將這兩個樣本的平均值作一個 10 之內的減法,就知道了咱們的優化力度具體是多少了。
然而另外一個問題出現了,咱們應該把什麼做爲數據上報給 GA 呢?顯然用整個網頁的加載時間去證實 CSS 的加載是不對的。那我用 CSS 加載完成以後的那個時間去證實?但是我又怎麼能證實 CSS 加載完成以後頁面就已經渲染好了呢?咱們不是在作體驗的優化嗎?又怎麼能僅憑藉 CSS 文件的加載來證實用戶體驗變好了呢?
此時我是凌亂的。不行,整個場面我要HOLD住,不能慌。
體驗,體驗,CSS都沒有加載,用戶連頁面都沒有看到又怎麼能叫體驗?因而用戶剛看到頁面的時間,被我認定是必定程度上能夠證實體驗優劣的。
怎麼去獲取這個時間呢?其實利用 performance API,就能夠獲取到上圖所示的瀏覽器各個階段的時間。
Chrome瀏覽器 能夠用 window.chrome.loadTimes().firstPaintTime; IE8+ 瀏覽器能夠用 window.performance.timing.msFirstPaint;
來獲取頁面開始渲染的時間。最後你們一致的意見是,將這個 「 firstPaintTime - navigationStart 」的時間近似理解爲用戶從訪問頁面到看到頁面的時間。
因而,我很開心的把這個這個時間上報到 GA,而後版本上線,等待數據收集。最後得出以下的統計結果:
看到以上的數據結果,這個優化的時間和總時間比起來比預想的差太多了。感受不該該啊?
當咱們仔細分析這個數據,發如今這整個的時間段內,服務端的時間佔了 1.1s 。我在這拼命的優化體驗,但是最後發現體驗的瓶頸並不在咱們前端這邊。這充分的說明,有的東西仍是得靠數聽說話,而不是你覺得你覺得的就是你覺得的。固然除開這個瓶頸時間咱們能夠得出以下的結論。
至此咱們有理有據的證實了優化體驗的成果,雖然結果出乎了咱們的預料,可是卻證實,數據上報是可以證實咱們體驗成果的一個有理證據。
固然咱們也把這個瓶頸問題,反饋給力服務端的同窗。而後獲得的答覆是,「 webnovel 」還屬於咱們海外站的新項目,不少海外服務器有待跟進。相信在後續設備以後,會解決這個痛點。
數據上報,讓你的體驗優化有理有據。
篇幅有限,這邊我只是零散的列舉了,我我的認爲能夠從用戶體驗角度去作的幾點重構優化,以及如何利用數據去證實你優化的力度。但願對於你們有必定的啓發和幫助,有什麼問題,也請給我留言,咱們能夠深刻的交流。