Все заметки

Автоматические скриншоты портфолио: вместо iframe — Playwright

Iframe в портфолио тормозит, падает на mobile Safari и крадёт SEO. Заменил на автоматические скриншоты — и портфолио ожило.

Проблема

Портфолио из 8 проектов показывалось через <iframe>. На десктопе выглядело эффектно: ноутбук, внутри живой сайт. Но:

  • Mobile Safari режет часть iframe — блокирует скрипты, убирает скролл.
  • LCP (Largest Contentful Paint) улетал за 4 секунды из-за загрузки 8 сайтов одновременно.
  • Lighthouse performance падал до 60 на мобильной эмуляции.
  • Блокировщики рекламы иногда блокируют чужие домены в iframe.
  • SEO: ссылки внутри iframe не передают вес, краулер не индексирует контент.

Решение

Скрипт автоматически снимает скриншоты всех сайтов портфолио и сохраняет их в public/screenshots/. На главной — статичные <img>, клик ведёт на живой сайт в новой вкладке. Iframe — только на детальной странице кейса (по запросу).

Код скрипта

// scripts/screenshots.mjs
import { chromium } from 'playwright';
import { mkdir } from 'node:fs/promises';

const cases = [
  { slug: 'manifik',       url: 'https://manifik-school.ru' },
  { slug: 'nails',         url: 'https://kb-nails.surge.sh' },
  { slug: 'cosmetologist', url: 'https://kb-cosmetologist.surge.sh' },
  // ...
];

await mkdir('public/screenshots', { recursive: true });

const browser = await chromium.launch();
const ctx = await browser.newContext({
  viewport: { width: 1440, height: 900 },
  deviceScaleFactor: 2,
});

for (const c of cases) {
  const page = await ctx.newPage();
  await page.goto(c.url, { waitUntil: 'networkidle', timeout: 30000 });
  await page.waitForTimeout(1500); // чтобы анимации доиграли
  await page.screenshot({
    path: `public/screenshots/${c.slug}.jpg`,
    type: 'jpeg',
    quality: 85,
    fullPage: false,
  });
  await page.close();
}

await browser.close();

Запускаю командой node scripts/screenshots.mjs перед каждым деплоем.

Результаты

МетрикаIframeСкриншоты
LCP4.2 с1.1 с
Lighthouse6298
Mobile SafariбагиOK
Размер главной8.4 МБ1.6 МБ

Бонус — автообновление

Скриншоты актуальны на момент последнего деплоя. В GitHub Actions добавил шаг: раз в неделю cron запускает скрипт и коммитит новые картинки. Клиенты меняют сайты → у меня в портфолио всегда свежие скриншоты без ручной работы.

Выводы

  • Iframe в портфолио — прошлый век. Работает только на больших экранах, проседает везде.
  • Скриншоты + ссылка на живой сайт — это и быстро, и честно.
  • Playwright за 5 минут настройки даёт то, что иначе стоит часов фотошопа.