前言
其實(shí)我們常用APP的人鞠值,對于一個(gè)頁面是原生APP還是hybird APP媚创,我們往往一眼就能看出來誰是網(wǎng)頁質(zhì)感、手感齿诉,誰是原生質(zhì)感筝野、手感,但是真讓你說兩者差別在哪里粤剧,你可能又一時(shí)說不出歇竟。今天我就試著討論一下這個(gè)問題。
下文主要對比討論網(wǎng)頁和原生的區(qū)別抵恋,而且焕议,下文中我所謂的網(wǎng)頁,是假定沒有優(yōu)化的弧关、做的非常弱雞的盅安、前后端分離且JS渲染的網(wǎng)頁唤锉,顯然,uni-app很容易做出這種網(wǎng)頁别瞭。而我所謂的原生窿祥,是假定優(yōu)化的很棒的原生。只有這樣蝙寨,我們才能最大限度地優(yōu)化網(wǎng)頁晒衩,讓網(wǎng)頁盡量貼近原生體驗(yàn)。
圖片
原生APP的圖片有什么特點(diǎn)墙歪?
懶加載听系,沒有加載成功的時(shí)候,有占位圖案虹菲,或者即便沒有占位圖案靠胜,至少寬高是撐起來的,而網(wǎng)頁會(huì)從一個(gè)小點(diǎn)突然變成一張圖毕源,容器由扁的突然撐高浪漠,尤其是使用了Vue等框架的前提下。
原生的圖片尺寸都是嚴(yán)格規(guī)定的脑豹,會(huì)為不同dpi準(zhǔn)備生成@2郑藏、@3的圖片,而網(wǎng)頁可能由一張非常大的圖片用樣式縮小瘩欺,然后直接用必盖,于是很卡頓。
解決方案
- 一定要給所有圖片設(shè)定寫死的寬高俱饿。
因?yàn)閡niapp為了兼容小程序歌粥,它的<image>組件是有默認(rèn)寬高的,這跟HTML的<img>是2個(gè)概念拍埠,所以失驶,最好給每一張圖片都設(shè)定寫死的寬高(所謂寫死當(dāng)然不是指用px單位,應(yīng)當(dāng)用rpx單位)枣购。
- 關(guān)于圖片實(shí)際大小的問題嬉探。
現(xiàn)在主流手機(jī)的ppi都是3,也就是說棉圈,主流手機(jī)的CSS像素寬度是360像素涩堤,設(shè)備像素寬度是1080像素,因此分瘾,一張全寬的圖片胎围,設(shè)計(jì)它的時(shí)候,它的寬度像素應(yīng)當(dāng)設(shè)為1080像素即可,就是說白魂,uniapp里面750rpx寬度的圖片汽纤,設(shè)計(jì)的時(shí)候按1080像素做,比例是1.44倍福荸,代碼里寫圖片寬度的時(shí)候不要寫1080px蕴坪,而是寫750rpx。
可能美工大人會(huì)說敬锐,不是按照750px寬度設(shè)計(jì)嗎辞嗡?
這特么老黃歷了,五年前的規(guī)矩也該變變了滞造。
- 首屏使用占位圖,也就是骨架屏栋烤。
骨架屏的本質(zhì)就是灰色的背景色谒养,只在首屏使用即可,也沒必要使用第三方組件庫明郭,自己調(diào)一調(diào)就出來了买窟。
- 預(yù)加載后一頁的首屏數(shù)據(jù)和圖片。
除了骨架屏薯定,我們還有一種更新的技術(shù)是始绍,前一頁閑時(shí)加載后一頁首屏的數(shù)據(jù)和圖片。當(dāng)圖片有了緩存话侄,當(dāng)然就秒開了亏推。
當(dāng)然,有個(gè)前提是年堆,從統(tǒng)計(jì)后臺(tái)看吞杭,你的用戶有大概率會(huì)進(jìn)入該下級頁面,達(dá)到一定概率值变丧,才值得為該下級頁面做預(yù)加載芽狗,不可能給所有下級頁面都使用預(yù)加載。
- 首屏用菊花圖痒蓬。
一個(gè)頁面有N個(gè)下級頁面童擎,不可能全都提前加載數(shù)據(jù)和圖片,這時(shí)候攻晒,對于不重要的頁面用用菊花圖也無妨顾复。也就是說,開場菊花圖轉(zhuǎn)啊轉(zhuǎn)炎辨,然后ajax首屏數(shù)據(jù)捕透,然后js渲染,然后監(jiān)聽圖片load事件,等一切全搞定乙嘀,才給全頁面執(zhí)行show末购,并開始加載下方的數(shù)據(jù)和圖片。
所以下方的內(nèi)容并不是一進(jìn)頁面就ajax虎谢,而是需要監(jiān)聽全頁面是不是show了盟榴,只當(dāng)show了才開始ajax下方的內(nèi)容。
- 首屏下方圖片使用懶加載婴噩。
首屏下方的圖片不可能用菊花圖擎场,用懶加載即可。那么骨架屏和懶加載的區(qū)別是什么几莽?骨架屏是連圖帶文字全都要做骨架迅办,懶加載只是圖片做即可,效果類似章蚣,都是灰色的底色站欺。關(guān)于懶加載方案,uniapp的<image>的lazy-load屬性支持APP(不支持H5)纤垂,所以APP可以用矾策。
- 使用交錯(cuò)GIF、交錯(cuò)PNG峭沦、漸進(jìn)JPEG贾虽。
交錯(cuò)GIF、交錯(cuò)PNG吼鱼、漸進(jìn)JPEG是一種更先進(jìn)的圖片蓬豁,它們的意思是,圖片顯示不是從上到下一點(diǎn)點(diǎn)展開菇肃,而是盡快充滿全部面積庆尘,然后慢慢由不清晰漸變到清晰。作圖工具都能制作這種圖片巷送,就看你覺得值不值得費(fèi)這個(gè)力氣了驶忌。
- 解決uniapp做的APP會(huì)閃爍的問題。
當(dāng)頁面結(jié)構(gòu)復(fù)雜笑跛,css樣式太多的情況付魔,使用<image>可能導(dǎo)致樣式生效較慢,出現(xiàn) “閃一下” 的情況飞蹂,此時(shí)全局設(shè)置image{will-change: transform}
可優(yōu)化此問題几苍。
到此,對于圖片的處理就非常接近原生了陈哑。
容器
原生APP的容器有什么特點(diǎn)妻坝?
跟圖片一樣伸眶,APP的容器也是默認(rèn)撐起高度的,而弱雞網(wǎng)頁的容器可能在打開的瞬間是無高度的刽宪,因?yàn)闆]內(nèi)容厘贼,等ajax到內(nèi)容后才忽然撐起高度。
APP的列表是惰性渲染的圣拄,只有接近展現(xiàn)的時(shí)候才會(huì)渲染嘴秸,滾動(dòng)也相當(dāng)絲滑,而弱雞網(wǎng)頁沒有這種優(yōu)化庇谆。
真1像素發(fā)絲線岳掐。
原生通常是首頁、無限加載的列表沒有滾動(dòng)條饭耳,正文有滾動(dòng)條串述,而弱雞網(wǎng)頁一律有滾動(dòng)條,或者是懂得用
::-webkit-scrollbar
隱藏滾動(dòng)條寞肖,然而剖煌,在APP端并不生效。
解決方案
很多方案跟上面相似逝淹。
- 首頁首屏可以采用骨架屏。
骨架屏可以做到提前撐起容器高度桶唐。
- 首頁首屏也可以采用菊花圖栅葡。
也可以放棄撐起高度這個(gè)念頭,直接先白屏+菊花圖尤泽,然后一瞬間呈現(xiàn)全渲染好的容器欣簇。
首頁下方骨架屏和菊花圖都可以,根據(jù)場景定坯约。
列表建議使用.nvue熊咽。
對于無限滾動(dòng)的列表,或者數(shù)量超過50個(gè)的列表闹丐,就建議用.nvue横殴,且使用list組件(https://uniapp.dcloud.io/component/list)甚至使用recycle-list組件(https://uniapp.dcloud.io/component/recycle-list)。
- 對于參差瀑布流建議使用.nvue卿拴。
應(yīng)使用waterfall組件(https://uniapp.dcloud.io/component/waterfall)衫仑。
- 真1像素發(fā)絲線。
當(dāng)然要實(shí)現(xiàn)堕花,這是起碼的。方案就不說了,可以上網(wǎng)搜索尚辑。
- 隱藏滾動(dòng)條员串。
微信小程序給出的解決方案是使用<scroll-view>呻粹、開啟enhanced
,關(guān)閉show-scrollbar
苏研,但是在APP上無效等浊。APP上應(yīng)該是使用.nvue + <scroll-view>,即:
<scroll-view :show-scrollbar="false" scroll-y>
由此也可知楣富,.nvue是必須學(xué)的凿掂,而且在各種首頁上必須使用。
手勢
原生APP的手勢有什么特點(diǎn)纹蝴?
什么是手勢庄萎?就是手指拉出浮層、拉走浮層等等塘安。比如新聞APP糠涛,文章下面有評論框,默認(rèn)是一行高度兼犯,點(diǎn)擊它忍捡,會(huì)浮出浮層,往下一劃切黔,就收起浮層砸脊。
除此之外,還有觸底刷新纬霞、下拉刷新等等凌埂。
H5網(wǎng)頁開發(fā)一般不會(huì)考慮手勢,怎么接近這種原生體驗(yàn)?zāi)兀?/p>
解決方案
- 拉出诗芜、拉走浮層瞳抓。
uni-app并沒有更高級的手勢封裝,只能使用原始的@touchstart伏恐、@touchmove孩哑、@touchend,好在玩法并不難翠桦,隨便舉個(gè)例子:
<view class="somearea" @touchstart="start" @touchend="end">
</view>
let startData = { clientX: null, clientY: null }
export default {
methods: {
start(e) {
startData.clientX = e.changedTouches[0].clientX;
startData.clientY = e.changedTouches[0].clientY;
},
end(e) {
const subX = e.changedTouches[0].clientX - startData.clientX;
const subY = e.changedTouches[0].clientY - startData.clientY;
if (subY > 50 || subY < -50) {
console.log("上下滑");
} else {
if (subX > 100) {
console.log("右滑");
} else if (subX < -100) {
console.log("左滑");
} else {
console.log("無效");
}
}
},
},
};
接著就是添加動(dòng)效横蜒。
- 觸底刷新、下拉刷新销凑。
uni-app自帶愁铺,能用一定要用,如果追求與眾不同的觸底刷新和下拉刷新闻鉴,一定要使用nvue的refresh組件(https://uniapp.dcloud.io/component/refresh)茵乱。
動(dòng)效
原生APP的動(dòng)效有什么特點(diǎn)?
原生的動(dòng)效特點(diǎn)是——至少原生還有點(diǎn)動(dòng)效孟岛,能給人一種高級感瓶竭,而網(wǎng)頁就是那么干巴巴的督勺,屁動(dòng)效都木有。
解決方案
解決方案就是拒絕干巴巴咯斤贰。這就需要?jiǎng)?chuàng)意了智哀,比如淘寶網(wǎng),隨便點(diǎn)開一張商品縮略圖荧恍,你看到的不僅僅是圖片放大瓷叫,還有變大的動(dòng)效,另外圖片周圍會(huì)有一些文字有入場效果送巡。當(dāng)增加了新功能摹菠,或者打算主推一個(gè)功能的時(shí)候,如果怕用戶無法發(fā)現(xiàn)新功能的入口骗爆,就可以給按鈕加個(gè)流光溢彩效果次氨。等等等等。
這個(gè)話題就不展開說了摘投,特效該抄襲就抄襲煮寡,沒啥不好意思。
組件
原生APP的組件有什么特點(diǎn)犀呼?
原生APP的組件肯定有自己獨(dú)特的外觀和操作體驗(yàn)幸撕,而uni-app的組件跟微信小程序一個(gè)樣,讓人有一種感覺就是好似在用微信小程序外臂,這肯定是不行的坐儿,就比如Toast,微信小程序的成功Toast是一個(gè)對勾专钉,而你的APP的對勾跟小程序一模一樣,會(huì)讓人以為你這個(gè)APP跟騰訊有一腿累铅。
解決方案
要么自己寫組件跃须,那么使用第三方組件庫。
總結(jié)
經(jīng)過這樣一番折騰娃兽,不信你的APP不像原生菇民!