Lien original : https://i18n.site/blog/tech/search
Séquence
Après plusieurs semaines de développement, i18n.site (un outil de traduction multilingue et de création de sites Web purement statique) prend désormais en charge la recherche frontale en texte intégral pure.
Cet article partagera la mise en œuvre technique de la recherche en texte intégral purement frontale d'i18n.site. Visitez i18n.site pour découvrir la fonctionnalité de recherche.
Le code est open-source : Noyau de recherche / Interface interactive
Un aperçu des solutions de recherche en texte intégral sans serveur
Pour les sites Web purement statiques de petite et moyenne taille tels que les documents/blogs personnels, la création d'un moteur de recherche en texte intégral auto-construit est trop lourde, et la recherche en texte intégral sans service est le choix le plus courant.
Les solutions de recherche en texte intégral sans serveur sont divisées en deux catégories principales :
Le premier implique des fournisseurs de services de recherche tiers comme algolia.com qui proposent des composants frontaux pour la recherche en texte intégral.
Ces services nécessitent un paiement en fonction du volume de recherche et sont souvent indisponibles pour les utilisateurs en Chine continentale en raison de problèmes de conformité.
Ils ne peuvent pas être utilisés hors ligne ou sur intranet et présentent des limitations importantes. Cet article ne sera pas développé davantage.
La deuxième catégorie est la recherche frontale en texte intégral pure.
Actuellement, les outils de recherche en texte intégral front-end courants incluent lunrjs et ElasticLunr.js (un développement secondaire basé sur lunrjs).
lunrjs propose deux méthodes pour créer des index, toutes deux avec leurs propres problèmes.
- Fichiers d'index prédéfinis
Étant donné que l'index comprend tous les mots des documents, il est de grande taille.
Chaque fois qu'un document est ajouté ou modifié, un nouveau fichier d'index doit être chargé.
Cela augmente le temps d'attente des utilisateurs et consomme une quantité importante de bande passante.
- Chargement de documents et création d'index à la volée
La création d'un index est une tâche gourmande en calcul, et sa reconstruction à chaque accès peut entraîner des retards notables, conduisant à une mauvaise expérience utilisateur.
En plus de lunrjs, il existe d'autres solutions de recherche en texte intégral, telles que :
fusejs, qui recherche en calculant la similarité entre les chaînes.
Cette solution a des performances médiocres et n'est pas adaptée à la recherche en texte intégral (voir Fuse.js Une requête longue prend plus de 10 secondes, comment optimiser ?).
TinySearch, qui utilise un filtre Bloom pour la recherche, ne peut pas effectuer de recherches de préfixes (par exemple, saisir goo pour rechercher good ou google) et ne peut pas obtenir un effet de saisie semi-automatique.
En raison des inconvénients des solutions existantes, i18n.site a développé une nouvelle solution de recherche en texte intégral purement frontale avec les fonctionnalités suivantes :
- Prend en charge la recherche multilingue, avec une taille compacte ; le noyau de recherche, lorsqu'il est fourni avec gzip, ne fait que 6,9 Ko (en comparaison, lunrjs fait 25 Ko)
- Construit un index inversé basé sur IndexedDB, avec une faible utilisation de la mémoire et des performances rapides
- Lorsque des documents sont ajoutés/modifiés, seuls les documents ajoutés ou modifiés sont réindexés, réduisant ainsi le nombre de calculs
- Prend en charge la recherche par préfixe, permettant l'affichage en temps réel des résultats de recherche au fur et à mesure que l'utilisateur tape
- Disponibilité hors ligne
Les détails de la mise en œuvre technique d'i18n.site seront présentés ci-dessous.
Segmentation de mots multilingues
La segmentation des mots utilise l'Intel.Segmenter natif du navigateur, qui est pris en charge par tous les navigateurs grand public.
Le code coffeescript pour la segmentation des mots est le suivant :
SEG = new Intl.Segmenter 0, granularity: "word" seg = (txt) => r = [] for {segment} from SEG.segment(txt) for i from segment.split('.') i = i.trim() if i and !'|`'.includes(i) and !/\p{P}/u.test(i) r.push i r export default seg export segqy = (q) => seg q.toLocaleLowerCase()
Où :
-
/p{P}/ est une expression régulière qui correspond aux signes de ponctuation, notamment : ! " # $ % & ' ( ) * , - . / : ; ? @ [ ] ^ _ { | } ~. .
- split('.' )c'est parce que la segmentation des mots du navigateur Firefox ne segmente pas.` .
Construction de l'indice
Cinq tables de stockage d'objets sont créées dans IndexedDB :
- mot : identifiant - mot
- doc : id - URL du document - numéro de version du document
- docWord : identifiant du document - tableau d'identifiants de mots
- préfixe : préfixe - tableau d'identifiants de mots
- rindex : identifiant du mot - identifiant du document - tableau de numéros de ligne
En transmettant un tableau d'URL du document et de numéro de version ver, la table doc est vérifiée pour l'existence du document. S'il n'existe pas, un index inversé est créé. Simultanément, l'index inversé des documents non transmis est supprimé.
Cette méthode permet une indexation incrémentielle, réduisant ainsi la charge de calcul.
In the front-end interface, a progress bar for index loading can be displayed to avoid lag during the initial load. See "Animated Progress Bar, Based on a Single progress + Pure CSS Implementation" English / Chinese.
IndexedDB High Concurrent Writing
The project is developed based on the asynchronous encapsulation of IndexedDB, idb.
IndexedDB reads and writes are asynchronous. When creating an index, documents are loaded concurrently to build the index.
To avoid data loss due to concurrent writes, you can refer to the following coffeescript code, which adds a ing cache between reading and writing to intercept competitive writes.
`coffee
pusher = =>
ing = new Map()
(table, id, val)=>
id_set = ing.get(id)
if id_set
id_set.add val
returnid_set = new Set([val]) ing.set id, id_set pre = await table.get(id) li = pre?.li or [] loop to_add = [...id_set] li.push(...to_add) await table.put({id,li}) for i from to_add id_set.delete i if not id_set.size ing.delete id break return
rindexPush = pusher()
prefixPush = pusher()
`Prefix Real-Time Search
To display search results in real-time as the user types, for example, showing words like words and work that start with wor when wor is entered.
The search kernel uses the prefix table for the last word after segmentation to find all words with that prefix and search sequentially.
An anti-shake function, debounce (implemented as follows), is used in the front-end interaction to reduce the frequency of searches triggered by user input, thus minimizing computational load.
js
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Precision and Recall
The search first segments the keywords entered by the user.
Assuming there are N words after segmentation, the results are first returned with all keywords, followed by results with N-1, N-2, ..., 1 keywords.
The search results displayed first ensure query precision, while subsequent loaded results (click the "Load More" button) ensure recall.
On-Demand Loading
To improve response speed, the search uses the yield generator to implement on-demand loading, returning results after each limit query.
Note that after each yield, a new IndexedDB query transaction must be opened for the next search.
Prefix Real-Time Search
To display search results in real-time as the user types, for example, showing words like words and work that start with wor when wor is entered.
The search kernel uses the prefix table for the last word after segmentation to find all words with that prefix and search sequentially.
An anti-shake function, debounce (implemented as follows), is used in the front-end interaction to reduce the frequency of searches triggered by user input, thus minimizing computational load.
js
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
Offline Availability
The index table does not store the original text, only words, reducing storage space.
Highlighting search results requires reloading the original text, and using service worker can avoid repeated network requests.
Also, because service worker caches all articles, once a search is performed, the entire website, including search functionality, becomes offline available.
Optimization for Displaying MarkDown Documents
The pure front-end search solution provided by i18n.site is optimized for MarkDown documents.
When displaying search results, the chapter name is shown, and clicking navigates to that chapter.
Summary
The pure front-end implementation of inverted full-text search, without the need for a server, is very suitable for small to medium-sized websites such as documents and personal blogs.
i18n.site's open-source self-developed pure front-end search is compact, responsive, and addresses the various shortcomings of current pure front-end full-text search solutions, providing a better user experience.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

L'application de JavaScript dans le monde réel comprend un développement frontal et back-end. 1) Afficher les applications frontales en créant une application de liste TODO, impliquant les opérations DOM et le traitement des événements. 2) Construisez RestulAPI via Node.js et Express pour démontrer les applications back-end.

Les principales utilisations de JavaScript dans le développement Web incluent l'interaction client, la vérification du formulaire et la communication asynchrone. 1) Mise à jour du contenu dynamique et interaction utilisateur via les opérations DOM; 2) La vérification du client est effectuée avant que l'utilisateur ne soumette les données pour améliorer l'expérience utilisateur; 3) La communication de rafraîchissement avec le serveur est réalisée via la technologie AJAX.

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Le passage de C / C à JavaScript nécessite de s'adapter à la frappe dynamique, à la collecte des ordures et à la programmation asynchrone. 1) C / C est un langage dactylographié statiquement qui nécessite une gestion manuelle de la mémoire, tandis que JavaScript est dynamiquement typé et que la collecte des déchets est automatiquement traitée. 2) C / C doit être compilé en code machine, tandis que JavaScript est une langue interprétée. 3) JavaScript introduit des concepts tels que les fermetures, les chaînes de prototypes et la promesse, ce qui améliore la flexibilité et les capacités de programmation asynchrones.

Différents moteurs JavaScript ont des effets différents lors de l'analyse et de l'exécution du code JavaScript, car les principes d'implémentation et les stratégies d'optimisation de chaque moteur diffèrent. 1. Analyse lexicale: convertir le code source en unité lexicale. 2. Analyse de la grammaire: générer un arbre de syntaxe abstrait. 3. Optimisation et compilation: générer du code machine via le compilateur JIT. 4. Exécuter: Exécutez le code machine. Le moteur V8 optimise grâce à une compilation instantanée et à une classe cachée, SpiderMonkey utilise un système d'inférence de type, résultant en différentes performances de performances sur le même code.

Les applications de JavaScript dans le monde réel incluent la programmation côté serveur, le développement des applications mobiles et le contrôle de l'Internet des objets: 1. La programmation côté serveur est réalisée via Node.js, adaptée au traitement de demande élevé simultané. 2. Le développement d'applications mobiles est effectué par le reactnatif et prend en charge le déploiement multiplateforme. 3. Utilisé pour le contrôle des périphériques IoT via la bibliothèque Johnny-Five, adapté à l'interaction matérielle.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

MinGW - GNU minimaliste pour Windows
Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Version crackée d'EditPlus en chinois
Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

Télécharger la version Mac de l'éditeur Atom
L'éditeur open source le plus populaire

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP