作者介紹:Addy osmani
就職谷歌Chrome團隊,致力於讓網站運行速度更快,他參與的項目包括——lighthouse
隨著移動網際網路快速發展,移動端網站的頁面效果也越來越絢,但是交互體驗或多或少有些「遲鈍」?這是為啥呢?
首先JavaScript運行在手機瀏覽器上會產生不小的系統開銷,由於這個問題存在,Addy osmani 將會帶著大家探討移動端網站的腳本問題,讓其在大多數手機瀏覽器上運行更快,更輕。
我們在構建交互式網站自然少不了JavaScript, 為了達到更好的交互,我們讓用戶瀏覽器加載了太多的JavaScript腳本。不知道大家是否有這樣的瀏覽體驗:我們在手機瀏覽器上刷網頁,點擊連結或者滑動頁面時,網頁一點反應都沒。這種經歷,想必大家都有,因為對於手機瀏覽器來說,運行加載JavaScript會消耗不小的系統資源,因此延遲了用戶的交互響應,今天我將會給大家介紹一些有效的方法策略,提升用戶在手機端的使用體驗。
太多的「交互」,讓網站更臃腫!
當你的用戶用手機訪問你的網站時,你的網站讓用戶的瀏覽器加載了大量的文件,其中很多是腳本文件。也許你為了方便開發或者為了更炫的效果,引入了腳本庫或插件庫,從來沒有檢查確認到底加載了多少腳本,體積有多大?加載的腳本是否對用戶有用?對於我們多說前端客來說,我們是如此的喜歡JavaScript,但是我們不得不正視它會消耗不小的系統資源。
不少熱門的網站,向用戶的瀏覽器發送了大於1MB的腳本文件。只有為數不多的網站進行了腳本文件壓縮,使腳本體積大小降到350KB左右,那些未壓縮腳本的網站,如果腳本超過1MB大小,您的用戶至少需要等待14秒的時間才能正常使用你的網站。(部分熱門移動網站腳本加載分析報告:https://beta.httparchive.org/reports/loading-speed)
為什麼這麼慢?用戶大多數是在不穩定的行動網路加載你的網站,腳本加載完了,需要手機CPU進行運行處理。
以下是目前大多數網站存在的問題:
使用了用戶界UI框架(例如bootstrap)客戶端框架或交互依賴框架(React,vue)Polyfills(但是現代瀏覽器並不需要)未壓縮的腳本工具庫(例如moment.js)隨著需求的增加,腳本的數量也在增加,體積也再不斷變大,因此頁面運行的時間也越來越長!
現代網頁加載時...
一個網頁加載時,對於用戶來說:網頁是否還在加載?加載的內容是否有用?功能是否能用?當網頁的內容一點點呈現給用戶時:導航顯示一部分出來,伺服器是否還在正常發送內容?當文本和其他非可見的內容,是不是用戶需要的,內容加載完了,用戶能否正常的點擊和滑動?
所謂的交互式頁面,必須快速響應用戶的輸入,因此javaScript腳本應該快速響應用戶的交互,無論用戶點擊連結還是滾動瀏覽頁面,用戶都需要頁面快速響應自己的行為。
為了最大化的滿足產品業務需求,您可能要求用戶的客戶端運行很多事件,由於JavaScript語言的特點,主線程上的事件延遲了交互元素的呈現,對於許多公司來說縮短交互時間是一個不小的挑戰。
什麼才是好的交互目標?
我們Chrome團隊認為,在大多數中等手機設備(https://calendar.perfplanet.com/2017/time-to-interactive-measuring-more-of-the-user-experience/),3G或4G的網絡環境下,5秒內完成用戶的交互響應,這就是良好的交互目標。你可能會說:我們的用戶都是用高端的手機和使用快速的網絡。但是我們所謂的用戶呢?——在使用「快速」的咖啡店的共享wifi或移動的車廂裡訪問我們的網站,他們的手機實際只能獲取2G或3G的速度。
哪些網站開始減少腳本的體積,縮短了用戶的交互時間?
Pinterest.com 將原先的腳本從2.5MB減少至200KB以下,交互時間從23秒減少至5.3秒(https://medium.com/dev-channel/a-pinterest-progressive-web-app-performance-case-study-3bd6ed2e6154),正式由於這個改進,網站的收入增長了44%,註冊量增加753%,行動網路用戶的活躍度增長了103%(https://medium.com/@Pinterest_Engineering/a-one-year-pwa-retrospective-f4a2f4129e05);autotrader網站將腳本的體積減少了56%,縮短了50%的交互時間。(https://engineering.autotrader.co.uk/2017/07/24/how-we-halved-page-load-times.html)。
對於一個移動網站時,不僅要考慮腳本的體積大小,響應時間,還要考慮移動變化不穩定的手機網絡和大多數終端手機的硬體環境。
為什麼JavaScrip的代價如此之高?
我們都清楚一個請求發送至伺服器後,伺服器會逐步返回一些HTML內容,在逐步解析渲染DOM時發現標記不同的資源(CSS,JavaScript)以及圖片資源,然後完成這些文件的下載和處理。
如果要讓JavaScript快速相應用戶的交互,我們必須要讓腳本快速的加載和編譯執行,由於JavaScript需要快速完成編譯才能執行用戶的響應,這個過程必然會影響延遲用戶的交互體驗。
還有一點需要記住,網絡上同等的資源,消耗的系統資源卻不同。一個200KB的圖片絕對不等於一個200KB的腳本消耗的資源,下載這些資源時間可能相同,但是消耗的資源成本卻不一樣。
不同類型的手機
現實就是這樣,並非每個人都用得起高端手機,還有大部分用戶使用中低端手機。由於中低端手機CPU,GPU的限制,處理JavaScript等資源的時間也不同。因此我們應該在真實的手機環境和網絡環境下測試至關重要。檢查分析您的用戶訪問行為至關重要,如果您無法購買太多中低端手機進行測試,你可以使用這個在線網站工具WebPageTest(webpagetest.org/easy),進行在線測試。(以下是小編前端達人http://www.qianduandaren.com的測試效果)
了解你的網站受眾十分重要,並非每個網站都要滿足低端手機在2G的環境下表現良好,你應該保證你的大多數用戶快速加載你的網站。
如何減少JavaScript腳本的發送
Code splitting(代碼分割)技術——將會幫你拆解大的JavaScript腳本文件,實現了腳本的按需加載(lazy-load)。這樣有效的避免了將單個「main.js」整個站點的腳本文件發送給用戶。
將代碼引入站點的最佳方法是動態import(),相關介紹請點擊查看https://developers.google.com/web/updates/,下面這個例子使我們常見的靜態引入方法:
import{add}from'./math'
console.log(add(30,15));
如果使用動態import(),我們可以按需加載引入math腳本文件,例如實現點擊一個按鈕動態引入math腳本
const btn= document.getElementByld('load);
btn.addEventListener('click',()=>{
import('./math').then(math =>{
console.log(math.add(30,151));
});});
使用webpack構建的項目也能很方便的實現按需加載,具體如何使用可以點擊查看https://www.jianshu.com/p/b3b8fb8a2336這篇文章。代碼分割同時可以應用在路由加載、組件加載、頁面加載等方面,以下分別是使用React,Vue,Angular使用Code splitting的使用指南:
React——https://medium.freecodecamp.org/code-splitting-with-react-and-react-router-62e174382d4cVueJS——https://router.vuejs.org/zh/guide/advanced/lazy-loading.htmlAngular——https://angular.io/guide/lazy-loading-ngmodules如果你正在使用React,我很高興向您推薦推薦React Loadable(https://github.com/jamiebuilds/react-loadable),實現了動態高效的加載組件,以下代碼是我們使用靜態方法引入gallery組件:
import GalleryComponent from 『./GalleryComponent』;
const My Component=()=>(<GalleryComponent/>);
使用React Loadable後,我們改下上面的代碼:
import Loadable from 'react-loadable』;
const LoadableGallerycomponent=Loadable({
loader:()=>import('./GalleryComponent'),
loading:()=><div>Loading...</div>,
});
constMyComponent=()=><LoadableGalleryComponent/>);
最近許多大型團隊正在使用Code splitting方法改寫重寫他們的手機端網站,並取得巨大的成果。比如Twitter他們背後優化的故事——https://blog.twitter.com/engineering/en_us/topics/open-source/2017/how-we-built-twitter-lite.html,Tinder背後優化的故事——https://medium.com/@addyosmani/a-tinder-progressive-web-app-performance-case-study-78919d98ece0,他們都通過此項技術將交互時間縮短了50%。
Next.js[react](https://github.com/zeit/next.js/),Preact CLI(https://github.com/developit/preact-cli) ,PWA starter kit(https://github.com/polymer/pwa-starter-kit) 這些框架設計之初的首要目標就是解決移動端網站的性能問題,讓代碼快速加載響應用戶的交互。
值得慶幸的事情,JavaScript生態為我們提供了分析打包後所有組件與組件的依賴關係的可視化工具,幫助我們分析。比如:
Webpack Bundle Analyzer( https://www.npmjs.com/package/webpack-bundle-analyzer)Source Map Explorer(https://github.com/danvk/source-map-explorer)Bundle Buddy (github.com/samccone/bundle-buddy)
優化,監控
如果你不確定你的JavaScript性能是否有問題,你可以使用Chrome提供的Lighthouse——是一個Google開源的自動化工具,主要用於改進網絡應用(移動端)的質量。目前測試項包括頁面性能、PWA、可訪問性(無障礙)、最佳實踐、SEO。Lighthouse會對各個測試項的結果打分,並給出優化建議,這些打分標準和優化建議可以視為Google的網頁最佳實踐。
還有一件值得你監控和關注的事情,就是檢查有沒有將未使用的代碼發送給用戶, code coverage(https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage)——谷歌瀏覽器開發者工具中的代碼覆蓋率面板,此面板內會告訴你哪些代碼未使用,哪些又是使用了的。這樣可以精簡掉未使用的代碼來減小頁面的大小。
這些工具對於識別需要分割代碼及哪些需要延長加載非關鍵腳本是非常有價值的,慶幸的是有一套標準的評估指標指引優化——https://timkadlec.com/2014/11/performance-budget-metrics/
設計合理的優化指標
定義一個可衡量可測試的優化目標至關重要,有個標準的行為指南有助指引整個團隊圍繞著目標不斷的改善用戶交互體驗。指標主要包含以下幾個方面:
裡程碑時間——頁面加載完,具備響應用戶的時間。數量指標——JavaScript腳本大小,多少文件請求數,圖片數量和大小基於規則的指標分數——我們可以通過專業的工具Lighthouse或WebPageTest等工具進行相關的評分。績效指標對於團隊來說,最大的挑戰並不是技術而是公司的文化,我們需要開會不斷的圍繞目標進行討論,向業務運營團隊諮詢他們期望的目標並接受各種相關質疑,同時向工程技術人員傳達會議目標讓其解決瓶頸問題,雖然過程有些痛苦,但是對項目的推進還是有很大的幫助。
那麼有什麼樣的工具能夠幫助我們決策制定合理化目標並生成可視化的報告呢,你可以使用 lighthouse CI project (https://github.com/ebidel/lighthouse-ci),Calibre(https://calibreapp.com/),treo(https://treo.sh/),speedcurve(https://speedcurve.com)
快點、再快點
許多小的改變將會帶來巨大的收益,儘可能的減少JavaScipt的體積換取更短用戶交互時間,如果你能漸進式的逐步推進這個目標,你的用戶會十分感謝你。
更多精彩內容,請微信關注」前端達人」公眾號!
新年大禮包
關注「前端達人」公眾號,回復「新年大禮包」獲取英文電子書: