Résumé : L’automatisation de certaines tâches et traitements d’information grâce aux outils numériques permet de réaliser des économies considérables sur nos activités. Le Web est une plateforme propice à la mise en place de tels outils : ceux-ci sont hébergés par des serveurs, qui centralisent les informations et coordonnent les utilisateurs, et ces derniers accèdent aux outils depuis leurs terminaux clients (ordinateur, téléphone, tablette, etc.) en utilisant un navigateur Web, sans étape d’installation. La réalisation de ces applications Web présente des difficultés pour les développeurs. La principale difficulté vient de la distance entre les postes client et serveur.D’une part, la distance physique (ou distance matérielle) entre les machines nécessite qu’une connexion réseau soit toujours établie entre elles pour que l’application fonctionne correctement. Cela pose plusieurs problèmes : comment gérer les problèmes de latence lors des échanges d’information ? Comment assurer une qualité de service même lorsque la connexion réseau est interrompue ? Comment choisir quelle part de l’application s’exécute sur le client et quelle part s’exécute sur le serveur ? Comment éviter aux développeurs d’avoir à résoudre ces problèmes sans pour autant masquer la nature distribuée des applications Web et au risque de perdre les avantages de ces architectures ?D’autre part, l’environnement d’exécution est différent entre les clients et serveurs, produisant une distance logicielle. En effet, côté client, le programme s’exécute dans un navigateur Web dont l’interface de programmation (API) permet de réagir aux actions de l’utilisateur et de mettre à jour le document affiché. De l’autre côté, c’est un serveur Web qui traite les requêtes des clients selon le protocole HTTP. Certains aspects d’une application Web peuvent être communs aux parties client et serveur, par exemple la construction de morceaux de pages Web, la validation de données saisies dans les formulaires, la navigation ou même certains calculs métier. Cependant, comme les API des environnements client et serveur sont différentes, comment mutualiser ces aspects tout en bénéficiant des mêmes performances d’exécution qu’en utilisant les API natives ? De même, comment conserver la possibilité de tirer parti des spécificités de chaque environnement ?Les travaux de cette thèse ont pour but de raccourcir cette distance, tant logicielle que matérielle, tout en préservant la capacité à tirer parti de cette distance, c’est-à-dire en donnant autant de contrôle aux développeurs.La première contribution concerne la distance matérielle. Nous proposons un modèle d’architecture pour les applications interactives et collaboratives fonctionnant en mode connecté et déconnecté. Notre modèle isole la préoccupation de synchronisation client-serveur, offrant ainsi un modèle de développement plus simple pour les développeurs.La seconde contribution concerne la distance logicielle. Nous nous appuyons sur un mécanisme d’évaluation retardée, permettant à un même programme d’être exécuté côté client ou serveur, pour bâtir des abstractions, offrant un modèle de programmation homogène et haut-niveau, produisant du code tirant parti des spécificités des environnements client et serveur. Nous avons observé que la taille du code écrit avec nos outils est du même ordre de grandeur que celle d’un code utilisant des bibliothèques haut-niveau existantes et 35% à 50% plus petite que celle d’un code bas-niveau, mais les performances d’exécution sont du même ordre de grandeur que celles d’un code bas-niveau et 39% à 972% meilleurs qu’un code haut-niveau.Une troisième contribution s’adresse aux adeptes du typage statique. En effet l’API du navigateur est conçue pour un langage dynamiquement typé, JavaScript, et certaines de ses fonctions peuvent être difficiles à exposer dans un langage statiquement typé. En effet, les solutions actuelles perdent en général de l’information, contraignant les développeurs à effectuer des conversions de type contournant le système de typage, ou proposent des fonctions avec un pouvoir d’expression réduit. Nous proposons deux façons d’exposer ces fonctions dans des langages statiquement typés, en nous appuyant respectivement sur les types paramétrés ou les types dépendants. Notre approche, tout en étant bien typée, permet de réduire le nombre de fonctions exposées aux développeurs tout en conservant le même pouvoir d’expression que l’API native.