如何讓uni-app APP看起來(lái)更像原生?

前言

其實(shí)我們常用APP的人,對(duì)于一個(gè)頁(yè)面是原生APP還是hybird APP,我們往往一眼就能看出來(lái)誰(shuí)是網(wǎng)頁(yè)質(zhì)感、手感,誰(shuí)是原生質(zhì)感、手感,但是真讓你說(shuō)兩者差別在哪里,你可能又一時(shí)說(shuō)不出。今天我就試著討論一下這個(gè)問(wèn)題。

下文主要對(duì)比討論網(wǎng)頁(yè)和原生的區(qū)別,而且,下文中我所謂的網(wǎng)頁(yè),是假定沒(méi)有優(yōu)化的、做的非常弱雞的、前后端分離且JS渲染的網(wǎng)頁(yè),顯然,uni-app很容易做出這種網(wǎng)頁(yè)。而我所謂的原生,是假定優(yōu)化的很棒的原生。只有這樣,我們才能最大限度地優(yōu)化網(wǎng)頁(yè),讓網(wǎng)頁(yè)盡量貼近原生體驗(yàn)。

圖片

原生APP的圖片有什么特點(diǎn)?

  1. 懶加載,沒(méi)有加載成功的時(shí)候,有占位圖案,或者即便沒(méi)有占位圖案,至少寬高是撐起來(lái)的,而網(wǎng)頁(yè)會(huì)從一個(gè)小點(diǎn)突然變成一張圖,容器由扁的突然撐高,尤其是使用了Vue等框架的前提下。

  2. 原生的圖片尺寸都是嚴(yán)格規(guī)定的,會(huì)為不同dpi準(zhǔn)備生成@2、@3的圖片,而網(wǎng)頁(yè)可能由一張非常大的圖片用樣式縮小,然后直接用,于是很卡頓。

解決方案

  1. 一定要給所有圖片設(shè)定寫死的寬高。

因?yàn)閡niapp為了兼容小程序,它的<image>組件是有默認(rèn)寬高的,這跟HTML的<img>是2個(gè)概念,所以,最好給每一張圖片都設(shè)定寫死的寬高(所謂寫死當(dāng)然不是指用px單位,應(yīng)當(dāng)用rpx單位)。

  1. 關(guān)于圖片實(shí)際大小的問(wèn)題。

現(xiàn)在主流手機(jī)的ppi都是3,也就是說(shuō),主流手機(jī)的CSS像素寬度是360像素,設(shè)備像素寬度是1080像素,因此,一張全寬的圖片,設(shè)計(jì)它的時(shí)候,它的寬度像素應(yīng)當(dāng)設(shè)為1080像素即可,就是說(shuō),uniapp里面750rpx寬度的圖片,設(shè)計(jì)的時(shí)候按1080像素做,比例是1.44倍,代碼里寫圖片寬度的時(shí)候不要寫1080px,而是寫750rpx。

可能美工大人會(huì)說(shuō),不是按照750px寬度設(shè)計(jì)嗎?

這特么老黃歷了,五年前的規(guī)矩也該變變了。

  1. 首屏使用占位圖,也就是骨架屏。

骨架屏的本質(zhì)就是灰色的背景色,只在首屏使用即可,也沒(méi)必要使用第三方組件庫(kù),自己調(diào)一調(diào)就出來(lái)了。

  1. 預(yù)加載后一頁(yè)的首屏數(shù)據(jù)和圖片。

除了骨架屏,我們還有一種更新的技術(shù)是,前一頁(yè)閑時(shí)加載后一頁(yè)首屏的數(shù)據(jù)和圖片。當(dāng)圖片有了緩存,當(dāng)然就秒開(kāi)了。

當(dāng)然,有個(gè)前提是,從統(tǒng)計(jì)后臺(tái)看,你的用戶有大概率會(huì)進(jìn)入該下級(jí)頁(yè)面,達(dá)到一定概率值,才值得為該下級(jí)頁(yè)面做預(yù)加載,不可能給所有下級(jí)頁(yè)面都使用預(yù)加載。

  1. 首屏用菊花圖。

一個(gè)頁(yè)面有N個(gè)下級(jí)頁(yè)面,不可能全都提前加載數(shù)據(jù)和圖片,這時(shí)候,對(duì)于不重要的頁(yè)面用用菊花圖也無(wú)妨。也就是說(shuō),開(kāi)場(chǎng)菊花圖轉(zhuǎn)啊轉(zhuǎn),然后ajax首屏數(shù)據(jù),然后js渲染,然后監(jiān)聽(tīng)圖片load事件,等一切全搞定,才給全頁(yè)面執(zhí)行show,并開(kāi)始加載下方的數(shù)據(jù)和圖片。

所以下方的內(nèi)容并不是一進(jìn)頁(yè)面就ajax,而是需要監(jiān)聽(tīng)全頁(yè)面是不是show了,只當(dāng)show了才開(kāi)始ajax下方的內(nèi)容。

  1. 首屏下方圖片使用懶加載。

首屏下方的圖片不可能用菊花圖,用懶加載即可。那么骨架屏和懶加載的區(qū)別是什么?骨架屏是連圖帶文字全都要做骨架,懶加載只是圖片做即可,效果類似,都是灰色的底色。關(guān)于懶加載方案,uniapp的<image>的lazy-load屬性支持APP(不支持H5),所以APP可以用。

  1. 使用交錯(cuò)GIF、交錯(cuò)PNG、漸進(jìn)JPEG。

交錯(cuò)GIF、交錯(cuò)PNG、漸進(jìn)JPEG是一種更先進(jìn)的圖片,它們的意思是,圖片顯示不是從上到下一點(diǎn)點(diǎn)展開(kāi),而是盡快充滿全部面積,然后慢慢由不清晰漸變到清晰。作圖工具都能制作這種圖片,就看你覺(jué)得值不值得費(fèi)這個(gè)力氣了。

  1. 解決uniapp做的APP會(huì)閃爍的問(wèn)題。

當(dāng)頁(yè)面結(jié)構(gòu)復(fù)雜,css樣式太多的情況,使用<image>可能導(dǎo)致樣式生效較慢,出現(xiàn) “閃一下” 的情況,此時(shí)全局設(shè)置image{will-change: transform}可優(yōu)化此問(wèn)題。

到此,對(duì)于圖片的處理就非常接近原生了。

容器

原生APP的容器有什么特點(diǎn)?

  1. 跟圖片一樣,APP的容器也是默認(rèn)撐起高度的,而弱雞網(wǎng)頁(yè)的容器可能在打開(kāi)的瞬間是無(wú)高度的,因?yàn)闆](méi)內(nèi)容,等ajax到內(nèi)容后才忽然撐起高度。

  2. APP的列表是惰性渲染的,只有接近展現(xiàn)的時(shí)候才會(huì)渲染,滾動(dòng)也相當(dāng)絲滑,而弱雞網(wǎng)頁(yè)沒(méi)有這種優(yōu)化。

  3. 真1像素發(fā)絲線。

  4. 原生通常是首頁(yè)、無(wú)限加載的列表沒(méi)有滾動(dòng)條,正文有滾動(dòng)條,而弱雞網(wǎng)頁(yè)一律有滾動(dòng)條,或者是懂得用::-webkit-scrollbar隱藏滾動(dòng)條,然而,在APP端并不生效。

解決方案

很多方案跟上面相似。

  1. 首頁(yè)首屏可以采用骨架屏。

骨架屏可以做到提前撐起容器高度。

  1. 首頁(yè)首屏也可以采用菊花圖。

也可以放棄撐起高度這個(gè)念頭,直接先白屏+菊花圖,然后一瞬間呈現(xiàn)全渲染好的容器。

  1. 首頁(yè)下方骨架屏和菊花圖都可以,根據(jù)場(chǎng)景定。

  2. 列表建議使用.nvue。

對(duì)于無(wú)限滾動(dòng)的列表,或者數(shù)量超過(guò)50個(gè)的列表,就建議用.nvue,且使用list組件(https://uniapp.dcloud.io/component/list)甚至使用recycle-list組件(https://uniapp.dcloud.io/component/recycle-list)。

  1. 對(duì)于參差瀑布流建議使用.nvue。

應(yīng)使用waterfall組件(https://uniapp.dcloud.io/component/waterfall)。

  1. 真1像素發(fā)絲線。

當(dāng)然要實(shí)現(xiàn),這是起碼的。方案就不說(shuō)了,可以上網(wǎng)搜索。

  1. 隱藏滾動(dòng)條。

微信小程序給出的解決方案是使用<scroll-view>、開(kāi)啟enhanced,關(guān)閉show-scrollbar,但是在APP上無(wú)效。APP上應(yīng)該是使用.nvue + <scroll-view>,即:

<scroll-view :show-scrollbar="false" scroll-y>

由此也可知,.nvue是必須學(xué)的,而且在各種首頁(yè)上必須使用。

手勢(shì)

原生APP的手勢(shì)有什么特點(diǎn)?

什么是手勢(shì)?就是手指拉出浮層、拉走浮層等等。比如新聞APP,文章下面有評(píng)論框,默認(rèn)是一行高度,點(diǎn)擊它,會(huì)浮出浮層,往下一劃,就收起浮層。

除此之外,還有觸底刷新、下拉刷新等等。

H5網(wǎng)頁(yè)開(kāi)發(fā)一般不會(huì)考慮手勢(shì),怎么接近這種原生體驗(yàn)?zāi)兀?/p>

解決方案

  1. 拉出、拉走浮層。

uni-app并沒(méi)有更高級(jí)的手勢(shì)封裝,只能使用原始的@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("無(wú)效");
        }
      }
    },
  },
};

接著就是添加動(dòng)效。

  1. 觸底刷新、下拉刷新。

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)效,能給人一種高級(jí)感,而網(wǎng)頁(yè)就是那么干巴巴的,屁動(dòng)效都木有。

解決方案

解決方案就是拒絕干巴巴咯。這就需要?jiǎng)?chuàng)意了,比如淘寶網(wǎng),隨便點(diǎn)開(kāi)一張商品縮略圖,你看到的不僅僅是圖片放大,還有變大的動(dòng)效,另外圖片周圍會(huì)有一些文字有入場(chǎng)效果。當(dāng)增加了新功能,或者打算主推一個(gè)功能的時(shí)候,如果怕用戶無(wú)法發(fā)現(xiàn)新功能的入口,就可以給按鈕加個(gè)流光溢彩效果。等等等等。

這個(gè)話題就不展開(kāi)說(shuō)了,特效該抄襲就抄襲,沒(méi)啥不好意思。

組件

原生APP的組件有什么特點(diǎn)?

原生APP的組件肯定有自己獨(dú)特的外觀和操作體驗(yàn),而uni-app的組件跟微信小程序一個(gè)樣,讓人有一種感覺(jué)就是好似在用微信小程序,這肯定是不行的,就比如Toast,微信小程序的成功Toast是一個(gè)對(duì)勾,而你的APP的對(duì)勾跟小程序一模一樣,會(huì)讓人以為你這個(gè)APP跟騰訊有一腿。

解決方案

要么自己寫組件,那么使用第三方組件庫(kù)。

總結(jié)

經(jīng)過(guò)這樣一番折騰,不信你的APP不像原生!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容