38
Web'in öksüz evladı: JavaScript JavaScript Web tarihi boyunca çok az insanın önemsediği, çok güçlü, prototype tabanlı, Object-Orient bir dildir. Sunumun amacı: JavaScript Performans Optimizasyonu İrfan Durmuş

Javascript Performance Optimisation

Embed Size (px)

Citation preview

Page 1: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

JavaScript Web tarihi boyunca çok az insanın önemsediği, çok güçlü, prototype tabanlı, Object-Orient bir dildir.

Sunumun amacı:

JavaScript Performans Optimizasyonu

İrfan Durmuş

Page 2: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

JavaScript Tarihi: Kısaca..

Geleceğin Teknolojisi: Nerelerde JS kullanılıyor?

Nonblocking pattern: Optimizasyon da ilk adım

Global variables suck!: Global yerine local daha iyi bir seçim

DOM'a erişimin maaliyeti: Git gel Gecko 6 saat

Event binding: Tek binding ile toplu event handle etmek varken..

Döngü içindeki değişkenler: Aynı değeri defalarca istemek gereksiz

Page 3: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

JavaScript TarihiKısaca..

Page 4: Javascript Performance Optimisation

JavaScript Tarihi

JS, şu anki Mozilla Vakfı CTO'su Brendan Eich tarafından Netscape için geliştirilmiştir.

İlk kez 1995'de Netscape ile dağıtıldı.

Mocha -> LiveScript -> JavaScript

1996 Kasım'da standartlaştırma için Ecma International'a gönderildi.

Page 5: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

Geleceğin TeknolojisiJavaScript Nerelerde Kullanılıyor?

Page 6: Javascript Performance Optimisation

JavaScript: Geleceğin Teknolojisi

250 Milyon web sitesi

PDF Dosyaları

SSB: Site Specific Browsers

Gmail, Twitter, Facebook masaüstü uygulamaları.

Mobil Uygulamalar, Masaüstü Widget'lar

PhoneGap, JSCocoa, Apple Widgets, Microsoft Gadgets

Tarayıcı eklentileri, Masaüstü uygulamaları

Opera, Chrome Eklentileri, Firebug, Chrome Webstore

Page 7: Javascript Performance Optimisation

JavaScript: Geleceğin Teknolojisi

Sunucu tarafında;

Nodejs/V8, mod_js/SpiderMonkey

Onlarca CommonJS implementasyonu çözümü

CommonJS ile;

Sunucu tarafında JavaScript Uygulamaları (CouchDB)

Komut satırı uygulamaları (NodeJS)

Desktop/GUI Uygulamaları (Widget'lar)

Hibrid uygulamalar (Adobe Air)

Page 8: Javascript Performance Optimisation

Başlamadan önce...

Daha iyi anlamak için bilinmesi gerekenler;

JavaScript bir değişkenin içerisinde method taşıyabilir, yani integer, string gibi function type'ımız vardır.

Herşey birer object'dir, yeni bir object için 'class' yerine 'function' kullanırız.

Anonymous function, isimsiz bir scope'dur. Aşağıdaki şekilde yazılır ve parametre gönderilir. Tabii ki bu da objectdir.

(function($, window){

// code...

}(jQuery, wndow));

Prototype tabanlı bir dildir, her objenin bir prototype'ı vardır. Prototype'daki bir değişkene erişirken, 'prototype'sız kullanılır. Aşağıdaki örneği inceleyelim;

function Users(){};

Users.prototype.getUser = function(id){ return id;};

var id = 1,

user = new Users();

user.getUser(id);

Page 9: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

Nonblocking PatternOptimizasyonda İlk Adım

Page 10: Javascript Performance Optimisation

Nonblocking Pattern

Nonblocking nedir ve neyi amaçlar?

Tarayıcı script tagını gördüğünde, diğer tüm içeriğin yüklenmesini durdurur (image'ler, css'ler vb.) ve scriptleri yüklemeye başlar.

Script dosyaları yüklendikten sonra derlenme süreci vardır.

Derlenme sürecinde bir sonraki script dosyası da diğer tüm içerik gibi bekletilir.

Inline JavaScript satırları da yorumlanması için JS Engin'e gönderildiğinde diğer tüm içerik bekletilir.

Nonblocking pattern, diğer içeriği engellemeden JavaScript çalıştırmayı amaçlar.

Page 11: Javascript Performance Optimisation

Nonblocking Pattern

Script elementlerinin olduğu bir sayfanın yüklenişi..

0 200 400 600 800 1000 1200 1400 1600 1800 2000

milisaniye

main.js

shared.js

users.js

other.js

style.css

Yükleme süresi Çalıştırma süresi

Page 12: Javascript Performance Optimisation

Nonblocking Pattern

Script tag'leri nerede konumlanmalıdır?

…..

<head>

<meta http-equiv="Content-type" content="text/html; charset=utf-8">

</head>

<body>

…..

…..

<script src="js/main.js"></script>

</body>

</html>

Page 13: Javascript Performance Optimisation

Nonblocking Pattern

Nonblocking Teknikleri;

Gecikmeli Scriptler (Deferred Scripts)HTML 4, eski bir teknik ve çoğu taraycı desteklemediği için bahsetmeyeceğiz.

Dinamik Script Elementivar script = document.createElement('script'); script.src=”bar.js”;

document.getElementsByTagName('head')[0].appendChild(script);

AJAX ile Script InjectionXMLHttpRequest aracılığıyla js dosyası alınır ve body e append edilir.

var x = new XMLHttpRequest();

x.open('get', 'main.js', true);

x.onreadystatechange = function(){

//.. xhr kontrol ve append kodları burada..

};

Page 14: Javascript Performance Optimisation

Nonblocking Pattern

Önerilen TeknikTüm dosyaları birleştirin.loader.js ve main.js

Minimizer ve Obfuscator kullanın.Google closure veya YUI

Script taglarını </body> den hemen önce yerleştirin. var script = document.createElement('script'); script.src=”bar.js”;

document.getElementsByTagName('head')[0].appendChild(script);

Sayfadaki tüm argumanların tamamlanmasını bekleyin.Jquery'deki document.ready nin sırrı..

Script tag'ini dinamik oluşturun.loader.js nin görevi: document.createElement('script');

Page 15: Javascript Performance Optimisation

Nonblocking Pattern

Loader çözümleriLazyLoad librarygithub.com/rgrove/lazyload

YUI (Yahoo User Interfaces)http://developer.yahoo.com/yui/

Kendi yazacağınız, 20 satır civarında bir loader. Script tag'i event leri ile script dosyasının yüklenip hazır olduğunu anlayabiliyoruz. Hiç bir

script dosyası sayfa tamamen hazır olmadan yüklenmemeli ve çalıştırılmamalı. obj.readyState (ie) ve/ya obj.onLoad (diğerleri) eventleri beklenmeli. Bu loader, dinamik olarak oluşturacağı script objesine src olarak yüklemek istediğiniz dosya yolunu verdikten sonra sayfaya append etmeli.

Page 16: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

Global Variables Suck!Global yerine local çok daha iyi bir seçim.

Page 17: Javascript Performance Optimisation

Global Variables Suck

İçiçe property'leri olan globaldeki bir objenin propertylerine erişmek;

var obj = {};

obj.smth = {};

obj.smth.more = {};

obj.smth.more.first = 2;

obj.smth.more.second = 3;

obj.smth.more.data;

function sum_nested_vars(){

for(var i = 0; i < 200000; i++){

obj.smth.more.data = obj.smth.more.first + obj.smth.more.second;

}

return obj.smth.more.data;

}

sum_nested_vars();

Page 18: Javascript Performance Optimisation

Global Variables Suck

Global değişkenlere/methodlara erişmek

var first = 2,

second = 3;

function sum_global_vars(){

var data;

for(var i = 0; i < 200000; i++){

data = first + second;

}

return data;

}

sum_global_vars();

Page 19: Javascript Performance Optimisation

Global Variables Suck

Local değişkenler kullanmak

function sum_local_vars(){

var first = 2,

second = 3,

data;

for(var i = 0; i < 200000; i++){

data = first + second;

}

return data;

}

sum_local_vars();

Page 20: Javascript Performance Optimisation

Global Variables Suck

GLOBAL AS NESTED

430 milisaniye

GLOBAL DEĞİŞKEN

300 milisaniye

LOCAL DEĞİŞKEN

1 milisaniye

Local Değişken

Global Değişken

Global Obje

0 50 100 150 200 250 300 350 400 450 500

Milisaniye

Page 21: Javascript Performance Optimisation

Global Variables Suck

// …

function sum_nested_vars(){

var first = obj.smth.more.first,

second = obj.smth.more.second,

data = obj.smth.more.data;

for(var i = 0; i < 200000; i++){

data = first + second;

}

obj.smth.more.data = data;

return data;

}

// ...

// ...

function sum_nested_vars(){

for(var i = 0; i < 200000; i++){

obj.smth.more.data = obj.smth.more.first + obj.smth.more.second;

}

return obj.smth.more.data;

}

// ...

Nested global objeden local değişkene optimizasyon. Uygulamanın büyüklüğüne göre bu farkın çok açılacağını veya kapanacağını unutmayın!

430 milisaniye 1 milisaniye

Page 22: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

DOM'a Erişimin MaaliyetiGit gel Gecko altı saat.

Page 23: Javascript Performance Optimisation

DOM'a Erişimin Maliyeti

function innerHtmlBadWay(){

for (var i = 0; i < 10000; i++){

document.getElementById('myDiv').innerHTML += 'x';

}

}

innerHtmlBadWay();

Her bir işlem için layout engine'e erişmektense, tüm datayı bir variable içerisinde toplayıp tek seferde yazmak çok daha hızlıdır.

function innerHtmlGoodWay(){

var data = 'x';

for (var i = 0; i < 10000; i++){

data += 'x';

}

document.getElementById('myDiv').innerHTML += data;

}

innerHtmlGoodWay();

X

Page 24: Javascript Performance Optimisation

DOM'a Erişimin Maliyeti

Değişkene atamak

Döngü içinde erişmek

0 500 1000 1500 2000 2500 3000 3500

Milisaniye

10.000 kez DOM'a innerHTML ile erişmek yerine datayı değişkene atayıp bir kez layout engine gitmek arasındaki farkı gösteren grafik.

For içinde erişmek: 3050 milisaniye

Variable'a atamak: 1 milisaniye

Page 25: Javascript Performance Optimisation

DOM'a Erişimin Maliyeti

JS Engine( V8 / SpiderMonkey )

Layout Engine( WebKit / Gecko )

Requestdocument.getElementByID('mydiv');

Response<div id='mydiv'></div>

6 saat'lik mesafe

NEDEN?

Page 26: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

Event BindingTek binding ile toplu event handle etmek varken..

Page 27: Javascript Performance Optimisation

Event Binding

Event'ler, click, hover, focus, keypress, mouseover vb. DOM eventleri olabileceği gibi, developer tarafından tanımlanmış özel eventler da olabilir.

Event nedir?

Page 28: Javascript Performance Optimisation

Event Binding

document.addEventListener('click', function(){

// code...

});

veya

function foo(){

// code...

};

document.addEventListener('click', foo);

Event listener

Page 29: Javascript Performance Optimisation

Event Binding

Bir event'in işleyişi

<div id=”container”>

<ul id=”navigation”>

<a href=”/main”>Home</a>

<li>

event

Page 30: Javascript Performance Optimisation

Event Binding

Bir event'in işleyişi

Event, window objesine kadar parent'ler üzerinden ilerler.

<div id=”container”>

<ul id=”navigation”>

<a href=”/main”>Home</a>

<li>

event

event

Event objedir ve target property'si vardır. Target property'si tıklanan DOM elementinin referansıdır, ve değişmez.

Page 31: Javascript Performance Optimisation

Event Binding

<ul id=”navigation”>

<li><a href=”/main”>Home</a></li>

<li><a href=”/foo”>Foo</a></li>

<li><a href=”/bar”>Bar</a></li>

<li><a href=”/baz”>Baz</a></li>

<li><a href=”/about”>About</a></li>

</ul>

Event objesi parent'ler üzerinden ilerlediğine göre, her bir link için ayrı ayrı event atamak yerine, liste içerisindeki tüm eventleri burada yakalayabiliriz.

event

Page 32: Javascript Performance Optimisation

Event Binding

(function() {

document.getElementById('navigation').onclick = function(event){

var target = event.target;

if (event.target.tagName == 'A') {

alert('Şu sayfa açılacak: \n\n' + target.attributes[0].value);

document.location = target.attributes[0].value;

};

event.preventDefault();

event.stopPropagation();

}

}());

Page 33: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

Döngü İçindeki DeğişkenlerAynı değeri defalarca istemek gereksiz

Page 34: Javascript Performance Optimisation

Döngü İçindeki Değişkenler

for (var i=0; i < things.length; i++) {

typeof things[i];

};

var l = things.length;

for (var i=0; i < l; i++) {

typeof things[i];

};

iyi

daha iyivar l = things.length

i=0;

for (; i < l; i++) {

typeof things[i];

};

kötü

Page 35: Javascript Performance Optimisation

Döngü İçindeki Değişkenler

'for' dışında tanımlamak

'for' içinde length kullanmak

0 5 10 15 20 25 30 35 40 45 50

Milisaniye

55.000 elemanı olan bir array için grafikteki performans farkı gözlenmiştir.

Page 36: Javascript Performance Optimisation

Okunabilecek Kitaplar

Page 37: Javascript Performance Optimisation

Ek:

Kaynaklar:

- Wikipedia

- Nicholas C. Zakas: High Performance JavaScript

İndirilebilir sunum:

slideshare.net/irfandurmus/javascript-performance-optimisation

Sunumdaki Kodlar:

github.com/irfan/javascript-presentation-codes

Page 38: Javascript Performance Optimisation

Web'in öksüz evladı: JavaScript

SORULAR

İrfan Durmuş