漸進式Web應用程序(PWAS)嘗試通過向移動用戶提供每個移動網絡應用程序和本機移動應用程序的世界。
>>他們提供類似應用的用戶體驗(濺出屏幕和主屏幕圖標),它們從https安全的服務器提供,即使以低質量或緩慢的網絡,它們也可以快速加載(由於頁面加載最佳實踐)條件,它們具有離線支持,即時加載和推動通知。 PWA的概念首先是由Google引入的,但仍然得到許多Chrome功能和出色的工具的支持,例如Lighthouse,這是一種可訪問性,性能和漸進式審核的開源工具,我們將在以後進行一些研究。 > 在整個速成課程中,我們將與ES6從頭開始構建PWA,並與燈塔進行反應並逐步優化它,直到我們在UX和性能方面取得最佳效果。
>術語“漸進式”一詞僅表示PWA的設計方式,以至於它們可以在現代瀏覽器中逐漸增強
,在現代瀏覽器中,許多新功能和技術已經得到支持,但在舊瀏覽器中也應該很好地工作沒有尖端的功能。
>然後您可以使用:
運行它
<span>npm install -g lighthouse </span>>請注意,即使您使用的是基於CLI的版本,您也需要在系統上安裝Chrome才能使用Lighthouse。
>從Scratch
構建您的第一個PWAlighthouse https://sitepoint.com/在本節中,我們將從頭開始創建一個漸進的Web應用程序。首先,我們將使用React和Reddit的API創建一個簡單的Web應用程序。接下來,我們將按照燈塔報告提供的說明來添加PWA功能。
>請注意,公共無授權reddit API已啟用CORS標題,因此您可以在沒有中介服務器的情況下從客戶端應用程序中消耗它。
>
我們首先安裝React Team創建的Project App,從WebPack配置的麻煩中節省您的項目樣板。
><span>npm install -g lighthouse </span>
應用程序外殼是漸進式Web應用程序的重要概念。這只是最小的HTML,CSS和JavaScript代碼,負責渲染用戶界面。
用於構建簡單的UI,我們將使用材料UI,這是React中的Google材料設計的實現。
讓我們從NPM安裝軟件包:
下一個打開src/app.js,然後添加:
>lighthouse https://sitepoint.com/
接下來,我們需要使用兩種方法fetchfirst()和fetchnext()獲取reddit帖子:
><span>npm install -g create-react-app </span>create-react-app react-pwa <span>cd react-pwa/ </span>
>您可以在此GitHub存儲庫中找到源代碼。
><span>npm install material-ui --save </span>>在對應用程序進行審核之前,您需要使用本地服務器在本地進行構建並在本地提供應用:
此命令在package.json中調用構建腳本,並在react-pwa/build文件夾中生成一個構建。
<span>import <span>React, { Component }</span> from 'react'; </span><span>import <span>MuiThemeProvider</span> from 'material-ui/styles/MuiThemeProvider'; </span><span>import <span>AppBar</span> from 'material-ui/AppBar'; </span><span>import <span>{Card, CardActions, CardHeader,CardTitle,CardText}</span> from 'material-ui/Card'; </span><span>import <span>FlatButton</span> from 'material-ui/FlatButton'; </span><span>import <span>IconButton</span> from 'material-ui/IconButton'; </span><span>import <span>NavigationClose</span> from 'material-ui/svg-icons/navigation/close'; </span> <span>import logo from './logo.svg'; </span><span>import './App.css'; </span> <span>class App extends Component { </span> <span>constructor(props) { </span> <span>super(props); </span> <span>this.state = { </span> <span>posts: [] </span> <span>}; </span> <span>} </span> <span>render() { </span> <span>return ( </span> <span><MuiThemeProvider> </span> <span><div> </span> <span><AppBar </span> title<span>={<span >React PWA</span>} </span> iconElementLeft<span>={<IconButton><NavigationClose /></IconButton>} </span> iconElementRight<span>={<FlatButton onClick={() => this.fetchNext('reactjs', this.state.lastPostName)} label="next" /> </span> <span>} </span> <span>/> </span> <span>{this.state.posts.map(function (el<span>, index</span>) { </span> <span>return <Card key={index}> </span> <span><CardHeader </span> title<span>={el.data.title} </span> subtitle<span>={el.data.author} </span> actAsExpander<span>={el.data.is_self === true} </span> showExpandableButton<span>={false} </span> <span>/> </span> <span><CardText expandable={el.data.is_self === true}> </span> <span>{el.data.selftext} </span> <span></CardText> </span> <span><CardActions> </span> <span><FlatButton label="View" onClick={() => { </span> <span>window.open(el.data.url); </span> <span>}} /> </span> <span></CardActions> </span> <span></Card> </span> <span>})} </span> <span><FlatButton onClick={() => this.fetchNext('reactjs', this.state.lastPostName)} label="next" /> </span> <span></div> </span> <span></MuiThemeProvider> </span> <span>); </span> <span>} </span><span>} </span> <span>export default App; </span>
>使用服務,您的應用程序將從http:// localhost:5000/。
從本地提供服務。<span>fetchFirst(url) { </span> <span>var that = this; </span> <span>if (url) { </span> <span>fetch('https://www.reddit.com/r/' + url + '.json').then(function (response) { </span> <span>return response.json(); </span> <span>}).then(function (result) { </span> that<span>.setState({ posts: result.data.children, lastPostName: result.data.children[result.data.children.length - 1].data.name }); </span> <span>console.log(that.state.posts); </span> <span>}); </span> <span>} </span> <span>} </span> <span>fetchNext(url<span>, lastPostName</span>) { </span> <span>var that = this; </span> <span>if (url) { </span> <span>fetch('https://www.reddit.com/r/' + url + '.json' + '?count=' + 25 + '&after=' + lastPostName).then(function (response) { </span> <span>return response.json(); </span> <span>}).then(function (result) { </span> that<span>.setState({ posts: result.data.children, lastPostName: result.data.children[result.data.children.length - 1].data.name }); </span> <span>console.log(that.state.posts); </span> <span>}); </span> <span>} </span> <span>} </span> <span>componentWillMount() { </span> <span>this.fetchFirst("reactjs"); </span><span>} </span>
>您可以毫無問題地審核您的應用程序,但是如果您想在移動設備中進行測試,也可以使用Surge.SH之類的服務來使用一個命令進行部署!
>您可以從此鏈接找到此應用的託管版本。
><span>npm run build </span>現在,讓我們打開Chrome DevTools,去審核面板,然後單擊執行審核。
從報告中我們可以看到,漸進式Web應用程序的得分為45/100,性能為68/100。
在漸進式Web應用程序下,我們有6個失敗的審核和5次通過的審核。這是因為生成的項目默認情況下已經添加了一些PWA功能,例如Web清單,視口元和
燈塔建議通過降低下載尺寸或推遲不必要的資源下載來減少關鍵渲染鏈的長度來改善頁面加載性能。
>請注意,性能得分和指標值可以在同一台計算機上的不同審核會話之間發生變化,因為它們受到許多不同條件的影響,例如您當前的網絡狀態以及當前的機器狀態。
為什麼頁面加載性能和速度重要在
之前考慮性能>您需要使用不同的測試工具,例如Chrome DevTools,Lighthouse,Google PagesPeed等,以在不同和模擬的網絡條件下進行大量測試,因此您可以成功地優化您的應用程序頁面加載性能。
> PWA性能指標您需要放在雷達上>您可以使用燈塔用不同的指標,診斷和機會來衡量和優化應用程序的頁面加載性能。
首先有意義的油漆
第一個有意義的油漆是一種措施,僅表示用戶在屏幕上看到有意義或主內容的時間。該審核的越低,您的應用程序的感知性能就越好。
>我們看到,從1.3s開始瀏覽器開始呈現空背景,然後從2s開始瀏覽器開始呈現標頭,2.4 s呈現標頭和底部的按鈕。直到第三秒鐘才呈現帖子。整個過程花費了3.4秒,第一個有意義的油漆等於
2.340ms - 當呈現沒有的標頭
第一個有意義的油漆實際上取決於我們可以認為有意義的塗料,這在不同的用戶之間可能有所不同。如果用戶只對閱讀帖子感興趣,那麼第一個有意義的油漆是在3秒鐘之後。您可以查看Google如何從此文檔中計算此指標。 > 這是同一應用程序的另一部膠片,其中燈塔在最後一個屏幕截圖上報告了FMP為 臨界渲染路徑 關鍵的渲染路徑是與Web瀏覽器渲染頁面如何相關的概念,也就是說,從接收HTML,CSS和JavaScript資產到瀏覽器處理並呈現實際有意義的內容的步驟。為了優化關鍵的渲染路徑,您需要對與用戶當前操作相關的內容進行更高的優先級。也就是說,如果他們要訪問您的應用程序,您可以先首先顯示UI的可見部分,或者稱為上述區域。
>
中嵌入標記的JS,CSS和IMG源的工具
>有關更多詳細信息,您可以閱讀“優化關鍵渲染路徑”。
>您還可以查看此策劃工具的列表,以融合關鍵CSS資產。還要檢查這些工具是否包含JavaScript和其他資產:
現在,讓我們嘗試使用內聯源和Inline-Source-CLI解決此問題:
然後,我們在構建文件夾中導航並打開index.html,然後將關鍵字inline添加到和<script> <script> elements我們想要內聯的元素:<ancy>>
<p>
</script>
<span>npm install -g lighthouse </span>>通過融入CSS和JavaScript資產,我們將關鍵請求鏈減少到2
您可以通過優化關鍵的渲染路徑來優化交互的時間。
>感知速度索引>感知速度索引是一個指標,可以在考慮佈局穩定性(沒有UI元素突然位移)的同時測量頁面上的折疊視覺性能。它只是指示頁面內容可見填充的速度。
估計的輸入延遲
估計的輸入延遲是一個指標,指示主線程何時準備處理輸入。
>
是第一個字節(TTFB)
>首先字節(TTFB)的時間是一種測量值,用來指示Web服務器或其他網絡資源的響應能力。 TTFB衡量用戶或客戶端的持續時間,向客戶端瀏覽器收到的頁面的第一個字節提出HTTP請求。
>現在讓我們查看開發人員使用的一組概念和常見技術來優化這些指標。
>代碼分裂和基於路由的塊>
JavaScript生態系統近年來已經發生了巨大變化,諸如WebPack和browserify之類的新工具,用於將所有腳本捆綁到一個文件中。這被認為是良好的做法,因為它有助於將多個腳本文件的網絡請求減少到一個請求(用於獲取整個捆綁包),優化關鍵的渲染路徑(沒有長期塊JavaScript和CSS資產)。但是問題是,對於大型應用程序,捆綁包將具有更大的尺寸,從而使下載捆綁包,對其進行處理,然後啟動應用程序效率非常低,這會影響即時的Web體驗(增加了第一個有意義的時間的時間油漆和UI變得互動的時間)。
作為解決此問題的解決方案,不同的應用程序使用代碼拆分和基於路由的塊(將代碼拆分為僅每條路線需要的塊)。因此,瀏覽器只需要下載渲染第一頁/路線所需的第一個塊,然後在用戶瀏覽其他路線時懶惰加載剩餘的塊。
>>服務器端渲染是呈現服務器上的初始內容而不是瀏覽器的過程 - 在許多情況下,它可能會改善頁面加載性能,因為瀏覽器可以在下載後立即顯示內容(PLAIN HTML) 。
>單獨的服務器端渲染將無濟於事,因為需要下載和啟動JavaScript資產。
> prpl性能模式prpl代表:
>最初URL路線的關鍵資源
> 通過緩存
優化性能 緩存是將經常請求的數據保存在近距離存儲位置的過程。對於Web,這是瀏覽器內存或數據庫。瀏覽器實際上具有專門為緩存網絡響應設計的高速緩存位置,但是開發人員還可以利用其他存儲機制(例如HTML5本地存儲API和IndexEdDB)。我們可以在此處考慮兩類應用程序。僅需要網絡連接才能使資產負責呈現UI和/或需要提供核心功能的應用程序。例如,考慮一個為用戶提供個人會計的應用程序,這僅取決於算法和計算(本地CPU)。
>第二類是依賴遠程服務器以獲取更新信息的應用程序。您可能想知道為什麼需要緩存數據,因為它很快就會過時,並且用戶大多需要更新的信息。問題是,在世界許多地方,問題不是網絡連接的永久中斷,而是網絡在慢速和良好信號之間的波動狀態,即使應用程序已經加載了,這也會影響用戶體驗。
>該應用程序可以利用數據緩存(利用背景同步API)來保證用戶在頁面之間導航時的服務,即使他們離開並在短時間內又回到應用程序。不斷觀看網絡狀態,然後恢復獲取/發送數據而不會中斷用戶。
現在,讓我們解決失敗的問題以獲得更好的分數。註冊服務工作者
>服務工作者是一種現代的瀏覽器技術,可以用作客戶端代理,允許您的應用程序(通過攔截網絡請求)實現用於添加功能(例如即時加載和離線支持等)的緩存等。
>服務工作者也可以用於實施更新並通過推送通知進行參與。
>>服務工作者無法訪問頁面DOM,但是可以通過postmessage()方法與客戶端(窗口,工作人員或共享工作者)進行通信。
>許多瀏覽器API可在服務工作者中使用,例如:
fetch api:用於從遠程服務器中獲取內容(發送請求並獲取響應)
>安裝事件:當用戶首次訪問該應用時,您將獲得安裝事件,並下載並安裝了服務工作者
激活事件:調用.register()後觸發(下載和安裝事件之後)以上是漸進式網絡應用程序:速成課程的詳細內容。更多資訊請關注PHP中文網其他相關文章!