重點介紹H5頁面秒開優化與實踐
背景
3月份針對線上重點H5專案秒開進行治理,本文將逐步介紹如何透過H5頁的最佳化手段來提高 1.5 秒開率。
為什麼要做最佳化?
- 從使用者角度來看,優化能讓頁面載入得更快、對使用者操作回應更及時,使用者體驗更良好,提升使用者體驗和降低使用者流失率非常重要。其中 Global Web Performance Matters for ecommerce報告中也有具體說明最佳化的重要性。
- 從企業角度來看,優化能夠減少頁面請求數或減少請求所佔頻寬,能夠節省可觀的資源成本,最終提高收益轉換。
優化目標
從上圖可以看出,有些網域下可能低於90%,最高的也沒達到96% ,離既定98%的目標還有一定差距。
H5效能分析
分析工具
- Lighthouse
- Chrome DevTools
- gtmertrix 線上視覺化分析工具
Webview載入H5
通常情況會分以下幾個階段
- Webview初始化。
- 到達新的頁面,網路連接,從伺服器下載html,css,js,頁面白螢幕。
- 頁面基本框架出現,js請求頁面數據,頁面處於loading狀態。
- 出現所需的數據,完成整個頁面的渲染,使用者可互動。
從圖形直觀看H5 啟動過程:
如何縮短這些過程的時間,就成了優化 H5 效能的關鍵。接下來我們詳細看一下各階段注意的最佳化點。
優化方案
從以下幾個方面入手:
- 載入策略最佳化
- 增加骨架螢幕
- 資源請求最佳化(靜態資源、圖片以及webp 、圖片懶載入、元件按需載入)
- 打包資源最佳化
- CDN & 快取
接下來就逐一分析
載入策略最佳化
先看一張圖:
developers.google.com/web/fundame…)從這張圖裡我們能看到什麼,大致能總結為以下四點:
- 預設:HTML解析,然後載入JS,此時HTML 解析中斷,然後執行JS,最後JS執行完成並恢復HTML解析。
- defer情況下:HTML 和JS 並駕齊驅,最後才執行JS( js腳本在所有元素載入完成後執行,而且是按照js腳本聲明的順序執行,但要等到dom文檔全部解析完才會被執行)。
- async 情況下:HTML和JS 並駕齊驅,JS 的執行可能在HTML解析之前就已完成了(js腳本是亂序執行的,不管你宣告的順序如何,只要某個js腳本載入完就立即執行)。
- module情況下:與defer情況類似,只不過在提取的過程中會加載多個JS 文件而已(聲明acript標籤type="module"屬性從而擁抱es6的模組導入導出語法, 加載也和defer差不多,只不過可以載入多個JS檔而已)。
專案中實作範例:
預先載入
prefetch 和preload
preload 是一個新的Web 標準,在頁面生命週期中事先載入你指定的資源,同時確保在瀏覽器的主要渲染機制啟動之前。
具體使用如下:
<scirpt></scirpt> <scirpt></scirpt>复制代码
注意:preload 緊鄰 title 放,使其最早介入。
prefetch 是提示浏览器,用户在下次导航时可能会使用的资源(HTML,JS,CSS或者图片等),因此浏览器为了提升性能可以提前加载、缓存资源。prefetch 的加载优先级相对较低,浏览器在空闲的时候才会在后台加载。用法与 preload 类似,将 rel 的值替换成 prefetch 即可。
preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源,而 prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源。所以建议:对于当前页面很有必要的资源使用 preload,对于可能在将来的页面中使用的资源使用 prefetch。
注意:用 preload 和 prefetch 情况下,如果资源不能被缓存,那么都有可能浪费一部分带宽,请慎用。非首页的资源建议不用 preload,prefetch 作为加载下一屏数据来用。
dns-prefetch 和 preconnect
dns-prefetch
DNS 请求需要的带宽非常小,但延迟较高,这点特别是在手机网络上比较明显。预读取 DNS 能让延迟明显减少一些(尤其是移动网络下)。为了帮助浏览器对某些域名进行预解析,你可以在页面的html标签中添加 dns-prefetch 告诉浏览器对指定域名预解析。
dns-prefetch 是一项使浏览器主动去执行域名解析的功能。dns-prefetch 应该尽量的放在网页的前面,推荐放在后面。具体使用方法如下:
<link>复制代码
洗车项目中有体现:
注意:dns-prefetch需慎用,推荐首屏加载资源添加DNS Prefetch
preconnect
和 DNS prefetch 类似,preconnect 不仅会解析 DNS,还会建立 TCP 握手连接和 TLS 协议(如果是https的话)。用法如下:
preconnect
允许浏览器在 HTTP 请求实际发送到服务器之前建立早期连接。可以预先启动 DNS 查找、TCP 握手和 TLS 协商等连接,从而消除这些连接的往返延迟并为用户节省时间。
<link>复制代码
骨架屏
从图上可以看出有白屏情况,FCP 时间超过了 1秒多,解决下来就用了骨架屏来解决白屏情况 并提升 FCP。
骨架屏
就是在页面资源尚未加载完成以及渲染尚未完成时,需要先给用户的展示页面大致结构。直到资源加载完成以及渲染完成后,使用渲染的页面。骨架屏处理方案也很多,常用方案有以下几种:
- 首屏:可以在
index.html
模版中手写骨架屏相关代码。 - 其他页面:可以利用UI提供SVG图
- 作为SPA中路由切换的loading:需自己编写骨架屏,推荐两个成熟方便定制的svg组件去定制骨架屏- react-content-loader和vue-content-loader。
- 骨架图渲染前不要出现任何网络请求,在此之前 HTML 内容不要超过 4KB。
我这里采用了固定的骨架屏SVG打包自动注入到模板方式。并产出了基于vite 的自动化注入骨架屏和无阻塞缓存资源文件@auto/vite-plugin-cdn私有插件。
举个?:
資源請求優化
圖片壓縮和webp
圖片是網站效能最佳化需要重點關注的方向。為什麼這麼說呢?來看個圖片:一般 UI 提供的切圖都是未通過壓縮的圖片,所有在開發過程中,我們必須再壓縮一次。如果壓縮後的圖片還是大於 500KB 就要考慮將圖片分割成多張。
目前市面上圖片壓縮比較多,給大家推薦個好用的工具(docsmall)。可批量壓縮各類圖片。
WebP 的優勢體現在它具有更優的影像資料壓縮演算法,在肉眼辨識無差異的影像品質情況下帶來較小的圖片體積的優勢;同時具備了無損和有損的壓縮模式、Alpha 透明以及動畫的特性,在JPEG 和PNG 上的轉換效果都相當優秀、穩定且統一。內部提供了圖片資源可以上傳到前端加速服務 或前端靜態資源服務內部資源庫會自動產生webp格式,可以在專案打包的時候處理圖片時加上format= webp 即可,介面動態圖片可採用 @auto/img-crop私有套件做裁切同時也可透過參數動態支援webp和設定快取時間。
webp前後對比:從對比結果來看,同圖採用webp 大小至少減少了 50%,越大的圖優化比例越大。大幅減少了檔案體積,縮短了載入的時間,大頁面圖片量較多的場景下,頁面的渲染速度是有較大提升的。
CDN & 快取
上面提到了前端加速服務 或 前端靜態資源服務內部服務皆整合CDN功能。具體情況可以參考使用文件。
結合以上兩個服務的應用能很好的處理資源問題,目前我們的新 SPA專案都發佈到了前端加速服務上。如圖:資源檔案自動都有快取
未覆蓋的CDN


#從圖上看左圖沒命中緩存,右圖則命中緩存,很多項目由於網域名稱介面和網頁介面一樣CDN 就是沒開啟緩存,我們後透過網域Path 來針對開啟CDN快取。
打包資源最佳化
提取第三方函式庫
#通常情況下,大多第三方函式庫的程式碼不做版本升級是不會改變的,這時就可以用到DllPlugin:把復用性較高的第三方函式庫打包在一起,不升級就不需要重新打包。
這樣做的優點:
- 提取的第三方库生成的资源版本号(资源的访问连接)不会变,提高了缓存的利用;
- 避免打包出单个文件的大小太大,不利于加载;
- 每次构建只重新打包业务代码,提高打包效率。
为了让前端页面性能更优, App WebView 中针对 React
、Vue
、Zepto
三大常用框架相关资源及 Polyfill
进行了预加载处理,所以我们把这些固定的资源调整为无阻塞的预加载地址。具体如何使用 App H5提供了 webpack的相关配置说明。
这里针对 vite 的配置做些说明:
import { defineConfig, loadEnv } from 'vite'; import react from '@vitejs/plugin-react'; import legacy from '@vitejs/plugin-legacy'; import createExternal from 'rollup-plugin-external-globals'; import cdn from '@auto/vite-plugin-cdn'; export default ({ mode }) => { process.env = { ...process.env, ...loadEnv(mode, process.cwd()) }; const { VITE_USER_NODE_ENV = 'mock' } = process.env; const plugins: Array<any> = []; const isProduction = process.env.NODE_ENV === 'production'; if (isProduction) { // 设置预加载的 react 等包为 external plugins.push( createExternal({ react: 'React', 'react-dom': 'ReactDOM', history: 'HistoryLibrary', 'react-router': 'ReactRouter', 'react-router-dom': 'ReactRouterDOM', immer: 'immer', axios: 'axios', 'js-cookie': 'Cookies', }), ); plugins.push( cdn({ enableModule: true, }), ); } // https://vitejs.dev/config/ return defineConfig({ legacy({ targets: ['> 0.05%', 'not dead', 'not op_mini all'], }), ...plugins, ], build: { rollupOptions: { external: [ 'react', 'react-dom', 'history', 'react-router', 'react-router-dom', 'axios', 'js-cookie', ], }, }, }); };
这里@auto/vite-plugin-cdn私有插件中提供正常骨架屏、预加载资源、处理资源加载顺序
示例:
优化打包资源
我们来看一组图:


从图上看优化前后,文件数从295 个减少到 214 个, 大小从 1.63MB 减少到439.88KB,大小降了73.6460%
webpack 和 vite 配置
设置预警来检验打包文件
资源(asset)是从 webpack 生成的任何文件。此选项根据单个资源体积(单位: bytes),控制 webpack 何时生成 性能提示。 用法:
// webpack 设置单个静态资源文件的大小最大超过300KB则会给出警告 module.exports = { //... performance: { maxAssetSize: 1024 * 300 } };
// vite 设置 build: { chunkSizeWarningLimit: 300 // 块大小警告的限制(以 kbs 为单位)默认 500 }
将打包后的静态资源控制在 300KB 以内,最终通过 Gzip 压缩后,基本都在 100KB 以内。其他的优化包括提取第三方库、移除调试和无用代码、Tree Shaking 等。
总结
经过以上的一系列的优化实施,我们来看一下优化前后数据的对比:从2月底开始实施优化,上图可以很明显看出数据的变化,秒开率虽然已经做到了95%以上,达到 98%的只有个别项目,还需要在迭代过程中关注性能以及持续的优化,这里也感谢为H5页面秒开做出贡献的同学。如有什么问题和想法欢迎留言区评论交流。
如果你读完了也不妨点个赞哟,万分感谢!
以上是重點介紹H5頁面秒開優化與實踐的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

Django:前端和後端開發都能搞定的神奇框架! Django是一個高效、可擴展的網路應用程式框架。它能夠支援多種Web開發模式,包括MVC和MTV,可以輕鬆地開發出高品質的Web應用程式。 Django不僅支援後端開發,還能夠快速建構出前端的介面,透過模板語言,實現靈活的視圖展示。 Django把前端開發和後端開發融合成了一種無縫的整合,讓開發人員不必專門學習
