AccueilClientsExpertisesBlogOpen SourceJobsContact

19 avril 2021

PWA et application mobile avec React Native

6 minutes de lecture

PWA et application mobile avec React Native

Le débat existe depuis l'arrivée des progressive web apps aux alentours de 2015, et persiste encore aujourd'hui, quand est-il préférable de faire une application native ? Que permet réellement une PWA ? Quelles sont les limites de chaque solution ?

Les réponses restent complexes mais nous partageons ici nos recommandations et réponses techniques apportées à nos clients.

Commençons par quelques définitions :

PWA : Une Progressive Web App, c'est avant tout un site web qui peut apparaître à l'utilisateur comme étant une application mobile. Ce site est ainsi composé des mêmes éléments qu'un site "classique", donc du HTML, CSS et JavaScript; cependant il sera spécialement adapté pour le mobile via différentes solutions comme un design responsive (mobile-first), un focus particulier sur les performances ainsi que l'ajout d'un Service worker.

Application native : Une application native est un projet mobile, composé de code "natif", c'est-à-dire Java/Kotlin pour Android ou Objective-C/Swift pour iOS. Pour déployer cette application il est nécessaire de passer par les stores applicatifs, Google Playstore ou App store.

Comparatif

Voyons les spécificités qui pourront nous aider à choisir le type d'application.

Application nativeProgressive Web App
DéveloppementLangages natifs (Java, Objective-C...) ou technologie cross plateforme (React Native)Technologies web (html, js...)
CoûtGénéralement plus complexe techniquement que pour le web et à multiplier par le nombre de plateformes ciblesLe site web est bien souvent à développer quoi qu'il arrive, puis on y ajoute des fonctionnalités dites "PWA"
DisponibilitéLié aux plateformes cibles, un smartphone, un accès au storeUn simple navigateur web, référencement naturel
PerformanceAu plus proche du système donc performance native, le binaire étant déjà chargé, il ne reste qu'à exécuter des requêtes pour récupérer des donnéesSite web à optimiser pour s'assurer de performance correcte sur mobile
DéploiementStore applicatifsHébergement web
Fonctions propresAccès aux données utilisateurs (touch id, face id, achat in app), bluetooth et 3D performante~

Exemple d'implémentation d'une PWA

Instagram implémente la plupart des fonctionnalités possibles avec une PWA, c'est à dire

  • ajout à l'écran d'accueil du téléphone
  • notifications push
  • cache hors ligne

Instagram - Ajout à l'écran d'accueil

Twitter implémente aussi ces fonctionnalités et peut être utilisé complètement en mode web sans nécessiter d'installer l'application mobile.

On constate que malgré les efforts mis en place pour que ces sites marchent parfaitement sur le web sur mobile, l'utilisateur est souvent appelé à installer l'application native pour une meilleure expérience.

Instagram - Utiliser l'application

React Native et le web

Chez Premier Octet nous utilisons principalement React Native pour créer nos applications mobiles. On ne le présente plus, c'est déjà le sujet de nombreux autres articles de notre blog.

React permet une abstraction entre ce que l'on veut afficher (composants) et comment l'afficher (rendu). Que votre application soit une application react native ou web, les composants sont créés via la librairie react. Cependant lors du rendu, nous devons utiliser react-dom ou react-native.

Cette séparation a rendu possible la création d'application native avec React, de partager du code entre une application web et mobile, ou encore d'avoir des abstractions très spécifique pour par exemple rendre de la 3D ou des PDF.

Pour notre cas, cela va nous permettre de créer une application React Native mais de l'exporter pour le web ! Grâce à la librairie react-native-web qui implémenter les composants du SDK native mais pour react-dom, on va pouvoir rendre une application mobile développée avec React Native pour le web.

Ainsi un composant React Native aura un équivalent implémenté pour le web, comme ci-dessous.

React Native

<View>
  <Text>Hello World</Text>
</View>

Web

<div>
  <p>Hello World</p>
</div>

La documentation officielle de React Native utilise maintenant cette technique pour pouvoir afficher des exemples interactifs.

L'utilisation de Expo facilement grandement le paramétrage d'une PWA (voir https://docs.expo.io/guides/progressive-web-apps/), mais il est tout à fait possible de partir d'une application React Native classique pour l'exporter pour le web.

Application démo

Pour l'exemple nous allons créer une application très simple pour consulter l'évolution des dernières cryptos dans les dernières 24h.

Initialisation

Grâce au CLI de Expo nous pouvons initialiser un projet déjà paramétré pour l'export web : expo init expo-web-demo.

Expo start

Et directement l'application peut être compilée pour le web avec les commandes suivantes

cd expo-web-demo
yarn start

Demo expo

On constate bien que l'application React Native utilise des éléments HTML pour se rendre pour le web. De plus, le rendu est identique sur le web et sur l'application Android.

Création de l'interface

Pour des raisons de simplicité nous allons afficher un header, une simple liste et un input pour ajouter une nouvelle monnaie. Habituellement pour nos projets web nous utilisons l'excellente bibliothèque de composants chakra-ui mais elle ne supporte pas React Native, donc nous allons essayer la nouvelle version de Native Base (attention en alpha !) qui possède un support web expérimental officiel.

<NativeBaseProvider>
  <Center flex={1}>
    <Box w="80%" maxWidth="400px">
      <Heading color="emerald.400" m={4}>
        Crypto list
      </Heading>
      <Box flex={1} flexDirection="row" alignItems="center" justifyContent="space-between" p={4}>
        <Image
          source={{
            uri: `https://www.cryptocompare.com/media/37746251/btc.png`,
          }}
          size="8"
        />
        <Box flex={1} flexDirection="row" justifyContent="space-around">
          <Text fontWeight="bold">BTC</Text>
          <Text
            style={{
              color: 'green',
            }}
          >
            10%
          </Text>
        </Box>
        <IconButton style={{ width: 50 }} icon={<Icon name={'remove'} />} onPress={() => {}} />
      </Box>
      <Input
        type="text"
        value={''}
        onChangeText={(text: string) => {}}
        InputRightElement={
          <Button onPress={() => {}} type="submit">
            Add
          </Button>
        }
        placeholder="Add your own"
        mt={4}
      />
    </Box>
  </Center>
</NativeBaseProvider>

Comme vous pouvez le constater cette librairie nous donne des primitives tel que Heading ou encore Box que nous pouvons paramétrer simplement via des props. Il est aussi possible d'étendre le thème pour y définir les couleurs primaires, secondaires, marges, breakpoints...

Récupération de données

Les requêtes d'API se font de la même manière en web qu'en mobile grâce à l'implémentation de React Native qui supporte fetch.

export const getCryptosPrices = async (cryptos: string[]): Promise<ApiResponse> => {
  const response = await fetch(
    `https://min-api.cryptocompare.com/data/pricemultifull?fsyms=${cryptos.join(',')}&tsyms=EUR`
  )
  return response.json()
}

Sauvegarde de la liste en hors ligne

Grâce aux efforts de la communauté, de nombreuses librairies supportent déjà le web, par exemple pour sauvegarder des données sur le système, nous utilisons généralement AsyncStorage.

La librairie peut utiliser l'extension de fichier .native.js pour spécifier une implémentation native et laisser webpack prendre le fichier classique pour le web.

Async storage support web

Avec un hook custom pour persister un état, nous avons ainsi une solution élégante et avec la même implémentation pour le web et le mobile

const [cryptos, setCryptos] = useAsyncStorage('cryptos', ['BTC', 'ETC', 'XRP'])

Déploiement

L'application web étant une simple application React, il est possible de l'héberger sur un hébergement statique comme Github pages.

Lancer la commande suivante pour installer la librairie de déploiement

yarn add -D gh-pages

Configurez le package.json

{
  "homepage": "http://{YOUR_USERNAME}.github.io/{YOUR_GITHUB_REPO}",
  "scripts": {
    "deploy": "gh-pages -d web-build",
    "predeploy": "expo build:web"
  }
}

Lancer le déploiement

yarn deploy

And voilà https://premieroctet.github.io/expo-web-demo/

L'ensemble du code source de cet article est disponible sur ce dépôt https://github.com/premieroctet/expo-web-demo.

Expo et react-native-web permettent donc de développer rapidement une application mobile native et une PWA avec le même code source. Il faut cependant voir l'application web comme un export mobile dans le sens où le plus gros du travail sera de gérer l'affichage desktop, gérer les breakpoints responsive et parfois remplacer des composants qui n'ont pas d'équivalent direct dans une plateforme (select, maps...).

Si vous avez déjà utilisé cet export, n'hésitez pas à nous en faire part sur Twitter !

18 avenue Parmentier
75011 Paris
+33 1 43 57 39 11
hello@premieroctet.com

Suivez nos aventures

GitHub
Twitter
Flux RSS

Naviguez à vue