<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Stanchev</title>
    <description>The latest articles on DEV Community by Stanchev (@stanchev).</description>
    <link>https://dev.to/stanchev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3136852%2Fb69e0776-89bc-4bf9-9a33-3587aa573cc8.jpg</url>
      <title>DEV Community: Stanchev</title>
      <link>https://dev.to/stanchev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/stanchev"/>
    <language>en</language>
    <item>
      <title>Оптимизация на производителността в Next.js</title>
      <dc:creator>Stanchev</dc:creator>
      <pubDate>Fri, 20 Mar 2026 18:24:04 +0000</pubDate>
      <link>https://dev.to/stanchev/optimizatsiia-na-proizvoditielnostta-v-nextjs-10e9</link>
      <guid>https://dev.to/stanchev/optimizatsiia-na-proizvoditielnostta-v-nextjs-10e9</guid>
      <description>&lt;h2&gt;
  
  
  Next.js 14/15 - важни бележки преди да започнем
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Минималната версия на Node.js е вече &lt;strong&gt;18.17&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Командата &lt;code&gt;next export&lt;/code&gt; е заменена с &lt;code&gt;output: 'export'&lt;/code&gt; в &lt;code&gt;next.config.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Пакетът &lt;code&gt;@next/font&lt;/code&gt; е премахнат - използвай вградения &lt;code&gt;next/font&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;API-та като &lt;code&gt;cookies&lt;/code&gt;, &lt;code&gt;headers&lt;/code&gt; и &lt;code&gt;draftMode&lt;/code&gt; са вече &lt;strong&gt;async&lt;/strong&gt; в Next.js 15 (изисква &lt;code&gt;await&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch&lt;/code&gt; заявките &lt;strong&gt;вече не се кешират по подразбиране&lt;/strong&gt; - използвай &lt;code&gt;cache: 'force-cache'&lt;/code&gt; ако ти трябва кеширане&lt;/li&gt;
&lt;li&gt;Някои конфигурационни опции са променени (&lt;code&gt;experimental-edge&lt;/code&gt; → &lt;code&gt;edge&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Ако използваш TypeScript, обнови &lt;code&gt;@types/react&lt;/code&gt; и &lt;code&gt;@types/react-dom&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Изграждането на бързи уеб приложения е от ключово значение. Next.js предоставя много вградени функции за производителност, но разработчиците все пак трябва да ги използват разумно. В това ръководство ще разгледаме практически техники за ускоряване на Next.js приложения - оптимизация на изображения, code splitting, lazy loading, статично генериране, оптимизирано зареждане на шрифтове и намаляване на размера на JavaScript bundle-а.&lt;/p&gt;




&lt;h2&gt;
  
  
  Оптимизация на изображения
&lt;/h2&gt;

&lt;p&gt;Големите или неоптимизирани изображения са един от най-честите проблеми с производителността. Вграденият компонент &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; на Next.js помага да ги оптимизираш автоматично. Той сервира изображения в правилния размер, в модерни формати (WebP/AVIF) и включва lazy loading по подразбиране.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/images/hero.jpg"&lt;/span&gt;
        &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Hero banner"&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;priority&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Добре дошли в сайта!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Какво прави &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt; компонентът
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Responsive изображения&lt;/strong&gt; - автоматично сервира размера, подходящ за устройството на потребителя&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy loading&lt;/strong&gt; - изображенията се зареждат само когато влязат във viewport-а, което ускорява началното зареждане&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blur placeholder&lt;/strong&gt; - добавя blur ефект докато изображението се зарежда чрез &lt;code&gt;placeholder="blur"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom loader&lt;/strong&gt; - за напреднали случаи можеш да дефинираш собствена функция за зареждане
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
  &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/images/hero.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Hero banner"&lt;/span&gt;
  &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"responsive"&lt;/span&gt;
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;priority&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Code Splitting и Lazy Loading
&lt;/h2&gt;

&lt;p&gt;Code splitting е техника за разделяне на кода на по-малки bundle-и, които се зареждат при нужда. Next.js прави това автоматично за страниците, но можеш и ръчно да разделяш компоненти.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Imports
&lt;/h3&gt;

&lt;p&gt;Използвай dynamic imports за да зареждаш компоненти само когато са необходими:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DynamicComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../components/HeavyComponent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DynamicComponent&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Route-Based Code Splitting
&lt;/h3&gt;

&lt;p&gt;Next.js автоматично разделя кода на ниво страница - всяка страница зарежда само JavaScript-а, от който се нуждае. Можеш да оптимизираш допълнително чрез dynamic imports за компоненти, които не са нужни веднага.&lt;/p&gt;




&lt;h2&gt;
  
  
  Статично генериране
&lt;/h2&gt;

&lt;p&gt;Статичното генериране е предпочитаният начин за генериране на страници в Next.js. Страниците се пре-рендират по време на build-а и се сервират като статични файлове - идеално за производителност и SEO.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;getStaticProps&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Използвай &lt;code&gt;getStaticProps&lt;/code&gt; за да извличаш данни по време на build-а:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incremental Static Regeneration (ISR)
&lt;/h3&gt;

&lt;p&gt;Next.js 12 въведе ISR, което ти позволява да обновяваш статично съдържание след като сайтът е built. Използвай свойството &lt;code&gt;revalidate&lt;/code&gt; в &lt;code&gt;getStaticProps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Регенерира страницата максимум веднъж на 10 секунди&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Оптимизирано зареждане на шрифтове
&lt;/h2&gt;

&lt;p&gt;Шрифтовете могат да бъдат значителна част от размера на bundle-а и да влияят на производителността. Next.js 13 въведе пакета &lt;code&gt;next/font&lt;/code&gt; за оптимизирано зареждане на шрифтове.&lt;/p&gt;

&lt;h3&gt;
  
  
  Използване на &lt;code&gt;next/font&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Импортирай шрифтове от &lt;code&gt;next/font&lt;/code&gt; вместо да използваш традиционни CSS &lt;code&gt;@font-face&lt;/code&gt; правила:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Roboto&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/font/google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roboto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Roboto&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;subsets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;400&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;roboto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Здравей, свят!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Предимства на &lt;code&gt;next/font&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Автоматично subsetting&lt;/strong&gt; - зареждат се само символите, използвани на страницата&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variable fonts&lt;/strong&gt; — поддръжка за variable fonts, което намалява броя на нужните файлове&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Оптимизирано зареждане&lt;/strong&gt; - шрифтовете се зареждат по начин, който не блокира рендирането&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Намаляване на размера на JavaScript bundle-а
&lt;/h2&gt;

&lt;p&gt;По-малкият JavaScript bundle означава по-бързо зареждане. Ето няколко стратегии:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Анализирай bundle-а си&lt;/strong&gt; - използвай &lt;code&gt;@next/bundle-analyzer&lt;/code&gt; за да видиш какво е в JavaScript bundle-а ти&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Премахни неизползвани зависимости&lt;/strong&gt; - редовно одитирай пакетите и премахвай тези, които не се използват&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Използвай по-леки алтернативи&lt;/strong&gt; - например &lt;code&gt;date-fns&lt;/code&gt; вместо &lt;code&gt;moment.js&lt;/code&gt; за работа с дати&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Оптимизирай lodash imports&lt;/strong&gt; - вместо целия lodash, импортирай само функциите, от които се нуждаеш&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bundle Analyzer - стъпка по стъпка
&lt;/h3&gt;

&lt;p&gt;Инсталирай:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @next/bundle-analyzer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Обнови &lt;code&gt;next.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withBundleAnalyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@next/bundle-analyzer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANALYZE&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withBundleAnalyzer&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Стартирай анализа:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;ANALYZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true &lt;/span&gt;next build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Извод
&lt;/h2&gt;

&lt;p&gt;Оптимизацията на производителността е от ключово значение за бързо и приятно потребителско изживяване. Next.js предлага мощни функции, които помагат на разработчиците да оптимизират приложенията си ефективно. Чрез оптимизация на изображения, code splitting, статично генериране, оптимизирано зареждане на шрифтове и внимателно управление на bundle размера можеш значително да подобриш производителността на Next.js приложенията си.&lt;/p&gt;

&lt;p&gt;Следи последните версии на Next.js и актуалните добри практики — framework-ът се развива бързо.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>performance</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Как изградих WordPress тема с Lighthouse 95+ от нулата</title>
      <dc:creator>Stanchev</dc:creator>
      <pubDate>Thu, 19 Mar 2026 18:46:26 +0000</pubDate>
      <link>https://dev.to/stanchev/kak-izghradikh-wordpress-tiema-s-lighthouse-95-ot-nulata-49af</link>
      <guid>https://dev.to/stanchev/kak-izghradikh-wordpress-tiema-s-lighthouse-95-ot-nulata-49af</guid>
      <description>&lt;p&gt;Когато започнах &lt;strong&gt;PressGrid&lt;/strong&gt;, целта беше проста: WordPress тема за новинарски сайтове, която не зарежда jQuery, не се нуждае от плъгини за перформанс и минава Lighthouse с &lt;strong&gt;95+&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Повечето теми идват с Bootstrap, jQuery, слайдери и десетки HTTP заявки. За новинарски сайт с висок трафик това е смърт - render-blocking ресурси убиват LCP, всяка допълнителна заявка вдига TTFB.&lt;/p&gt;

&lt;p&gt;Решението: &lt;strong&gt;нулеви JS зависимости&lt;/strong&gt; извън WordPress core, ~22KB CSS без framework overhead, и всичко написано ръчно.&lt;/p&gt;




&lt;h2&gt;
  
  
  Архитектура: какво направи разликата
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Deferred JS навсякъде
&lt;/h3&gt;

&lt;p&gt;Всички скриптове се зареждат с &lt;code&gt;defer&lt;/code&gt; - навигация, progress bar, share бутони, back-to-top. Браузърът парсва HTML без прекъсване. Нито един скрипт не блокира рендиране.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;wp_enqueue_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'pressgrid-main'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;get_template_directory_uri&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/assets/js/main.js'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="no"&gt;PRESSGRID_VERSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'strategy'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'defer'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Transient caching + &lt;code&gt;no_found_rows&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Hero, trending, category grid - всичко минава през &lt;code&gt;set_transient()&lt;/code&gt;. Само post ID-та се кешират, заявката се реконструира от кеша.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_transient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_hero_posts'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$cached&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WP_Query&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'posts_per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'no_found_rows'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// пропуска SQL_CALC_FOUND_ROWS&lt;/span&gt;
        &lt;span class="s1"&gt;'fields'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ids'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nf"&gt;set_transient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_hero_posts'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;MINUTE_IN_SECONDS&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Резултат: от ~8 DB заявки при зареждане до &lt;strong&gt;1-2 при cache hit&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. LCP оптимизация
&lt;/h3&gt;

&lt;p&gt;Hero изображението получава &lt;code&gt;fetchpriority="high"&lt;/code&gt; + &lt;code&gt;loading="eager"&lt;/code&gt;. Всички останали - &lt;code&gt;loading="lazy"&lt;/code&gt; + &lt;code&gt;decoding="async"&lt;/code&gt;. Preconnect hints се добавят &lt;strong&gt;само когато съответните функции са активни&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Preconnect само ако weather widget-ът е включен&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;get_theme_mod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_weather_api_key'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. CSS без framework - ~22KB
&lt;/h3&gt;

&lt;p&gt;Целият стилинг е нативен CSS Grid + Flexbox. Никакъв Bootstrap. CSS custom properties за theming с live Customizer preview чрез &lt;code&gt;postMessage&lt;/code&gt; транспорт - без page reload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--pg-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="m"&gt;#cc0000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--pg-secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;#990000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--pg-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="m"&gt;#1a1a1a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--pg-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--font-display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s2"&gt;'Playfair Display'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Georgia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--font-ui&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="s2"&gt;'Barlow Condensed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  SEO от ден едно
&lt;/h2&gt;

&lt;p&gt;Lighthouse Performance е само половината. За новинарски сайт SEO е също толкова важен.&lt;/p&gt;

&lt;h3&gt;
  
  
  NewsArticle JSON-LD (автоматично)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pressgrid_newsarticle_schema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nf"&gt;is_single&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'@context'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://schema.org'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'@type'&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'NewsArticle'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'headline'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_the_title&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'datePublished'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_the_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'c'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'dateModified'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_the_modified_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'c'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'author'&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'@type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Person'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_the_author&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'publisher'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'@type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Organization'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'name'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_bloginfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
        &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;wp_json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$schema&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'wp_head'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_newsarticle_schema'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google News изисква NewsArticle schema за Discover. Излиза автоматично на всеки single post - нулева конфигурация.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Graph + Twitter Cards на всяка страница
&lt;/h3&gt;

&lt;p&gt;Не само на постове - на архиви, категории, статични страници. Featured image-ът се дърпа автоматично.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reading UX: 6 неща без нито един плъгин
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reading progress bar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.pg-progress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Тънка червена линия в горната част на viewport-а. Само на single posts. &lt;code&gt;passive: true&lt;/code&gt; — не блокира scroll thread-а.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estimated read time (server-side)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pressgrid_reading_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$post_id&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_post_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'post_content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$post_id&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$words&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_word_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;wp_strip_all_tags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$content&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$words&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Native share buttons — нулев external JS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sharePost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;share&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Копирано ✓&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Web Share API на мобилни, clipboard fallback на desktop. LinkedIn - обикновен &lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt;. Никакъв SDK.&lt;/p&gt;

&lt;h3&gt;
  
  
  Останалите три без ред JS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Related posts&lt;/strong&gt; — &lt;code&gt;WP_Query&lt;/code&gt; по същата категория с &lt;code&gt;orderby=rand&lt;/code&gt;, без плъгин&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky sidebar&lt;/strong&gt; — &lt;code&gt;position: sticky; top: 2rem&lt;/code&gt; — буквално един ред CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Card hover animations&lt;/strong&gt; — &lt;code&gt;translateY(-3px)&lt;/code&gt; + &lt;code&gt;box-shadow&lt;/code&gt;, чист CSS&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Forex ticker, който се самоактивира
&lt;/h2&gt;

&lt;p&gt;Едно от любимите ми неща в PressGrid: форекс тикерът се активира &lt;strong&gt;автоматично&lt;/strong&gt; когато Layout Builder има секция с Business/Finance категория. Нулева конфигурация.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;pressgrid_has_business_section&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_transient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_has_biz_section'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$cached&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$cached&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$slugs&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'business'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'finance'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'бизнес'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'финанси'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'economy'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'пазари'&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;$sections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_layout_sections'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$sections&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$section&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'enabled'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_category&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$section&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'category'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cat&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;in_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cat&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$slugs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;set_transient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'pressgrid_has_biz_section'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;MINUTE_IN_SECONDS&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Данните идват от &lt;strong&gt;Frankfurter&lt;/strong&gt; (ECB) - безплатно, без API ключ, кешира се 6 часа.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security hardening
&lt;/h2&gt;

&lt;p&gt;Всеки &lt;code&gt;$_POST&lt;/code&gt; минава през &lt;code&gt;wp_verify_nonce()&lt;/code&gt; + &lt;code&gt;current_user_can()&lt;/code&gt;. Всеки output — &lt;code&gt;esc_html()&lt;/code&gt;, &lt;code&gt;esc_url()&lt;/code&gt;, &lt;code&gt;esc_attr()&lt;/code&gt;. Ad HTML минава през &lt;code&gt;wp_kses()&lt;/code&gt; со strict whitelist.&lt;/p&gt;

&lt;p&gt;Нещото, което ме радва най-много: font upload-ът валидира WOFF2 magic bytes (&lt;code&gt;0x774F4632&lt;/code&gt;) преди да запише файла. Не разчитам само на extension-а.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$handle&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$tmp_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rb'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$magic&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;fread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;fclose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$handle&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$magic&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\x77\x4F\x46\x32&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;wp_die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Invalid WOFF2 file.'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Резултатът
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Метрика&lt;/th&gt;
&lt;th&gt;Стойност&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lighthouse Performance&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;95+&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render-blocking JS&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External JS зависимости&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS размер&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~22KB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB заявки при cache hit&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1-2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PHP файлове&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Преводими стрингове&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;182&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Какво следва
&lt;/h2&gt;

&lt;p&gt;В момента работя по &lt;strong&gt;Sofia Vital&lt;/strong&gt; - Next.js 18 проект, където прилагам същите принципи: Core Web Vitals first, structured data, нулев layout shift.&lt;/p&gt;

&lt;p&gt;Ако искаш да разгледаш кода на PressGrid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/stantchev/PressGrid-WordPress-Theme" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stantchev.github.io/PressGrid-WordPress-Theme/" rel="noopener noreferrer"&gt;Документация&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Въпроси? Drop ги в коментарите — отговарям на всичко.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>wordpress</category>
      <category>performance</category>
      <category>seo</category>
    </item>
    <item>
      <title>10 Lesser-Known WordPress Plugins to Improve SEO Performance</title>
      <dc:creator>Stanchev</dc:creator>
      <pubDate>Fri, 23 May 2025 07:50:33 +0000</pubDate>
      <link>https://dev.to/stanchev/10-lesser-known-wordpress-plugins-to-improve-seo-performance-1pm8</link>
      <guid>https://dev.to/stanchev/10-lesser-known-wordpress-plugins-to-improve-seo-performance-1pm8</guid>
      <description>&lt;p&gt;Most WordPress site owners rely on popular SEO plugins like Yoast or Rank Math. However, several lesser-known plugins offer powerful SEO enhancements that can help your website stand out in search results. Using these hidden gems can improve site speed, metadata management, link building, and content analysis — key factors for better SEO performance.&lt;/p&gt;

&lt;p&gt;Here are 10 effective but less popular WordPress plugins worth considering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Schema &amp;amp; Structured Data for WP &amp;amp; AMP&lt;br&gt;
This plugin adds rich schema markup to your content, improving how search engines understand your site. Enhanced snippets can increase click-through rates by making your listings more attractive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WP Meta SEO&lt;br&gt;
WP Meta SEO simplifies bulk metadata editing, allowing you to optimize titles, descriptions, and images efficiently. It also monitors broken links and generates XML sitemaps for better crawlability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SEO Optimized Images&lt;br&gt;
Automatically adds missing alt and title attributes to images based on configurable templates. Optimizing image SEO improves your chances of ranking in image search and boosts overall page relevance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal Link Juicer&lt;br&gt;
This plugin automates internal linking by inserting keyword-based links within your content. It strengthens site architecture and distributes link equity, which positively impacts SEO.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WP Speed of Light&lt;br&gt;
Site speed directly affects SEO rankings. WP Speed of Light offers caching, minification, and database optimization features to improve loading times and enhance user experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autoptimize&lt;br&gt;
Autoptimize aggregates, minifies, and caches scripts and styles. It helps reduce page size and improves load speeds, factors that Google’s algorithm rewards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Broken Link Checker&lt;br&gt;
Search engines penalize websites with broken links. This plugin scans your content for dead links and missing images, alerting you to fix issues quickly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rankie&lt;br&gt;
Rankie tracks your keyword rankings in real time and generates reports. Understanding how your keywords perform enables data-driven SEO strategies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SEO Redirection Plugin&lt;br&gt;
Managing 301 redirects is crucial during site restructuring or URL changes. This plugin makes redirect management easy, helping preserve link equity and user experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;W3 Total Cache&lt;br&gt;
Though not obscure, W3 Total Cache is less discussed compared to competitors. It optimizes caching, CDN integration, and browser caching, improving speed and SEO metrics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrating these lesser-known WordPress plugins can complement your main SEO tools, creating a robust SEO strategy that covers technical optimization, content enhancement, and user experience. For professional help with SEO strategies and implementation, check out &lt;a href="https://stanchev.bg/" rel="noopener noreferrer"&gt;SEO Услуги&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>plugins</category>
      <category>seo</category>
      <category>performance</category>
    </item>
    <item>
      <title>Behind the Build: Portfolio Process</title>
      <dc:creator>Stanchev</dc:creator>
      <pubDate>Thu, 08 May 2025 09:15:03 +0000</pubDate>
      <link>https://dev.to/stanchev/behind-the-build-portfolio-process-133p</link>
      <guid>https://dev.to/stanchev/behind-the-build-portfolio-process-133p</guid>
      <description>&lt;p&gt;Building a portfolio is more than just throwing together a collection of projects. It's about showing off your skills, but also about making sure that everything works seamlessly and efficiently. In this article, I'll walk you through the behind-the-scenes process of how I built my portfolio site from scratch using Vite, Tailwind CSS, and TypeScript—with a big emphasis on speed, SEO optimization, and modern design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the Stage: Defining the Project's Core Goals
&lt;/h2&gt;

&lt;p&gt;Before diving into the code, I took time to set some key objectives for the project. These goals would guide every decision I made throughout the development process:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed&lt;/strong&gt; – I wanted the site to be as fast as possible, because no one likes slow-loading pages.&lt;br&gt;
 &lt;strong&gt;SEO Optimization&lt;/strong&gt; – A beautiful site is useless if no one can find it, so ensuring the site was built with SEO best practices in mind was a priority.&lt;br&gt;
 &lt;strong&gt;Minimalist Design&lt;/strong&gt; – I wanted the design to be clean, simple, and focused on content.&lt;br&gt;
 &lt;strong&gt;Scalable Code&lt;/strong&gt; – The last thing I wanted was to end up with a messy, unmaintainable codebase, so I made sure the architecture was structured for scalability.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each of these goals was taken into consideration as I chose tools, set up the project, and wrote the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Tools I Chose
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;1. Vite for Fast Development&lt;/em&gt;&lt;br&gt;
The development environment needed to be fast and efficient. That's where Vite comes in. It's a next-generation build tool that gives you a lightning-fast development server and an optimized production build. It's not just fast—it also helps with code splitting, hot module replacement, and ensuring that the app loads quickly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2. TypeScript for Better Code Quality&lt;/em&gt;&lt;br&gt;
I chose TypeScript to add strong typing and improve code quality. TypeScript is a game-changer for catching errors early and making sure everything is properly structured. It also makes the codebase easier to maintain and scale as the project grows.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;3. Tailwind CSS for Custom, Responsive Design&lt;/em&gt;&lt;br&gt;
Designing a portfolio requires balance. I wanted the site to look polished but not bloated. Enter Tailwind CSS. It's a utility-first CSS framework that lets you build custom designs quickly. With Tailwind, I could write clean and responsive CSS without worrying about overriding styles or bloating the page with unnecessary classes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;4. PostCSS for CSS Enhancements&lt;/em&gt;&lt;br&gt;
PostCSS was used to extend the capabilities of CSS. It allows for transformations like automatically adding vendor prefixes, optimizing the final CSS, and enabling modern CSS features that aren’t yet supported by all browsers.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;5. ESLint for Clean Code&lt;/em&gt;&lt;br&gt;
Maintaining a clean and readable codebase was important to me, so I integrated ESLint. ESLint ensures that all code adheres to the same formatting rules and helps avoid common mistakes, improving code quality and maintainability.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO Optimization: Behind the Scenes
&lt;/h3&gt;

&lt;p&gt;SEO is not just about keyword stuffing. It’s about creating a website that both users and search engines can understand. Here's how I approached SEO during the build:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Semantic HTML&lt;/em&gt; – I made sure to use semantic tags (like , , ) to structure the content properly. This not only helps search engines crawl the site but also improves accessibility.&lt;br&gt;
&lt;em&gt;Optimized Assets&lt;/em&gt; – I compressed and resized images to ensure fast load times, which is essential for both user experience and SEO.&lt;br&gt;
&lt;em&gt;Responsive Design&lt;/em&gt; – Since mobile traffic is huge, I made sure the site looks great on all devices. Tailwind’s responsive utilities made this task much easier.&lt;br&gt;
&lt;em&gt;Clean URL Structure&lt;/em&gt; – The URLs are clean and descriptive, which improves both user experience and SEO.&lt;/p&gt;

&lt;p&gt;Building a portfolio site isn’t just about showing off your skills; it’s about creating a user-friendly, fast, and SEO-optimized website that reflects your approach to development. By focusing on speed, SEO, and modern design, I built a portfolio that not only looks great but also performs well. I hope this behind-the-scenes look into my process has been insightful and helps you in your own projects.&lt;/p&gt;

&lt;p&gt;You can check out the full source code for &lt;a href="https://github.com/stantchev/stanchev" rel="noopener noreferrer"&gt;Stanchev&lt;/a&gt;'s project on GitHub, or view the live version of the site &lt;a href="https://stanchev.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>learning</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
