{"id":34853,"date":"2025-11-22T21:41:35","date_gmt":"2025-11-22T18:41:35","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=34853"},"modified":"2025-11-22T21:41:35","modified_gmt":"2025-11-22T18:41:35","slug":"intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/","title":{"rendered":"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma"},"content":{"rendered":"<p><body><\/p>\n<h2>Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma<\/h2>\n<p>Web uygulamalar\u0131nda performans, kullan\u0131c\u0131 deneyimi ve SEO i\u00e7in kritik bir fakt\u00f6rd\u00fcr. \u00d6zellikle g\u00f6rsel a\u011f\u0131rl\u0131kl\u0131 sayfalarda, t\u00fcm g\u00f6rsellerin sayfa y\u00fcklendi\u011finde an\u0131nda indirilmesi, sayfa y\u00fckleme s\u00fcresini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir ve kullan\u0131c\u0131lar\u0131n bo\u015f bir ekranla kar\u015f\u0131la\u015fmas\u0131na neden olabilir. \u0130\u015fte bu noktada &#8220;tembel y\u00fckleme&#8221; (lazy loading) devreye girer. Tembel y\u00fckleme, bir g\u00f6rselin veya di\u011fer medya \u00f6\u011fesinin yaln\u0131zca kullan\u0131c\u0131n\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na (viewport) girdi\u011finde veya girmek \u00fczere oldu\u011funda y\u00fcklenmesini sa\u011flayan bir tekniktir.<\/p>\n<p>Geleneksel olarak, tembel y\u00fckleme i\u015flemleri scroll event listener&#8217;lar ve elementin konumu hesaplamalar\u0131yla yap\u0131l\u0131rd\u0131. Ancak bu y\u00f6ntemler genellikle performans sorunlar\u0131na yol a\u00e7abilir ve taray\u0131c\u0131 taraf\u0131ndan optimize edilmez. Neyse ki, modern web taray\u0131c\u0131lar\u0131 art\u0131k bu soruna \u00e7ok daha verimli bir \u00e7\u00f6z\u00fcm sunuyor: Intersection Observer API. Bu rehberde, Intersection Observer API&#8217;sini kullanarak Vue.js&#8217;te nas\u0131l sa\u011flam ve performansl\u0131 bir tembel y\u00fckleme g\u00f6rsel bile\u015feni olu\u015fturaca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz.<\/p>\n<h2>Intersection Observer API Nedir ve Neden Kullanmal\u0131y\u0131z?<\/h2>\n<p>Intersection Observer API, bir eleman\u0131n k\u00f6k eleman (genellikle taray\u0131c\u0131 g\u00f6r\u00fcnt\u00fc alan\u0131) ile kesi\u015fti\u011fi (intersecting) an\u0131 asenkron olarak g\u00f6zlemlemenizi sa\u011flayan bir taray\u0131c\u0131 API&#8217;sidir. Bu API, \u00f6zellikle tembel y\u00fckleme (lazy loading), sonsuz kayd\u0131rma (infinite scrolling) ve reklam g\u00f6r\u00fcn\u00fcrl\u00fc\u011f\u00fc takibi gibi senaryolar i\u00e7in tasarlanm\u0131\u015ft\u0131r. Temel amac\u0131, elemanlar\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na girip girmedi\u011fini veya ne kadar\u0131n\u0131n girdi\u011fini y\u00fcksek performansla tespit etmektir.<\/p>\n<p>Peki, neden Intersection Observer&#8217;\u0131 kullanmal\u0131y\u0131z? \u0130\u015fte ba\u015fl\u0131ca nedenler:<\/p>\n<ul>\n<li><strong>Performans:<\/strong> Geleneksel scroll event listener tabanl\u0131 \u00e7\u00f6z\u00fcmler, her kayd\u0131rma olay\u0131nda DOM manip\u00fclasyonlar\u0131 ve pozisyon hesaplamalar\u0131 yaparak ciddi performans d\u00fc\u015f\u00fc\u015flerine neden olabilir. Intersection Observer ise taray\u0131c\u0131n\u0131n ana i\u015f par\u00e7ac\u0131\u011f\u0131ndan ba\u011f\u0131ms\u0131z \u00e7al\u0131\u015f\u0131r ve yaln\u0131zca kesi\u015fim durumunda bir geri arama (callback) fonksiyonu tetikler. Bu, \u00e7ok daha ak\u0131c\u0131 bir kullan\u0131c\u0131 deneyimi sa\u011flar.<\/li>\n<li><strong>Basitlik:<\/strong> Karma\u015f\u0131k pozisyon hesaplamalar\u0131yla u\u011fra\u015fmak yerine, Intersection Observer API&#8217;si \u00e7ok daha temiz ve okunabilir bir kod yazman\u0131z\u0131 sa\u011flar. API&#8217;nin kullan\u0131m\u0131 olduk\u00e7a sezgiseldir.<\/li>\n<li><strong>Taray\u0131c\u0131 Optimizasyonu:<\/strong> Taray\u0131c\u0131lar Intersection Observer API&#8217;sini kendi i\u00e7lerinde optimize eder. Bu, pil \u00f6mr\u00fc ve genel sistem kaynaklar\u0131 a\u00e7\u0131s\u0131ndan daha verimli \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Esneklik:<\/strong> Bir eleman\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na tamamen girmesini beklemek yerine, belirli bir e\u015fik de\u011feriyle (threshold) veya k\u00f6k kenar bo\u015fluklar\u0131 (rootMargin) ile eleman\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na girmeden \u00f6nce bile y\u00fcklenmeye ba\u015flamas\u0131n\u0131 sa\u011flayabilirsiniz.<\/li>\n<\/ul>\n<p>Intersection Observer&#8217;\u0131n temel yap\u0131 ta\u015flar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li><strong><code>root<\/code>:<\/strong> G\u00f6zlemlenen eleman\u0131n kesi\u015fti\u011fi k\u00f6k eleman. Varsay\u0131lan olarak taray\u0131c\u0131 g\u00f6r\u00fcnt\u00fc alan\u0131d\u0131r (viewport). Bir DOM eleman\u0131 da olabilir.<\/li>\n<li><strong><code>rootMargin<\/code>:<\/strong> K\u00f6k eleman\u0131n etraf\u0131ndaki kenar bo\u015fluklar\u0131n\u0131 belirtir. CSS margin \u00f6zelli\u011fi gibi \u00e7al\u0131\u015f\u0131r (\u00f6rn: &#8220;10px 20px 30px 40px&#8221;). Bu, bir eleman\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na girmeden belirli bir mesafe \u00f6nce y\u00fcklenmesini sa\u011flamak i\u00e7in harika bir yoldur.<\/li>\n<li><strong><code>threshold<\/code>:<\/strong> K\u00f6k eleman ile g\u00f6zlemlenen eleman\u0131n kesi\u015fme y\u00fczdesini belirten bir say\u0131 veya say\u0131 dizisi. \u00d6rne\u011fin, <code>0.1<\/code> eleman\u0131n %10&#8217;u g\u00f6r\u00fcn\u00fcr oldu\u011funda, <code>[0, 0.25, 0.5, 0.75, 1]<\/code> ise eleman\u0131n her %25&#8217;i g\u00f6r\u00fcn\u00fcr oldu\u011funda geri arama fonksiyonunu tetikler.<\/li>\n<\/ul>\n<h2>Vue.js&#8217;te Temel Bir Tembel Y\u00fckleme G\u00f6rsel Bile\u015feni Olu\u015fturma<\/h2>\n<p>\u015eimdi, Intersection Observer API&#8217;sini kullanarak Vue.js&#8217;te nas\u0131l temel bir tembel y\u00fckleme g\u00f6rsel bile\u015feni olu\u015fturaca\u011f\u0131m\u0131za bakal\u0131m. Bu bile\u015fen, bir g\u00f6rselin yaln\u0131zca kullan\u0131c\u0131n\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131na girdi\u011finde y\u00fcklenmesini sa\u011flayacak.<\/p>\n<h3>Bile\u015fen Yap\u0131s\u0131<\/h3>\n<p><code>LazyImage.vue<\/code> ad\u0131nda yeni bir Vue bile\u015feni olu\u015ftural\u0131m. Bu bile\u015fen, g\u00f6rselin <code>src<\/code> ve <code>alt<\/code> \u00f6zelliklerini prop olarak alacak. Ayr\u0131ca, g\u00f6rsel y\u00fcklenmeden \u00f6nce g\u00f6sterilecek bir yer tutucu (placeholder) g\u00f6rsel veya bir y\u00fckleme g\u00f6stergesi i\u00e7in de mant\u0131k ekleyece\u011fiz.<\/p>\n<p>\u0130lk olarak, bile\u015fenin temel yap\u0131s\u0131n\u0131 ve gerekli durum (state) de\u011fi\u015fkenlerini tan\u0131mlayal\u0131m:<\/p>\n<pre><code class=\"language-html\"><template>\n  <div class=\"lazy-image-container\" :class=\"{ 'loaded': isLoaded }\">\n    <img\n      ref=\"imageRef\"\n      :src=\"currentSrc\"\n      :alt=\"alt\"\n      @load=\"handleImageLoad\"\n      @error=\"handleImageError\"\n      :class=\"{ 'placeholder': !isLoaded, 'actual-image': isLoaded }\"\n    \/>\n    <!-- Y\u00fckleme g\u00f6stergesi veya yer tutucu burada g\u00f6sterilebilir -->\n    <div v-if=\"!isLoaded &#038;&#038; !isError\" class=\"loading-spinner\"><\/div>\n  <\/div>\n<\/template>\n\n<script>\nexport default {\n  name: 'LazyImage',\n  props: {\n    src: {\n      type: String,\n      required: true\n    },\n    alt: {\n      type: String,\n      default: ''\n    },\n    placeholderSrc: {\n      type: String,\n      default: 'data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' \/\/ \u015eeffaf 1x1 GIF\n    }\n  },\n  data() {\n    return {\n      isLoaded: false,\n      isError: false,\n      currentSrc: this.placeholderSrc,\n      observer: null\n    };\n  },\n  mounted() {\n    this.initIntersectionObserver();\n  },\n  beforeUnmount() {\n    if (this.observer) {\n      this.observer.disconnect();\n    }\n  },\n  methods: {\n    initIntersectionObserver() {\n      const options = {\n        root: null, \/\/ G\u00f6r\u00fcnt\u00fc alan\u0131 (viewport)\n        rootMargin: '0px 0px 200px 0px', \/\/ G\u00f6rsel 200px yakla\u015ft\u0131\u011f\u0131nda y\u00fckle\n        threshold: 0 \/\/ Herhangi bir oranda g\u00f6r\u00fcn\u00fcr oldu\u011funda\n      };\n\n      this.observer = new IntersectionObserver(this.handleIntersect, options);\n      this.observer.observe(this.$refs.imageRef);\n    },\n    handleIntersect(entries) {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          this.currentSrc = this.src; \/\/ G\u00f6rseli y\u00fckle\n          this.observer.unobserve(entry.target); \/\/ G\u00f6zlemlemeyi durdur\n        }\n      });\n    },\n    handleImageLoad() {\n      this.isLoaded = true;\n      this.isError = false;\n    },\n    handleImageError() {\n      this.isError = true;\n      this.isLoaded = true; \/\/ Hata olsa bile y\u00fckleme tamamland\u0131 say\u0131l\u0131r\n      this.currentSrc = 'https:\/\/via.placeholder.com\/150?text=Hata'; \/\/ Hata g\u00f6rseli\n    }\n  }\n};\n<\/script>\n\n<style scoped>\n.lazy-image-container {\n  display: inline-block;\n  position: relative;\n  overflow: hidden;\n  background-color: #f0f0f0; \/<em> Yer tutucu arka plan rengi <\/em>\/\n  min-width: 100px; \/<em> Minimum boyutlar <\/em>\/\n  min-height: 100px;\n}\n\n.lazy-image-container img {\n  width: 100%;\n  height: 100%;\n  object-fit: cover;\n  transition: opacity 0.5s ease-in-out;\n}\n\n.lazy-image-container img.placeholder {\n  opacity: 0;\n}\n\n.lazy-image-container img.actual-image {\n  opacity: 1;\n}\n\n.loading-spinner {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 30px;\n  height: 30px;\n  border: 4px solid rgba(0, 0, 0, 0.1);\n  border-left-color: #333;\n  border-radius: 50%;\n  animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n  0% { transform: translate(-50%, -50%) rotate(0deg); }\n  100% { transform: translate(-50%, -50%) rotate(360deg); }\n}\n<\/style>\n<\/code><\/pre>\n<h3>Intersection Observer Entegrasyonu<\/h3>\n<p>Yukar\u0131daki kodda, Intersection Observer&#8217;\u0131 Vue bile\u015fenimize entegre etmek i\u00e7in a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 izledik:<\/p>\n<ol>\n<li><strong><code>data<\/code> Tan\u0131mlamas\u0131:<\/strong>\n<ul>\n<li><code>isLoaded<\/code>: G\u00f6rselin ba\u015far\u0131l\u0131 bir \u015fekilde y\u00fcklenip y\u00fcklenmedi\u011fini tutar.<\/li>\n<li><code>isError<\/code>: G\u00f6rsel y\u00fcklenirken bir hata olup olmad\u0131\u011f\u0131n\u0131 tutar.<\/li>\n<li><code>currentSrc<\/code>: <code><img><\/code> etiketinin anl\u0131k <code>src<\/code> de\u011ferini tutar. Ba\u015flang\u0131\u00e7ta <code>placeholderSrc<\/code> ile ba\u015flar.<\/li>\n<li><code>observer<\/code>: Intersection Observer \u00f6rne\u011fini tutacak de\u011fi\u015fken.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>mounted()<\/code> Ya\u015fam D\u00f6ng\u00fcs\u00fc Kancas\u0131:<\/strong>\n<ul>\n<li>Bile\u015fen DOM&#8217;a ba\u011fland\u0131\u011f\u0131nda <code>initIntersectionObserver()<\/code> metodunu \u00e7a\u011f\u0131r\u0131r\u0131z. Bu, g\u00f6zlemcinin ba\u015flat\u0131lmas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>beforeUnmount()<\/code> Ya\u015fam D\u00f6ng\u00fcs\u00fc Kancas\u0131:<\/strong>\n<ul>\n<li>Bile\u015fen DOM&#8217;dan ayr\u0131lmadan \u00f6nce, e\u011fer bir g\u00f6zlemci \u00f6rne\u011fi varsa, <code>observer.disconnect()<\/code> metodunu \u00e7a\u011f\u0131rarak g\u00f6zlemciyi durdururuz. Bu, bellek s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in kritik bir ad\u0131md\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>initIntersectionObserver()<\/code> Metodu:<\/strong>\n<ul>\n<li><code>options<\/code> nesnesini tan\u0131mlar\u0131z:\n<ul>\n<li><code>root: null<\/code>: G\u00f6zlemcinin k\u00f6k eleman\u0131 olarak taray\u0131c\u0131 g\u00f6r\u00fcnt\u00fc alan\u0131n\u0131 kullan\u0131r\u0131z.<\/li>\n<li><code>rootMargin: '0px 0px 200px 0px'<\/code>: Bu, g\u00f6rsel g\u00f6r\u00fcnt\u00fc alan\u0131na 200 piksel yakla\u015ft\u0131\u011f\u0131nda tetiklenmesini sa\u011flar. Kullan\u0131c\u0131 g\u00f6rseli g\u00f6rmeden hemen \u00f6nce y\u00fcklemeye ba\u015flamak i\u00e7in harikad\u0131r.<\/li>\n<li><code>threshold: 0<\/code>: G\u00f6rselin herhangi bir k\u0131sm\u0131 g\u00f6r\u00fcnt\u00fc alan\u0131na girdi\u011finde callback&#8217;i tetikler.<\/li>\n<\/ul>\n<\/li>\n<li>Yeni bir <code>IntersectionObserver<\/code> \u00f6rne\u011fi olu\u015fturur ve <code>handleIntersect<\/code> metodumuzu callback olarak atar\u0131z.<\/li>\n<li><code>observer.observe(this.$refs.imageRef)<\/code> ile <code><img><\/code> eleman\u0131m\u0131z\u0131 g\u00f6zlemlemeye ba\u015flar\u0131z. <code>ref=\"imageRef\"<\/code> ile elemana referans al\u0131r\u0131z.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>handleIntersect(entries)<\/code> Metodu:<\/strong>\n<ul>\n<li>Bu metod, g\u00f6zlemlenen eleman\u0131n kesi\u015fim durumu de\u011fi\u015fti\u011finde \u00e7a\u011fr\u0131l\u0131r. <code>entries<\/code> dizisi, de\u011fi\u015fen her eleman i\u00e7in bir <code>IntersectionObserverEntry<\/code> nesnesi i\u00e7erir.<\/li>\n<li>Her bir <code>entry<\/code> i\u00e7in <code>entry.isIntersecting<\/code> \u00f6zelli\u011fini kontrol ederiz. E\u011fer <code>true<\/code> ise, eleman g\u00f6r\u00fcnt\u00fc alan\u0131na girmi\u015f demektir.<\/li>\n<li><code>this.currentSrc = this.src<\/code> diyerek ger\u00e7ek g\u00f6rselin URL&#8217;sini atar\u0131z. Bu, taray\u0131c\u0131n\u0131n g\u00f6rseli indirmesini tetikler.<\/li>\n<li><code>this.observer.unobserve(entry.target)<\/code> ile g\u00f6rsel y\u00fcklendikten sonra art\u0131k onu g\u00f6zlemlemeyi durdururuz. Bu, gereksiz g\u00f6zlemlemeleri ve performans y\u00fck\u00fcn\u00fc \u00f6nler.<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>handleImageLoad()<\/code> ve <code>handleImageError()<\/code> Metodlar\u0131:<\/strong>\n<ul>\n<li><code>@load<\/code> ve <code>@error<\/code> event&#8217;leri ile g\u00f6rselin y\u00fcklenme durumunu takip ederiz.<\/li>\n<li><code>handleImageLoad<\/code>, g\u00f6rsel ba\u015far\u0131yla y\u00fcklendi\u011finde <code>isLoaded<\/code> durumunu <code>true<\/code> yapar.<\/li>\n<li><code>handleImageError<\/code>, g\u00f6rsel y\u00fcklenirken bir hata olu\u015ftu\u011funda <code>isError<\/code> durumunu <code>true<\/code> yapar ve bir hata g\u00f6rseli g\u00f6sterir.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h2>Geli\u015fmi\u015f \u00d6zellikler ve En \u0130yi Uygulamalar<\/h2>\n<p>Temel bir bile\u015fen olu\u015fturduk, ancak kullan\u0131c\u0131 deneyimini daha da iyile\u015ftirmek ve bile\u015fenimizi daha sa\u011flam hale getirmek i\u00e7in baz\u0131 geli\u015fmi\u015f \u00f6zellikler ve en iyi uygulamalar\u0131 ekleyebiliriz.<\/p>\n<h3>Yer Tutucu G\u00f6rseller (Placeholder Images)<\/h3>\n<p>G\u00f6rsel y\u00fcklenirken bo\u015f bir alan b\u0131rakmak yerine, kullan\u0131c\u0131ya ge\u00e7ici bir yer tutucu g\u00f6stermek daha iyi bir deneyim sunar. Bu, sayfan\u0131n d\u00fczeninin g\u00f6rsel y\u00fcklenene kadar bozulmamas\u0131n\u0131 sa\u011flar ve kullan\u0131c\u0131n\u0131n ne bekledi\u011fini anlamas\u0131na yard\u0131mc\u0131 olur. Yer tutucu olarak \u015funlar\u0131 kullanabiliriz:<\/p>\n<ul>\n<li><strong>D\u00fc\u015f\u00fck \u00c7\u00f6z\u00fcn\u00fcrl\u00fckl\u00fc \u00d6nizleme:<\/strong> Ger\u00e7ek g\u00f6rselin \u00e7ok k\u00fc\u00e7\u00fck boyutlu ve d\u00fc\u015f\u00fck kaliteli bir versiyonu.<\/li>\n<li><strong>Tek Renkli Bir Arka Plan:<\/strong> G\u00f6rselin ana rengine yak\u0131n d\u00fcz bir renk.<\/li>\n<li><strong>SVG Yer Tutucular:<\/strong> Hafif ve \u00f6l\u00e7eklenebilir SVG&#8217;ler.<\/li>\n<li><strong>Base64 Veri URI&#8217;leri:<\/strong> \u00c7ok k\u00fc\u00e7\u00fck g\u00f6rseller i\u00e7in HTML i\u00e7inde do\u011frudan kodlanm\u0131\u015f g\u00f6rseller. Yukar\u0131daki \u00f6rnekte \u015feffaf 1&#215;1 GIF kulland\u0131k.<\/li>\n<\/ul>\n<p>\u00d6rnek bile\u015fenimizde <code>placeholderSrc<\/code> prop&#8217;u ve <code>currentSrc<\/code> veri \u00f6zelli\u011fi ile bu mant\u0131\u011f\u0131 zaten uygulad\u0131k. G\u00f6rsel y\u00fcklenene kadar <code>currentSrc<\/code>, <code>placeholderSrc<\/code> de\u011ferini tutar ve y\u00fcklendi\u011finde ger\u00e7ek <code>src<\/code> de\u011ferini al\u0131r.<\/p>\n<h3>Hata Y\u00f6netimi<\/h3>\n<p>G\u00f6rselin y\u00fcklenememesi durumunda (\u00f6rn. bozuk URL, sunucu hatas\u0131), kullan\u0131c\u0131ya ne oldu\u011funu bildirmek ve alternatif bir g\u00f6rsel g\u00f6stermek \u00f6nemlidir. <code><img><\/code> etiketinin <code>@error<\/code> olay\u0131n\u0131 dinleyerek bunu kolayca yapabiliriz. Yukar\u0131daki kodda <code>handleImageError<\/code> metodunu bu ama\u00e7la ekledik. Bu metod, <code>isError<\/code> durumunu <code>true<\/code> yapar ve <code>currentSrc<\/code>&#8216;yi bir hata g\u00f6rseli URL&#8217;siyle g\u00fcnceller.<\/p>\n<h3>CSS Ge\u00e7i\u015fleri ve Y\u00fckleme G\u00f6stergesi<\/h3>\n<p>G\u00f6rselin yer tutucudan ger\u00e7ek g\u00f6rseline ge\u00e7i\u015fini daha yumu\u015fak hale getirmek, kullan\u0131c\u0131 deneyimini art\u0131r\u0131r. CSS ge\u00e7i\u015fleri (transitions) kullanarak bu etkiyi sa\u011flayabiliriz. Ayr\u0131ca, g\u00f6rsel y\u00fcklenirken kullan\u0131c\u0131ya g\u00f6rselin yolda oldu\u011funu bildiren bir y\u00fckleme g\u00f6stergesi (spinner) eklemek de iyi bir uygulamad\u0131r.<\/p>\n<p>\u00d6rnek kodumuzdaki CSS b\u00f6l\u00fcm\u00fc, bu ge\u00e7i\u015fleri ve bir y\u00fckleme g\u00f6stergesini nas\u0131l ekleyebilece\u011finizi g\u00f6stermektedir:<\/p>\n<ul>\n<li><code>.lazy-image-container img<\/code> i\u00e7in <code>transition: opacity 0.5s ease-in-out;<\/code> ekleyerek g\u00f6rselin \u015feffafl\u0131\u011f\u0131 de\u011fi\u015fti\u011finde yumu\u015fak bir ge\u00e7i\u015f sa\u011fl\u0131yoruz.<\/li>\n<li><code>.placeholder<\/code> s\u0131n\u0131f\u0131 ba\u015flang\u0131\u00e7ta <code>opacity: 0;<\/code> iken, <code>.actual-image<\/code> s\u0131n\u0131f\u0131 <code>opacity: 1;<\/code> olur. G\u00f6rsel y\u00fcklendi\u011finde <code>isLoaded<\/code> durumu <code>true<\/code> olur ve bu s\u0131n\u0131flar dinamik olarak atan\u0131r.<\/li>\n<li><code>.loading-spinner<\/code> s\u0131n\u0131f\u0131, g\u00f6rsel y\u00fcklenirken g\u00f6sterilen basit bir CSS animasyonlu spinner olu\u015fturur. <code>v-if=\"!isLoaded && !isError\"<\/code> ko\u015fuluyla sadece g\u00f6rsel y\u00fcklenene veya hata olu\u015fana kadar g\u00f6r\u00fcn\u00fcr.<\/li>\n<\/ul>\n<h3><code>rootMargin<\/code> ve <code>threshold<\/code> Ayarlar\u0131<\/h3>\n<p>Bu Intersection Observer se\u00e7eneklerini iyi anlamak, tembel y\u00fckleme stratejinizi optimize etmenizi sa\u011flar:<\/p>\n<ul>\n<li><strong><code>rootMargin<\/code>:<\/strong> Varsay\u0131lan olarak <code>\"0px\"<\/code> olan bu de\u011feri, g\u00f6rselin g\u00f6r\u00fcnt\u00fc alan\u0131na girmeden belirli bir mesafe \u00f6nce y\u00fcklenmeye ba\u015flamas\u0131n\u0131 sa\u011flamak i\u00e7in de\u011fi\u015ftirebilirsiniz. \u00d6rne\u011fin, <code>\"0px 0px 300px 0px\"<\/code> de\u011feri, g\u00f6rselin g\u00f6r\u00fcnt\u00fc alan\u0131n\u0131n alt kenar\u0131na 300 piksel yakla\u015ft\u0131\u011f\u0131nda y\u00fcklenmesini tetikler. Bu, kullan\u0131c\u0131n\u0131n kayd\u0131rma yaparken g\u00f6rselin zaten y\u00fcklenmi\u015f olmas\u0131n\u0131 ve bo\u015f bir alan g\u00f6rmemesini sa\u011flar.<\/li>\n<li><strong><code>threshold<\/code>:<\/strong> Bu de\u011fer, g\u00f6zlemlenen eleman\u0131n y\u00fczde ka\u00e7\u0131n\u0131n k\u00f6k eleman ile kesi\u015fti\u011finde callback&#8217;in tetiklenece\u011fini belirler. <code>0<\/code> (varsay\u0131lan), eleman\u0131n herhangi bir k\u0131sm\u0131 g\u00f6r\u00fcn\u00fcr oldu\u011funda tetikler. <code>1<\/code> ise eleman\u0131n tamam\u0131 g\u00f6r\u00fcn\u00fcr oldu\u011funda tetikler. <code>[0, 0.5, 1]<\/code> gibi bir dizi, eleman\u0131n %0, %50 ve %100&#8217;\u00fc g\u00f6r\u00fcn\u00fcr oldu\u011funda ayr\u0131 ayr\u0131 tetiklenmesini sa\u011flar. Genellikle tembel y\u00fckleme i\u00e7in <code>0<\/code> veya <code>0.1<\/code> gibi k\u00fc\u00e7\u00fck bir de\u011fer yeterlidir.<\/li>\n<\/ul>\n<p>Bu ayarlar\u0131 uygulaman\u0131z\u0131n gereksinimlerine ve kullan\u0131c\u0131 deneyimi hedeflerinize g\u00f6re dikkatlice ayarlay\u0131n.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h2>\n<h3>Sonu\u00e7<\/h3>\n<p>Bu rehberde, Vue.js&#8217;te Intersection Observer API kullanarak nas\u0131l performansl\u0131 ve kullan\u0131c\u0131 dostu bir tembel y\u00fckleme g\u00f6rsel bile\u015feni olu\u015fturulaca\u011f\u0131n\u0131 \u00f6\u011frendik. Intersection Observer&#8217;\u0131n performansa olan katk\u0131lar\u0131, basit kullan\u0131m\u0131 ve taray\u0131c\u0131 optimizasyonlar\u0131 sayesinde, eski ve verimsiz y\u00f6ntemlere k\u0131yasla modern web uygulamalar\u0131 i\u00e7in \u00e7ok daha \u00fcst\u00fcn bir \u00e7\u00f6z\u00fcm sundu\u011funu g\u00f6rd\u00fck.<\/p>\n<p>Yer tutucu g\u00f6rseller, hata y\u00f6netimi, CSS ge\u00e7i\u015fleri ve y\u00fckleme g\u00f6stergeleri gibi ek \u00f6zelliklerle bile\u015fenimizi daha da zenginle\u015ftirdik. Bu yakla\u015f\u0131mlar\u0131 kendi Vue.js projelerinize entegre ederek, hem sayfa y\u00fckleme s\u00fcrelerini k\u0131saltabilir hem de kullan\u0131c\u0131lar\u0131n\u0131za daha ak\u0131c\u0131 ve ho\u015f bir deneyim sunabilirsiniz. Unutmay\u0131n, k\u00fc\u00e7\u00fck optimizasyonlar bile b\u00fcy\u00fck farklar yaratabilir!<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<h3 id=\"intersection-observer-t\u00fcm-tarayicilarda-destekleniyor-mu\">Intersection Observer t\u00fcm taray\u0131c\u0131larda destekleniyor mu?<\/h3>\n<p>Intersection Observer API, modern taray\u0131c\u0131lar\u0131n b\u00fcy\u00fck \u00e7o\u011funlu\u011fu taraf\u0131ndan desteklenmektedir (Chrome, Firefox, Safari, Edge). Ancak, daha eski taray\u0131c\u0131lar (\u00f6rn. IE11) i\u00e7in bir polyfill&#8217;e ihtiyac\u0131n\u0131z olabilir. <a href=\"https:\/\/polyfill.io\/v3\/url-builder\/\" target=\"_blank\">Polyfill.io<\/a> gibi servisler veya do\u011frudan bir polyfill k\u00fct\u00fcphanesi (\u00f6rn. <code>intersection-observer<\/code> npm paketi) kullanarak uyumlulu\u011fu art\u0131rabilirsiniz.<\/p>\n<h3 id=\"cok-sayida-gorselde-performans-sorunlari-yasar-miyim\">\u00c7ok say\u0131da g\u00f6rselde performans sorunlar\u0131 ya\u015far m\u0131y\u0131m?<\/h3>\n<p>Hay\u0131r, tam tersine! Intersection Observer API, bu t\u00fcr senaryolar i\u00e7in \u00f6zel olarak tasarlanm\u0131\u015ft\u0131r. Geleneksel scroll event listener&#8217;lar her kayd\u0131rmada tetiklenip pahal\u0131 DOM hesaplamalar\u0131 yaparken, Intersection Observer taray\u0131c\u0131n\u0131n ana i\u015f par\u00e7ac\u0131\u011f\u0131ndan ba\u011f\u0131ms\u0131z \u00e7al\u0131\u015f\u0131r ve yaln\u0131zca kesi\u015fim durumu de\u011fi\u015fti\u011finde geri arama fonksiyonunu tetikler. Bu, \u00e7ok say\u0131da g\u00f6rselin oldu\u011fu sayfalarda bile m\u00fckemmel performans sa\u011flar.<\/p>\n<h3 id=\"video-veya-iframe-icin-de-kullanilabilir-mi\">Video veya iframe i\u00e7in de kullan\u0131labilir mi?<\/h3>\n<p>Kesinlikle! Intersection Observer API, herhangi bir DOM eleman\u0131n\u0131n g\u00f6r\u00fcnt\u00fc alan\u0131yla kesi\u015fimini g\u00f6zlemlemek i\u00e7in kullan\u0131labilir. Bu nedenle, <code><video><\/code>, <code><iframe><\/code> veya hatta karma\u015f\u0131k bile\u015fenler gibi di\u011fer medya veya i\u00e7erik t\u00fcrlerinin tembel y\u00fcklemesi i\u00e7in de ayn\u0131 mant\u0131\u011f\u0131 uygulayabilirsiniz. \u00d6rne\u011fin, bir video eleman\u0131 i\u00e7in <code>src<\/code> yerine <code>data-src<\/code> kullan\u0131p, g\u00f6r\u00fcnt\u00fc alan\u0131na girdi\u011finde <code>src<\/code> \u00f6zelli\u011fini atayabilirsiniz.<\/p>\n<h3 id=\"vue-2-ve-vue-3-te-kullanim-farkliliklari-var-mi\">Vue 2 ve Vue 3&#8217;te kullan\u0131m farkl\u0131l\u0131klar\u0131 var m\u0131?<\/h3>\n<p>Intersection Observer API&#8217;sinin kendisi taray\u0131c\u0131 API&#8217;si oldu\u011fundan, Vue 2 ve Vue 3 aras\u0131ndaki temel kullan\u0131m mant\u0131\u011f\u0131 ayn\u0131d\u0131r. Ya\u015fam d\u00f6ng\u00fcs\u00fc kancalar\u0131n\u0131n isimleri ve Kompozisyon API&#8217;sinin (Composition API) Vue 3&#8217;te getirdi\u011fi yeni reaktivite modeli d\u0131\u015f\u0131nda b\u00fcy\u00fck bir fark yoktur. Vue 3&#8217;te <code>setup()<\/code> fonksiyonu ve <code>onMounted<\/code>, <code>onBeforeUnmount<\/code> gibi kancalarla Kompozisyon API&#8217;sini kullanarak bu bile\u015feni daha mod\u00fcler bir \u015fekilde yazabilirsiniz. \u00d6rne\u011fin:<\/p>\n<pre><code class=\"language-js\">\/\/ Vue 3 Composition API \u00f6rne\u011fi\nimport { ref, onMounted, onBeforeUnmount } from 'vue';\n\nexport default {\n  props: ['src', 'alt', 'placeholderSrc'],\n  setup(props) {\n    const imageRef = ref(null);\n    const isLoaded = ref(false);\n    const isError = ref(false);\n    const currentSrc = ref(props.placeholderSrc);\n    let observer = null;\n\n    const handleIntersect = (entries) => {\n      entries.forEach((entry) => {\n        if (entry.isIntersecting) {\n          currentSrc.value = props.src;\n          observer.unobserve(entry.target);\n        }\n      });\n    };\n\n    const handleImageLoad = () => {\n      isLoaded.value = true;\n      isError.value = false;\n    };\n\n    const handleImageError = () => {\n      isError.value = true;\n      isLoaded.value = true;\n      currentSrc.value = 'https:\/\/via.placeholder.com\/150?text=Hata';\n    };\n\n    onMounted(() => {\n      const options = {\n        root: null,\n        rootMargin: '0px 0px 200px 0px',\n        threshold: 0,\n      };\n      observer = new IntersectionObserver(handleIntersect, options);\n      if (imageRef.value) {\n        observer.observe(imageRef.value);\n      }\n    });\n\n    onBeforeUnmount(() => {\n      if (observer) {\n        observer.disconnect();\n      }\n    });\n\n    return {\n      imageRef,\n      isLoaded,\n      isError,\n      currentSrc,\n      handleImageLoad,\n      handleImageError,\n    };\n  },\n};\n<\/code><\/pre>\n<h3 id=\"v-lazy-load-gibi-bir-direktif-olusturmak-mumkun-mu\"><code>v-lazy-load<\/code> gibi bir direktif olu\u015fturmak m\u00fcmk\u00fcn m\u00fc?<\/h3>\n<p>Evet, Intersection Observer API&#8217;sini kullanarak \u00f6zel bir Vue direktifi olu\u015fturmak kesinlikle m\u00fcmk\u00fcnd\u00fcr. Bu, tembel y\u00fckleme mant\u0131\u011f\u0131n\u0131 do\u011frudan bir HTML eleman\u0131na <code>v-lazy-load=\"image.src\"<\/code> \u015feklinde uygulaman\u0131za olanak tan\u0131r ve bile\u015fen olu\u015fturmaktan daha basit bir kullan\u0131m sa\u011flayabilir. Direktif i\u00e7inde <code>mounted<\/code> hook&#8217;unda Intersection Observer&#8217;\u0131 ba\u015flat\u0131r ve eleman\u0131n g\u00f6r\u00fcn\u00fcrl\u00fc\u011f\u00fcne g\u00f6re <code>src<\/code> \u00f6zelli\u011fini atars\u0131n\u0131z. Bu yakla\u015f\u0131m, basit tembel y\u00fckleme senaryolar\u0131 i\u00e7in olduk\u00e7a pop\u00fclerdir.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma\nWeb uygulamalar\u0131nda performans, kullan\u0131c\u0131 deneyimi ve SEO i","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[874],"tags":[],"class_list":{"0":"post-34853","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-server","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Intersection Observer API ile Vue.js&#039;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Intersection Observer API ile Vue.js&#039;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma\" \/>\n<meta property=\"og:description\" content=\"Intersection Observer API ile Vue.js&#039;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma Web uygulamalar\u0131nda performans, kullan\u0131c\u0131 deneyimi ve SEO i\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-22T18:41:35+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma\",\"datePublished\":\"2025-11-22T18:41:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\"},\"wordCount\":2282,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Server\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\",\"name\":\"Intersection Observer API ile Vue.js'te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-22T18:41:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Intersection Observer API ile Vue.js'te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/","og_locale":"tr_TR","og_type":"article","og_title":"Intersection Observer API ile Vue.js'te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma","og_description":"Intersection Observer API ile Vue.js'te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma Web uygulamalar\u0131nda performans, kullan\u0131c\u0131 deneyimi ve SEO i","og_url":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-22T18:41:35+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"12 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma","datePublished":"2025-11-22T18:41:35+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/"},"wordCount":2282,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Server"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/","url":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/","name":"Intersection Observer API ile Vue.js'te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-22T18:41:35+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/intersection-observer-api-ile-vue-jste-tembel-yuklenen-gorsel-bileseni-olusturma\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Intersection Observer API ile Vue.js&#8217;te Tembel Y\u00fcklenen G\u00f6rsel Bile\u015feni Olu\u015fturma"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34853","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34853"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34853\/revisions"}],"predecessor-version":[{"id":34854,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34853\/revisions\/34854"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}