1. Veriyi GET değil POST metoduyla gönderin.
2. Veriyi Cookie'ye kaydedin ve diğer sayfada cookie'den okuyun.
3. Veri sadece front-end'de kullanılacaksa sessionStorage'a kaydedin ve diğer sayfada da sessionStorage'dan okuyun.
4. Veriyi session yoluyla iletin.
5. GET ile gönderdiğiniz parametreleri şifreleyin ve diğer sayfada şifreyi çözün.
6. Verileri veritabanına kaydedin ve diğer sayfada veritabanını kontrol edin.
... aklıma gelenler bunlar.
Ama sizin yapmak istediğiniz şey, bir kullanıcı login olmuşsa bunu session'a kaydetmek ve index.php'de de session'ı kontrol etmek.
B sitesinin veritabanına bağlanma işini doğrudan B sitesinden erişerek yapabilirsiniz.
1. B sitesinde web servis gibi çalışacak bir sayfa oluşturun. Bu sayfa kendisine POST yöntemiyle gelen verileri alsın, kendi veritabanına yazsın.
2. A sitesinden bu B sitesindeki sayfaya POST isteği gönderin.
B sitesinde integration.php sayfası
$productId = $_POST["product_id"];
$newPrice = $_POST["price"];
updateDatabase("UPDATE products SET price='$newPrice' WHERE id=$productId");
echo json_encode(["status"=>true, "message"=>"Price updated successfully"]);
exit();
A sitesinde bir ürünün fiyatını kendi veritabanına kaydederken, B sitesine de durumu bildiren sayfa
// ... A sitesi kendi veritabanında güncelleme işini yaptıktan sonra B sitesine de verileri gönderiyor...
$fields = ['product_id' => '1234', 'price' => '19.90'];
$postvars = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://b.site/integration.php");
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
$result = curl_exec($ch);
curl_close($ch);
// Burada da dönen $result değerine göre işlemin başarılı/başarısız oluşuna göre aksiyon alınabilir...
Dikkat: Bu örneklerde hiçbir güvenlik önlemi alınmadığı için saldırıya çok açık.
B sitesinde hangi siteden istek atıldığının tespiti, SQL injection önlemleri, A sitesinin B sitesine istek göndermeden önce B sitesinde oturum açması veya bir token alması...
Ama temel olarak sunucular arası veritabanı bağlantısı kuramıyorsanız siz de böyle bir yola başvurabilirsiniz.
Eğer her component kendi isteğinin verilerini sadece kendisi kullanacaksa istekleri component'lerin kendi içinde tutmanız iyidir.
Eğer bazı istekler birden çok component'i etkilecekse bu yönetimi ana component'te tutmak iyidir.
React, ana component'te herhangi bir state değişimi olduğunda tüm alt component'lerini tekrar kontrol eder ve DOM'da bir değişiklik gerekip gerekmediğine bakar. Eğer gerekmiyosa DOM'u güncellemez. Ama yine de bu kontrolün de bir maliyeti vardır.
Örneğin ana component'inizde 5 tane alt component var. Bu component'lerden hepsi kendi isteğini atıyor ve dönen veriyi kendi içinde işliyor. Ama biri var ki, dönen sonucu işledikten sonra bir de ana component'e veri iletmesi gerekiyor.
İşte bu durumda React ana component'te bir aksiyon gerçekleştiği için 5 component'i birden yeniden taramak zorunda kalıyor ki bu değişikliğin onları etkileyip etkilemediğinden emin olsun...
Bu durumun önüne geçmelisiniz. Kendi yağında kavrulan 4 component'inizin tekrar kontrol edilmemesini sağlamalısınız. Bunun için de bu 4 component'i React.memo()
fonksiyonu içine alabilirsiniz.
Böylelikle React bu component'leri, onlara gönderdiği parametrelerde bir değişiklik olmadığı için, yeniden kontrol etmeyecek. Onları sanki pure component gibi varsayıp geçecek.
Ben bu durumda muhtemelen 4 component'i React.memo()
korumasına alırdım ama 5.component'in isteğini o component'in içinde değil ana component'te atardım. Sonucu da props yoluyla 5.component'e iletirdim.
Ama tabi hangi yöntemi kullandığınızda daha iyi performans alacağınız sizin kurgunuza bağlı. Belki de tüm istekleri ana component'te atmalı ve sonuçları diğer component'lere prop yoluyla iletmelisinizdir...
<div id="infinite-scroll">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
#infinite-scroll { width: 400px; height:400px; padding:5px; overflow-y: scroll;}
.item { margin:5px; height:150px; background-color: #ccc; }
const $scrollView = document.getElementById("infinite-scroll");
$scrollView.addEventListener("scroll", function (e) {
const scrollTop = e.target.scrollTop;
const contentHeight = e.target.scrollHeight - e.target.offsetHeight;
if (contentHeight <= scrollTop) {
alert("son!")
}
})
web.dev sitesinden bulduğum aşağıdaki başlıklara göz atabilirsiniz.
Bazı Animasyonlar Neden Yavaş Çalışır?
Modern tarayıcılar iki CSS özelliğini ucuza canlandırabilir: transform
ve opacity
.
Başka bir animasyon yaparsanız, saniyede 60 kare (FPS) ipeksi pürüzsüzlükte bir hız elde edemezsiniz. Bu yazı, bunun neden böyle olduğunu açıklıyor.
Animasyon Performansı ve Kare Hızı
Web'de herhangi bir animasyon kullanılırken hedefin 60 FPS'lik bir kare hızı olduğu yaygın olarak kabul edilmektedir. Bu kare hızı, animasyonlarınızın düzgün görünmesini sağlayacaktır. Web'de bir frame, ekranı güncellemek ve yeniden render etmek için gereken tüm işleri yapmak için gereken süredir. Her frame 16.7ms (1000ms / 60 ≈ 16.7) içinde tamamlanmazsa, kullanıcılar gecikmeyi algılayacaktır.
Render İşlem Sırası
Bir web sayfasında bir şey görüntülemek için tarayıcının aşağıdaki sıralı adımlardan geçmesi gerekir:
- Style: Elemente uygulanan stiller hesaplanır.
- Layout: Her elemanın geometrik şekli ve konumu bulunur.
- Paint: Her elementin pikselleri katmanlara doldurulur.
- Composite: Katmanlar ekrana çizilir.
Bu 4 atım tarayıcıların rendering pipeline'ı olarak bilinir.
Zaten yüklenmiş bir sayfada bir şeyi anime ettiğinizde, bu adımların tekrar ele alınması gerekir. Bu süreç, animasyonun gerçekleşmesi için değiştirilmesi gereken adımdan başlar.
Daha önce yazdığım gibi, bu adımlar sıralıdır. Örneğin, layout'u değiştiren bir animasyon uygularsanız, paint ve birleştirme adımlarının da yeniden çalışması gerekir. Bu nedenle, düzeni değiştiren bir şeyi canlandırmak, yalnızca kompozisyonu değiştiren bir şeyi canlandırmaktan daha pahalıdır.Daha önce yazdığım gibi, bu adımlar sıralıdır. Örneğin, layout'u değiştiren bir animasyon uygularsanız, paint ve composite adımlarının da yeniden çalışması gerekir. Bu nedenle, layout'u değiştiren bir animasyon, yalnızca composite adımını değiştiren bir animasyondan daha maliyetlidir.
Layout Animasyon Özellikleri
Layout değişiklikleri, değişiklikten etkilenen tüm öğelerin geometrisinin (konum ve boyut) hesaplanmasını içerir. Bir elementi değiştirirseniz, diğer elemanların geometrisinin de yeniden hesaplanması gerekebilir. Örneğin, <html> öğesinin genişliğini değiştirirseniz, alt öğelerinden herhangi biri etkilenebilir. Öğelerin taşma ve birbirini etkileme şekli nedeniyle, ağacın daha aşağısındaki değişiklikler bazen en üste kadar yerleşim hesaplamalarına neden olabilir.
Görünür öğelerin ağacı ne kadar büyükse, layout hesaplamalarının yapılması o kadar uzun sürer.
Paint Animasyon Özellikleri
Paint, elementlerin ekranda hangi sırayla boyanacağını belirleme işlemidir. Genellikle pipeline'daki tüm görevlerin en uzun sürenidir.
Uygulamanızdaki öğelerin katmanlar halinde nasıl gruplandığına bağlı olarak, değişenlerin yanı sıra diğer öğelerin de boyanması gerekebilir.
Composite Animasyon Özellikleri
Composite (birleştirme), sayfayı katmanlara ayırma, sayfanın nasıl görünmesi gerektiğiyle ilgili bilgileri piksellere dönüştürme ve sayfayı oluşturmak için katmanları bir araya getirme (birleştirme) işlemidir.
opacity
animasyonunun maliyeti düşükler listesine dahil edilmesinin nedeni budur. Bu özellik kendi katmanında olduğu sürece, bu özellikteki değişiklikler composite (birleştirme) adımı sırasında GPU tarafından işlenebilir. Chromium tabanlı tarayıcılar ve WebKit, opacity
ve transform
animasyonu olan herhangi bir öğe için yeni bir katman oluşturur.
Katman nedir?
Tarayıcının, canlandırılacak veya geçişi yapılacak şeyleri yeni bir katmana yerleştirerek, diğer her şeyi değil, yalnızca bu öğeleri yeniden boyaması gerekir. Photoshop'un, birlikte hareket ettirilebilen bir grup öğe içeren katman kavramına aşina olabilirsiniz. Tarayıcı oluşturma katmanları bu fikre benzer.
Tarayıcı, yeni bir katmanda hangi öğelerin olması gerektiğine karar vermekte iyiyse de, birini kaçırırsa, katman oluşturmaya zorlamanın yolları vardır. Bunu, yüksek performanslı animasyonlar nasıl oluşturulur bölümünde bulabilirsiniz.
Ancak, her katman RAM'de (geçici bellekte) yer tutacağından, yeni katman oluştururken iyi düşünmek gerekir.
Sınırlı belleğe sahip cihazlarda yeni katmanlar oluşturmak, çözmeye çalıştığınızdan daha fazla performans sorununa neden olabilir. Ek olarak, her katmanın dokularının GPU'ya yüklenmesi gerekir. Bu nedenle, CPU ve GPU arasındaki bant genişliğininin de kısıtlamasına takılarak performans kaybı yaşayabilirsiniz.
Yüksek Performanslı CSS Animasyonları Nasıl Yapılır?
Bu kılavuz size yüksek performanslı CSS animasyonlarının nasıl oluşturulacağınızı anlatır.
Bu kılavuzun önerdiği tüm CSS özellikleri çok iyi tarayıcı uyumluluğuna sahiptir:
... Bu sayfanın içeriği çok uzun olduğu için şu an çevirecek zamanım yok ama basit bir dil kullanıldığı için kolayca anlayabilirsiniz.
Sorumun cevabını Next.js dokümantasyonunda buldum.
Custom Server
Varsayılan olarak next.js, next start
ile kendi sunucusunu başlatır.
Eğer sizin kendi backend'iniz varsa bunu Next.js ile kullanmaya devam edebilirsiniz.
Özel bir Next.js sunucusu, özel sunucu kalıplarını kullanabileceğiniz bir server başlatmanıza olanak verir.
Çoğunlukla buna ihtiyacınız omaz ama bu tam bir özelleştirme yapmanıza olanak verir.
Lütfen yalnızca Next.js'in routing yapısı sizin ihtiyaçlarınızı karşılayamıyorsa bir custom server kullanmanız gerektiğini unutmayın.
Bir custom server önemli performans optimizasyonlarını kaldıracaktır. Mesela serverless fonksiyonlar ve Automatic Static Optimization.
Aşağıdaki custom server örneğine bir göz atın:
// server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// middleware kullanırken `hostname` ve `port` aşapıdaki şekilde sağlanmalıdır.
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// `url.parse` için ikinci parametre olarak true vermeyi unutmayın.
// Bu, URL'nin query bölümünü ayrıştırmasını söyler.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') await app.render(req, res, '/a', query)
else if (pathname === '/b') await app.render(req, res, '/b', query)
else await handle(req, res, parsedUrl)
}
catch (err) {
console.error('İşlem sırasında hata oluştu', req.url, err)
res.statusCode = 500
res.end('internal server error')
}
}).listen(port, (err) => {
if (err) throw err
console.log(`> Sunucu Hazır: http://${hostname}:${port}`)
})
})
server.js, babel veya webpack'ten geçmez.
Bu dosyanın gerektirdiği syntax ve import'ların, çalıştırdığınız geçerli node sürümüyle uyumlu olduğundan emin olun.
Custom server'ı çalıştırmak için package.json içindeki script komutlarını şu şekilde güncellemeniz gerekir:
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
Custom server, sunucuyu Next.js uygulamasına bağlamak için aşağıdaki içe aktarmayı kullanır:
const next = require('next')
const app = next({})
İlk satırdaki next
, aşağıdaki parametreleri alabilen bir objeyi parametre olarak alan bir fonksiyon döndürür:
- dev: [Boolean] - Next.js'in geliştirici modunda başlayıp başlamayacağı. Varsayılan:
false
- dir: [String] - Next.js projesinin konumu. Varsayılan: "."
- quiet: [Boolean] - Sunucu bilgilerini içeren hata mesajlarını gizlemek istiyor musun? Varsayılan:
false
- conf: [object] - next.config.js dosyası için kullanacağınız object'in aynısı. Varsayılan:
{}
İkinci satırdakinext
fonksiyonunun sonucu atanmış olanapp
, Next.js'in istekleri gerektiği gibi kullanmasını sağlamak için kullanılabilir.
Dosya Sistemine Göre Yapılan Routing'i Kaldırmak
Varsayılan olaran Next.js, pages klasörü altına yerleştirilen dosya-klasör yapısına göre bir routing kullanır.
Eğer Custom Server kullanarak aynı sayfayı iki farklı link'in render etmesi sağlanıyorsa bu durum SEO ve UX açısından sorunlara yol açabilir.
Bu davranışı devre dışı bırakmak ve sayfalardaki dosyalara dayalı yönlendirmeyi önlemek için next.config.js dosyasını açın ve useFileSystemPublicRoutes
yapılandırmasını devre dışı bırakın:
module.exports = {
useFileSystemPublicRoutes: false,
}
useFileSystemPublicRoutes
öğesinin SSR'den dosya adı yollarını devre dışı bıraktığını unutmayın.
İstemci tarafı yönlendirme hala bu yollara erişebilir.
Bu seçeneği kullanırken, programatik olarak istemediğiniz rotalara navigasyona karşı önlem almalısınız.
İstemci tarafı yönlendiricisini, dosya adı yollarına istemci tarafı yönlendirmelerine izin vermeyecek şekilde de yapılandırmak isteyebilirsiniz. Bunun için router.beforePopState
'e bakın.
https://jquery.com/upgrade-guide/3.0/
Bu saufada tam olarak geçiş için neler yapılması gerektiğini anlatıyor.
Ayrıca bu kaynakta JQuery Migrate Plugin başlığı altında şöyle yazıyor:
jQuery 1.9/2.0'da yapılan büyük değişikliklerde olduğu gibi, eski kodun 3.0 sürümüne geçişini basitleştirmek için jQuery Migrate Plugin'in yeni bir sürümünü oluşturduk. Bu eklentiyi bir yükseltme aracı olarak kullanmanızı şiddetle tavsiye ederiz, kodunuzu etkileyebilecek büyük değişikliklerin çoğu hakkında özel tavsiyeler verecektir.
Sonra da aynı başlık altında adım adım ne yapmanız gerektiği anlatılmış.
1. Önce sayfada kullandığınız jquery sürümünü 1.x veya 2.x'in en son sürümüne yükseltin. Yani mesela 1.12.0 sürümünü kullanıyorsanız artık 1.12.4 sürümünü kullanın.
2. Sıkıştırılmamış jQuery Migrate 1.x Eklentisini sayfaya ekleyin.
3. Mecbur değil ama önerilir: sonraki sürümler genellikle jQuery'nin en son sürümleriyle en uyumlu olduğundan, kullanımda olan tüm eklentileri güncelleyin.
4. Bir kılavuz olarak JQMIGRATE 1.x uyarı dokümantasyonunu kullanarak sayfayı test edin ve konsolda görünen tüm uyarıları çözün.
5. JQuery Migrate 1.x eklentisini kaldırın ve sayfadaki güncellenmiş jQuery kodunun yalnızca en son jQuery 1.x/2.x kullanımdayken düzgün şekilde çalışmaya devam etmesini sağlayın. Yani sayfanız migrate olmadan JQuery 1.12.4 ile düzgün şekilde çalışabiliyor durumda olsun.
-- Eğer sizin sayfanızda zaten JQuery 1.12.4 yüklüyse ve hiç hata almıyorsanız direkt 6.adımdan da başlayabilirsiniz.
6. Sayfadaki jQuery sürümünü en son 3.x sürümüne (3.6.1) yükseltin ve sıkıştırılmamış jQuery Migrate 3.x eklentisini sayfaya ekleyin.
7. JQMIGRATE 3.x uyarı dokümantasyonunu kılavuz olarak kullanarak sayfayı test edin ve konsolda görünen tüm uyarıları çözün. Üçüncü taraf eklentilerdeki hataları eklenti yazarına bildirin çünkü bu eklenti yeni jquery sürümüyle uyumlu çalışamıyor olabilir.
8. jQuery Migrate 3.x eklentisini kaldırın ve sayfanın düzgün şekilde çalışmaya devam etmesini sağlayın.
Sadece hızlıca bir göz atmanız da yetebilir belki.
Ben çok kullanılan bazı fonksiyonlardaki değişimleri yazdım:
1. Kodunuzda $(window).load()
kullanımı varsa bunu $(window).on('load')
şeklinde değiştirmelisiniz.
$(window).load(function() {
// ...kodlar
}
yerine şu olmalı:
$(window).on('load', function() {
// ...kodlar
}
).load(function
geçen ifadeleri ).on('load', function
şeklinde bul-değiştir mantığıyla değiştirebilirsiniz.
2. Kullanılan tarayıcıyı algılamak için artık $.browser
kullanamazsınız. Kullanılan tarayıcıyı tespit etmenin başka yollarını kullanmalısınız.
if ($.browser == 'MSIE') {
// Ben internet explorer'ım diyen kodlar...
}
// yerine şöyle bir kod kullanılabilir:
const regex = RegExp('MSIE*');
if (regex.test(navigator.userAgent)) {
// Ben internet explorer'ım diyen kodlar...
}
3. addSelf()
yerine addBack()
kullanın. Basitçe bul-değiştir mantığıyla halledebilirsiniz.
1,2,3 için Kaynak: https://www.computerminds.co.uk/articles/upgrading-jquery-1x-version-3x
4. size()
yerine length
kullanın. Kaç eleman seçtiğinizi length
ile öğrenebilirsiniz.
5. $.unique()
fonksiyonunun adı değişti: $.uniqueSort()
. İşlevi aynı, sadece fonksiyon adı değişti.
6. $.ready
ifadesi destekleniyor. $.when
ile veya Promise
yapılarıyla kullanılabilir. Örn:
$.when( $.ready, $.getScript("optional.js") ).then(function() {
// document hazır olduğunda optional.js yüklenip çalıştırlacak...
}).catch( function() {
// işlem sırasında bir hata oluşmuşsa burası çalışacak...
});
7. .width()
, .height()
, .css("width")
, and .css("height")
eskiden hep tam sayı olarak dönerdi. Artık daha hassas veri döndüğü için tam sayı yerine küsüratlı sayı da dönebilir.
8. .on("ready", fonksiyon)
kaldırıldı. Bunun yerine $(fonksiyon)
kullanın.
9. .bind()
ve .delegate()
kaldırıldı. Bunlar yerine .on()
var. Aynı şekilde .unbind()
ve .undelegate()
yerine de .off()
kullanılmalı.
4-9 Kaynak: https://jquery.com/upgrade-guide/3.0/
const newStatus = !$(this).prop('checked');
$(this).prop('checked', newStatus);
şeklinde prop()
fonksiyonunu kullanmayı deneyebilirsiniz.
O zaman ekran genişliğini kontrol edip öyle çalıştırın.
<script id="willRemove">
(function () {
var options = {
call: "0 000 000 00 00", // Call phone number
whatsapp: "0 000 000 00 00", // WhatsApp number
call_to_action: "Nasıl yardımcı olabilirim?", // Call to action
button_color: "#FF6550", // Color of button
position: "left", // Position may be 'right' or 'left'
order: "call,whatsapp", // Order of buttons
};
var proto = 'https:', host = "getbutton.io", url = proto + '//static.' + host;
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = url + '/widget-send-button/js/init.js';
s.onload = function () { WhWidgetSendButton.init(host, proto, options); };
var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x);
})();
// Ekran genişliği 600px veya altındaysa silinsin...
if(window.innerWidth <= 600) {
setTimeout(function(){
// Bu #willRemove id'li script tag'ı kendini 10 milisaniye sonra imha edecek...
document.getElementById('willRemove').remove();
},10);
}
</script>
Kodun çalıştıktan sonra kendini remove etmesini sağlayabilirsiniz.
Bunun için bu kodları bir script tag'ına alın ve bu tag'a bir id verin.
Sonra setTimeout()
fonksiyonuyla kodun çalışmasına yetecek kadar kısa bir an izin verin ve bu tag'ı komple silin.
<script id="willRemove">
(function () {
var options = {
call: "0 000 000 00 00", // Call phone number
whatsapp: "0 000 000 00 00", // WhatsApp number
call_to_action: "Nasıl yardımcı olabilirim?", // Call to action
button_color: "#FF6550", // Color of button
position: "left", // Position may be 'right' or 'left'
order: "call,whatsapp", // Order of buttons
};
var proto = 'https:', host = "getbutton.io", url = proto + '//static.' + host;
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = url + '/widget-send-button/js/init.js';
s.onload = function () { WhWidgetSendButton.init(host, proto, options); };
var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x);
})();
setTimeout(function(){
// Bu #willRemove id'li script tag'ı kendini 10 milisaniye sonra imha edecek...
document.getElementById('willRemove').remove();
},10);
</script>