Статистика платформи після хвилі 19
Ретроспектива хвилі 19
Хвиля 19 досліджувала фізику всесвіту в найбільших масштабах і найкоротших часових проміжках. Спотлайт #38 простежив інфляційну космологію через акустичні піки реліктового випромінювання до N-тільних симуляцій темної матерії й нових обмежень DESI BAO. Навчальний #29 побудував загальну теорію відносності від рівняння геодезичної лінії до чорних дір Керра, гравітаційних хвиль та парадоксу інформації. Спотлайт #39 глибоко занурився у фізичну хімію — теорію перехідного стану Айрінга, електронний перенос Маркуса, теорію функціонала густини (DFT) та фемтосекундну спектроскопію хвильових пакетів.
Космологія та темна матерія: реліктове випромінювання, інфляція, N-тільні симуляції та великомасштабна структура
Загальна теорія відносності та викривлений простір-час: від принципу еквівалентності до чорних дір
Фізична хімія та динаміка реакцій: перехідні стани, теорія Маркуса, спектроскопія та фемтохімія
Повністю офлайн-орієнтований PWA
Service worker хвилі 18 попередньо кешував усі 75 сторінок категорій, але не 345 окремих сторінок симуляцій. Хвиля 19 розширює список попереднього кешування на кореневий HTML кожної симуляції, надаючи відвідувачам повну бібліотеку симуляцій офлайн після першого візиту. Загальний обсяг попереднього кешу — близько 12 МБ HTML, CSS і JS (без урахування текстур WebGL і Three.js, які надто великі, щоб кешувати їх безумовно).
Service Worker v19 — стратегія попереднього кешування
// sw.js key changes in v19 // 1. Build-time manifest from directory listing (Node script) const SIM_PRECACHE = [ '/acid-base/', '/adc-dac/', '/aerofoil/', ... (345 entries) ].map(path => ({ url: path, revision: BUILD_HASH })); // 2. Quota-aware cache installation async function installWithQuotaCheck(cacheName, urls) { const estimate = await navigator.storage.estimate(); const availableMB = (estimate.quota - estimate.usage) / 1e6; if (availableMB < 50) { console.warn('[SW] Low storage, skipping sim precache'); return; } const cache = await caches.open(cacheName); // Batch in groups of 20 to avoid overwhelming fetch pipeline for (let i = 0; i < urls.length; i += 20) { await cache.addAll(urls.slice(i, i + 20)); } } // 3. CacheFirst for simulation pages (long cache lifetime) registerRoute( ({ url }) => SIMS.some(s => url.pathname.startsWith(s)), new CacheFirst({ cacheName: 'sims-v19', plugins: [ new ExpirationPlugin({ maxEntries: 400, maxAgeSeconds: 60 * 60 * 24 * 30 }), new CacheableResponsePlugin({ statuses: [200] }) ]}) ); // 4. NetworkFirst for blog posts (always fresh when online) registerRoute( ({ url }) => url.pathname.startsWith('/blog/'), new NetworkFirst({ cacheName: 'blog-v19', networkTimeoutSeconds: 3, plugins: [ new ExpirationPlugin({ maxAgeSeconds: 86400 }) ] }) ); // 5. Offline fallback setCatchHandler(async ({ request }) => { if (request.destination === 'document') return caches.match('/offline.html'); return Response.error(); });
Внутрішньосторінкова пропозиція встановлення тепер з'являється
після третього відвідування симуляції користувачем через подію
beforeinstallprompt. Інтерфейс показує банер, який
можна закрити, з приблизною кількістю сеансів та описом переваг
офлайн-режиму. Попередні дані (змодельовані): 6% встановлень на
мобільних, 2% на десктопі.
Підсвітка результатів пошуку
Нечіткий пошук, представлений у хвилі 18, повертав ранжовані
результати симуляцій, але показував їх без жодної візуальної
вказівки на те, де саме збігся запит. Хвиля 19 додає
підсвітку термінів: збіжні слова й часткові n-грами обгортаються
в елементи <mark> із бурштиновим фоном, а
комбінації клавіш F3/Shift+F3 циклічно перемикають підсвічені
збіги у списку результатів.
Власний DOM-Range підсвічувач (без бібліотек)
// highlight.js — ~60 lines, no external dependency function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } export function highlightTerms(container, terms) { // Walk all text nodes under container const iter = document.createNodeIterator(container, NodeFilter.SHOW_TEXT); const nodes = []; let n; while ((n = iter.nextNode())) nodes.push(n); const pattern = new RegExp( `(${terms.map(escapeRe).join('|')})`, 'gi' ); nodes.forEach(textNode => { const text = textNode.nodeValue; if (!pattern.test(text)) return; pattern.lastIndex = 0; const frag = document.createDocumentFragment(); let last = 0, match; while ((match = pattern.exec(text)) !== null) { if (match.index > last) frag.appendChild(document.createTextNode(text.slice(last, match.index))); const mark = document.createElement('mark'); mark.textContent = match[0]; mark.style.cssText = 'background:#fbbf24;color: var(--color-text);border-radius:2px;padding:0 1px'; frag.appendChild(mark); last = pattern.lastIndex; } if (last < text.length) frag.appendChild(document.createTextNode(text.slice(last))); textNode.parentNode.replaceChild(frag, textNode); }); } // Keyboard navigation through marks let markIdx = -1; document.addEventListener('keydown', e => { const isF3 = e.key === 'F3' || (e.ctrlKey && e.key === 'g'); if (!isF3) return; e.preventDefault(); const marks = [...document.querySelectorAll('#results mark')]; if (!marks.length) return; markIdx = (markIdx + (e.shiftKey ? -1 : 1) + marks.length) % marks.length; marks[markIdx].scrollIntoView({ behavior: 'smooth', block: 'center' }); marks.forEach((m, i) => m.style.outline = i === markIdx ? '2px solid #ff7043' : ''); });
Підсвічувач застосовується до полів назви, категорії й опису симуляції в кожній картці результату, використовуючи токенізовані терміни запиту з нечіткого пошукового рушія. Триграмні збіги з косинусною подібністю нижче 0,6 виключаються з підсвітки, щоб уникнути підсвічування майже випадкових збігів символів.
Аудит структурованих даних JSON-LD
Google Rich Results Test виявив, що 47 симуляціям бракує
обов'язкових властивостей схеми. Хвиля 19 додає три відсутні
поля до блоку JSON-LD кожної симуляції:
educationalLevel (середня школа/бакалаврат/аспірантура),
teaches (масив навчальних цілей з опису симуляції) і
learningResourceType (завжди
"simulation" згідно з термінологією schema.org).
Шаблон збагачення JSON-LD (для кожної симуляції)
- "@type": "WebApplication", - "name": "Acid-Base Equilibrium", - "description": "Interactive acid-base simulation..." + "@type": ["WebApplication", "LearningResource"], + "name": "Acid-Base Equilibrium", + "description": "Interactive acid-base simulation...", + "educationalLevel": "undergraduate", + "teaches": [ + "pH calculation", + "Henderson-Hasselbalch equation", + "buffer chemistry", + "titration curves" + ], + "learningResourceType": "simulation", + "interactivityType": "active", + "isAccessibleForFree": true
Скрипт аудиту на Node.js читає всі 345 файлів
index.html, витягує наявний JSON-LD, перевіряє його
відповідність термінології schema.org і генерує маніфест
патчів. Перевірка після розгортання через пакетний інспектор
URL-адрес Google Search Console показує 0 помилок і 302
симуляції, придатні для розширених результатів (43 симуляції не
мають значних кандидатів у структуровані дані про навчання й
використовують лише WebApplication).
Інженерний чекліст хвилі 19
- ✓SW v19 попередньо кешує всі 345 кореневих HTML-сторінок симуляцій із захистом за квотою
- ✓Пакетний цикл встановлення (по 20 за раз) запобігає таймауту встановлення Service Worker
- ✓Внутрішньосторінкова пропозиція встановлення PWA з'являється після 3-ї симуляції (mobile-first)
- ✓Власний DOM-range підсвічувач пошуку (без залежності від mark.js, 60 рядків)
- ✓Циклічна навігація клавішами F3/Shift+F3 по підсвічених пошукових термінах
- ✓Скрипт аудиту JSON-LD: перевірено 345 файлів, 302 збагачено educationalLevel/teaches/learningResourceType
- ✓Google Rich Results Test: 0 помилок після розгортання, 302 придатні для розширених фрагментів
- ✓Оцінка PWA в Lighthouse: 100 (порівняно з 96 до хвилі 19)
- ⚠Генерація OG-зображень / відеомініатюр для 50+ симуляцій — перенесено на хвилю 20
Анонс хвилі 20
Імунологія та інфекційні хвороби
Вроджений і набутий імунітет, різноманітність рецепторів Т-клітин, механізми вакцин, колективний імунітет (R₀) та епідемічне моделювання SIR/SEIR.
Статистична теорія поля
Інтеграли по траєкторіях, статистичні суми, ренормалізаційна група моделі Ізінга, класи універсальності та зв'язки між КТП і статистичною механікою.
Геофізика та сейсмологія
Тектоніка плит, поширення сейсмічних P/S-хвиль, нормальні моди коливань Землі, аномалії геоїда та гравітації, а також мантійна конвекція.
Відеомініатюри та OG-зображення
Автоматизований конвеєр знімків на базі Playwright для 50+ OG-зображень симуляцій, прев'ю для соцмереж та генерація відеомініатюр для стрічки блогу.
Хвиля 20 знаменує важливу віху: Навчальний #30 стане 30-м дописом найдовшої освітньої серії на платформі. Статистична теорія поля перебуває на перетині фізики конденсованого стану, квантової гравітації та машинного навчання (машини Больцмана, дифузійні моделі) — об'єднуючи півдюжини інших спотлайт-тем в одному фреймворку.