অনুরোধের সাথে fps নিয়ন্ত্রণ করছেনএনিমেশনফ্রেম?


140

দেখে মনে হচ্ছে requestAnimationFrameএখন জিনিসগুলি সঞ্চার করার জন্য ডি-ফ্যাক্টো উপায়। এটি বেশিরভাগ ক্ষেত্রে আমার পক্ষে বেশ ভালভাবে কাজ করেছে, তবে এই মুহুর্তে আমি কিছু ক্যানভাস অ্যানিমেশন করার চেষ্টা করছি এবং আমি ভাবছিলাম: এটি কোনও নির্দিষ্ট fps এ চলছে কিনা তা নিশ্চিত করার কোনও উপায় আছে কি? আমি বুঝতে পেরেছি যে আরএএফের উদ্দেশ্য ধারাবাহিকভাবে মসৃণ অ্যানিমেশনগুলির জন্য, এবং আমি আমার অ্যানিমেশন চপ্পি তৈরির ঝুঁকিটি চালাতে পারি তবে এখনই মনে হচ্ছে এটি নির্বিচারে বিভিন্ন গতিতে বেশ নির্বিচারে চলবে, এবং আমি ভাবছি যে লড়াইয়ের কোনও উপায় আছে কিনা? যে একরকম।

আমি ব্যবহার করব setIntervalতবে আমি আরএএফ প্রস্তাবিত অপ্টিমাইজেশন চাই (বিশেষত ট্যাবটির ফোকাসের সময় স্বয়ংক্রিয়ভাবে থামানো)।

যদি কেউ আমার কোডটি দেখতে চায় তবে এটি বেশ সুন্দর:

animateFlash: function() {
    ctx_fg.clearRect(0,0,canvasWidth,canvasHeight);
    ctx_fg.fillStyle = 'rgba(177,39,116,1)';
    ctx_fg.strokeStyle = 'none';
    ctx_fg.beginPath();
    for(var i in nodes) {
        nodes[i].drawFlash();
    }
    ctx_fg.fill();
    ctx_fg.closePath();
    var instance = this;
    var rafID = requestAnimationFrame(function(){
        instance.animateFlash();
    })

    var unfinishedNodes = nodes.filter(function(elem){
        return elem.timer < timerMax;
    });

    if(unfinishedNodes.length === 0) {
        console.log("done");
        cancelAnimationFrame(rafID);
        instance.animate();
    }
}

যেখানে নোড.ড্রেডফ্ল্যাশ () হ'ল এমন কিছু কোড যা কাউন্টার ভেরিয়েবলের উপর ভিত্তি করে ব্যাসার্ধ নির্ধারণ করে এবং তারপরে একটি বৃত্ত আঁকবে।


1
আপনার অ্যানিমেশন পিছিয়ে আছে? আমি মনে করি এর সর্বাধিক সুবিধা requestAnimationFrameহ'ল (নাম ধরণের প্রস্তাব হিসাবে) কেবলমাত্র যখন অ্যানিমেশন ফ্রেমের প্রয়োজন হয় তখনই অনুরোধ করা। ধরা যাক আপনি একটি স্ট্যাটিক কালো ক্যানভাস দেখিয়েছেন, আপনার 0 fps পাওয়া উচিত কারণ কোনও নতুন ফ্রেমের প্রয়োজন নেই। তবে আপনি যদি কোনও অ্যানিমেশন প্রদর্শন করছেন যা 60fps প্রয়োজন, আপনার এটিও পাওয়া উচিত। rAFকেবল অকেজো ফ্রেমগুলি "এড়িয়ে যেতে" এবং তারপরে সিপিইউ সংরক্ষণ করতে দেয়।
ম্যাক্সডেক

সেটআইন্টারভালও নিষ্ক্রিয় ট্যাবে কাজ করে না।
ভিলিয়াসএল

এই কোডটি 90hz ডিসপ্লে vs 60hz ডিসপ্লে বনাম 144hz ডিসপ্লেতে আলাদাভাবে চলে।
ম্যানথ্রাক্স

উত্তর:


190

কীভাবে অনুরোধঅ্যানিমেশনফ্রেমকে নির্দিষ্ট ফ্রেমের হারে থ্রোটল করবেন

5 টি এফপিএসে ডেমো থ্রোটলিং: http://jsfiddle.net/m1erickson/CtsY3/

এই পদ্ধতিটি শেষ ফ্রেম লুপটি কার্যকর করার পর থেকে অতিবাহিত সময় পরীক্ষা করে কাজ করে।

আপনার অঙ্কন কোডটি কেবল তখনই কার্যকর করা হয় যখন আপনার নির্দিষ্ট FPS ব্যবধানটি কেটে যায়।

কোডের প্রথম অংশটি অতিবাহিত সময় গণনার জন্য কিছু ভেরিয়েবল সেট করে।

var stop = false;
var frameCount = 0;
var $results = $("#results");
var fps, fpsInterval, startTime, now, then, elapsed;


// initialize the timer variables and start the animation

function startAnimating(fps) {
    fpsInterval = 1000 / fps;
    then = Date.now();
    startTime = then;
    animate();
}

এবং এই কোডটি হ'ল আসল অনুরোধঅ্যানিমেশনফ্রেম লুপ যা আপনার নির্দিষ্ট এফপিএস এ আঁকবে।

// the animation loop calculates time elapsed since the last loop
// and only draws if your specified fps interval is achieved

function animate() {

    // request another frame

    requestAnimationFrame(animate);

    // calc elapsed time since last loop

    now = Date.now();
    elapsed = now - then;

    // if enough time has elapsed, draw the next frame

    if (elapsed > fpsInterval) {

        // Get ready for next frame by setting then=now, but also adjust for your
        // specified fpsInterval not being a multiple of RAF's interval (16.7ms)
        then = now - (elapsed % fpsInterval);

        // Put your drawing code here

    }
}

5
দুর্দান্ত ব্যাখ্যা এবং উদাহরণ। এটি স্বীকৃত উত্তর হিসাবে চিহ্নিত করা উচিত
muxcmux

13
ভাল ডেমো - এটি গ্রহণ করা উচিত। এখানে, ডেট.নো () এর পরিবর্তে উইন্ডো.পারফরমেশন.উন () ব্যবহার করে প্রদর্শন করার জন্য, আপনার ফিডলটি কাঁটাযুক্ত। এটি আরএএফ ইতিমধ্যে গ্রহণ করা উচ্চ-রেজাল্ট টাইমস্ট্যাম্পের সাথে দুর্দান্তভাবে চলেছে, সুতরাং কলব্যাকের ভিতরে ডেট.নো () কল করার দরকার নেই: jsfiddle.net/chicagogrooves/nRpVD/2
ডিন র‌্যাডক্লিফ

2
নতুন আরএএফ টাইমস্ট্যাম্প বৈশিষ্ট্যটি ব্যবহার করে আপডেট হওয়া লিঙ্কটির জন্য ধন্যবাদ। নতুন আরএএফের টাইমস্ট্যাম্পটি দরকারী অবকাঠামো যুক্ত করেছে এবং এটি ডেট.নো থেকেও আরও সুনির্দিষ্ট।
Marke

13
এটি একটি দুর্দান্ত ডেমো, যা আমাকে নিজের ( জেএসফিডাল ) তৈরি করতে অনুপ্রাণিত করেছিল । প্রধান পার্থক্যগুলি হ'ল ডেটের পরিবর্তে আরএএফ (ডিনের ডেমো এর মতো) ব্যবহার করে, লক্ষ্য ফ্রেমরেটকে গতিশীলভাবে সামঞ্জস্য করতে নিয়ন্ত্রণ যুক্ত করে, অ্যানিমেশন থেকে পৃথক ব্যবধানে ফ্রেমরেটকে নমুনা তৈরি করতে এবং historicalতিহাসিক ফ্রেমরেটের গ্রাফ যুক্ত করা হয়।
tavnab

1
আপনি যখন কোনও ফ্রেম এড়াতে যাচ্ছেন তখন আপনি নিয়ন্ত্রণ করতে পারবেন সমস্ত। একটি 60 fps মনিটর সর্বদা 16ms ব্যবধানে আঁকেন। উদাহরণস্বরূপ আপনি যদি আপনার গেমটি 50fps এ চালাতে চান তবে আপনি প্রতি 6th ষ্ঠ ফ্রেমে এড়িয়ে যেতে চান। 20 মিমি (1000/50) কেটে গেছে কিনা তা আপনি পরীক্ষা করে দেখেন এবং এটি (কেবল 16 মিমি অতিক্রান্ত হয়েছে) তাই আপনি একটি ফ্রেম এড়িয়ে গেছেন, তারপরে আপনার আঁকানোর পরের পরের ফ্রেম 32ms কেটে গেছে, সুতরাং আপনি আঁকুন এবং পুনরায় সেট করুন। তবে তারপরে আপনি অর্ধেক ফ্রেমগুলি এড়িয়ে 30fps এ চলে যাবেন। সুতরাং আপনি পুনরায় সেট করার সময় মনে রাখবেন আপনি গতবারে 12 মিমি বেশ দীর্ঘ অপেক্ষা করেছিলেন। সুতরাং পরবর্তী ফ্রেমে আরও একটি 16 মিমি পাস হয় তবে আপনি এটি 16 + 12 = 28 মিমি হিসাবে গণনা করেন যাতে আপনি আবার আঁকেন এবং আপনি 8 মিমি দীর্ঘ দীর্ঘ অপেক্ষা করেছিলেন
কার্টিস

47

আপডেট 2016/6

ফ্রেম হারকে থ্রোটলিং করার সমস্যাটি হ'ল স্ক্রিনটির একটি ধ্রুবক আপডেটের হার থাকে, সাধারণত 60 এফপিএস।

আমরা 24 এফপিএস চাইলে আমরা কখনই স্ক্রিনে সত্যিকারের 24 এফপিএস পাব না, আমরা এটির মতো সময় দিতে পারি তবে এটি দেখাতে পারি না কারণ মনিটরটি কেবলমাত্র 15 এফপিএস, 30 এফপিএস বা 60 এফপিএসে সিঙ্কড ফ্রেমগুলি প্রদর্শন করতে পারে (কিছু মনিটরও 120 এফপিএস) )।

যাইহোক, সময়সই উদ্দেশ্যে আমরা যখন সম্ভব সম্ভব গণনা করতে এবং আপডেট করতে পারি।

আপনি কোনও বস্তুতে গণনা এবং কলব্যাকগুলি encapsulate করে ফ্রেম-হার নিয়ন্ত্রণের জন্য সমস্ত যুক্তি তৈরি করতে পারেন:

function FpsCtrl(fps, callback) {

    var delay = 1000 / fps,                               // calc. time per frame
        time = null,                                      // start time
        frame = -1,                                       // frame count
        tref;                                             // rAF time reference

    function loop(timestamp) {
        if (time === null) time = timestamp;              // init start time
        var seg = Math.floor((timestamp - time) / delay); // calc frame no.
        if (seg > frame) {                                // moved to next frame?
            frame = seg;                                  // update
            callback({                                    // callback function
                time: timestamp,
                frame: frame
            })
        }
        tref = requestAnimationFrame(loop)
    }
}

তারপরে কিছু নিয়ামক এবং কনফিগারেশন কোড যুক্ত করুন:

// play status
this.isPlaying = false;

// set frame-rate
this.frameRate = function(newfps) {
    if (!arguments.length) return fps;
    fps = newfps;
    delay = 1000 / fps;
    frame = -1;
    time = null;
};

// enable starting/pausing of the object
this.start = function() {
    if (!this.isPlaying) {
        this.isPlaying = true;
        tref = requestAnimationFrame(loop);
    }
};

this.pause = function() {
    if (this.isPlaying) {
        cancelAnimationFrame(tref);
        this.isPlaying = false;
        time = null;
        frame = -1;
    }
};

ব্যবহার

এটি খুব সহজ হয়ে যায় - এখন, আমাদের যা যা করতে হবে তা হ'ল কলব্যাক ফাংশন এবং পছন্দসই ফ্রেম রেট ঠিক এভাবে সেট করে একটি উদাহরণ তৈরি করা:

var fc = new FpsCtrl(24, function(e) {
     // render each frame here
  });

তারপরে শুরু করুন (যা ইচ্ছা থাকলে ডিফল্ট আচরণ হতে পারে):

fc.start();

এটাই, সমস্ত যুক্তি অভ্যন্তরীণভাবে পরিচালিত হয়।

ডেমো

var ctx = c.getContext("2d"), pTime = 0, mTime = 0, x = 0;
ctx.font = "20px sans-serif";

// update canvas with some information and animation
var fps = new FpsCtrl(12, function(e) {
	ctx.clearRect(0, 0, c.width, c.height);
	ctx.fillText("FPS: " + fps.frameRate() + 
                 " Frame: " + e.frame + 
                 " Time: " + (e.time - pTime).toFixed(1), 4, 30);
	pTime = e.time;
	var x = (pTime - mTime) * 0.1;
	if (x > c.width) mTime = pTime;
	ctx.fillRect(x, 50, 10, 10)
})

// start the loop
fps.start();

// UI
bState.onclick = function() {
	fps.isPlaying ? fps.pause() : fps.start();
};

sFPS.onchange = function() {
	fps.frameRate(+this.value)
};

function FpsCtrl(fps, callback) {

	var	delay = 1000 / fps,
		time = null,
		frame = -1,
		tref;

	function loop(timestamp) {
		if (time === null) time = timestamp;
		var seg = Math.floor((timestamp - time) / delay);
		if (seg > frame) {
			frame = seg;
			callback({
				time: timestamp,
				frame: frame
			})
		}
		tref = requestAnimationFrame(loop)
	}

	this.isPlaying = false;
	
	this.frameRate = function(newfps) {
		if (!arguments.length) return fps;
		fps = newfps;
		delay = 1000 / fps;
		frame = -1;
		time = null;
	};
	
	this.start = function() {
		if (!this.isPlaying) {
			this.isPlaying = true;
			tref = requestAnimationFrame(loop);
		}
	};
	
	this.pause = function() {
		if (this.isPlaying) {
			cancelAnimationFrame(tref);
			this.isPlaying = false;
			time = null;
			frame = -1;
		}
	};
}
body {font:16px sans-serif}
<label>Framerate: <select id=sFPS>
	<option>12</option>
	<option>15</option>
	<option>24</option>
	<option>25</option>
	<option>29.97</option>
	<option>30</option>
	<option>60</option>
</select></label><br>
<canvas id=c height=60></canvas><br>
<button id=bState>Start/Stop</button>

পুরানো উত্তর

এর মূল উদ্দেশ্যটি requestAnimationFrameমনিটরের রিফ্রেশ হারে আপডেটগুলি সিঙ্ক করা nc এটি আপনাকে মনিটরের FPS বা এর কোনও ফ্যাক্টর (যেমন 60, 30, 15 এফপিএসের জন্য একটি সাধারণ রিফ্রেশ রেট @ 60 হার্জ এর জন্য) এনিমেট করতে হবে।

আপনি যদি আরও নির্বিচারে এফপিএস চান তবে আরএএফ ব্যবহারের কোনও মানে নেই কারণ ফ্রেম রেট কখনই মনিটরের আপডেট ফ্রিকোয়েন্সিটির সাথে মেলে না (কেবলমাত্র একটি ফ্রেম এখানে এবং সেখানে) যা আপনাকে কোনও মসৃণ অ্যানিমেশন দিতে পারে না (যেমন সমস্ত ফ্রেমের পুনরায় সময়সীমার সাথে ) এবং আপনি পাশাপাশি ব্যবহার করতে পারেন setTimeoutবা setIntervalতার পরিবর্তে।

পেশাদার ভিডিও শিল্পে এটি একটি সুপরিচিত সমস্যা যখন আপনি কোনও আলাদা এফপিএসে কোনও ভিডিও প্লেব্যাক করতে চান তখন ডিভাইসটি এটিকে রিফ্রেশ দেখায়। মোশন ভেক্টরগুলির উপর ভিত্তি করে ফ্রেম সংমিশ্রণ এবং জটিল পুনঃ-টাইমিং পুনঃনির্মাণ ইন্টারমিডিয়েট ফ্রেমগুলির মতো অনেক কৌশল ব্যবহৃত হয়েছে, তবে ক্যানভাসের সাথে এই কৌশলগুলি উপলভ্য নয় এবং ফলাফল সর্বদা ঝাঁকুনির ভিডিওতে থাকবে।

var FPS = 24;  /// "silver screen"
var isPlaying = true;

function loop() {
    if (isPlaying) setTimeout(loop, 1000 / FPS);

    ... code for frame here
}

আমরা setTimeout প্রথমে রাখার কারণ (এবং rAFপলি-ফিল ব্যবহার করার পরে কিছু জায়গা কেন প্রথমে রয়েছে) হ'ল এটি আরও সঠিক setTimeoutহবে কারণ লুপটি শুরু হওয়ার সাথে সাথে কোনও ইভেন্টের সারি তৈরি করা হবে যাতে বাকী কোডটি কত সময় ব্যবহার করবে তা বিবেচনা করে না (প্রদত্ত এটি সময়সীমা ব্যবধানের অতিক্রম না করে) পরের কলটি উপস্থাপিত হওয়ার মধ্যবর্তী সময়ে আসবে (শুদ্ধ আরএএফের জন্য এটি প্রয়োজনীয় নয় কারণ আরএফ কোনও ক্ষেত্রে পরবর্তী ফ্রেমে ঝাঁপিয়ে পড়ার চেষ্টা করবে)।

এটিও লক্ষণীয় যে এটিকে প্রথমে রাখার ফলে কলগুলি যেমন স্ট্যাকিং ঝুঁকিপূর্ণ হয় setIntervalsetIntervalএই ব্যবহারের জন্য কিছুটা আরও সঠিক হতে পারে।

আর আপনি ব্যবহার করতে পারেন setIntervalপরিবর্তে বাইরে লুপ একই কাজ করতে।

var FPS = 29.97;   /// NTSC
var rememberMe = setInterval(loop, 1000 / FPS);

function loop() {

    ... code for frame here
}

এবং লুপ থামাতে:

clearInterval(rememberMe);

ট্যাব ঝাপসা হয়ে গেলে ফ্রেমের হার কমাতে আপনি এই জাতীয় একটি উপাদান যুক্ত করতে পারেন:

var isFocus = 1;
var FPS = 25;

function loop() {
    setTimeout(loop, 1000 / (isFocus * FPS)); /// note the change here

    ... code for frame here
}

window.onblur = function() {
    isFocus = 0.5; /// reduce FPS to half   
}

window.onfocus = function() {
    isFocus = 1; /// full FPS
}

এইভাবে আপনি এফপিএস হ্রাস করতে পারেন 1/4 ইত্যাদি।


4
কিছু ক্ষেত্রে আপনি মনিটরের ফ্রেম রেটের সাথে মিলের চেষ্টা করছেন না বরং চিত্রের সিকোয়েন্সগুলিতে ফ্রেমগুলি ড্রপ করুন। দুর্দান্ত ব্যাখ্যা
বিটিডব্লিউ

3
অনুরোধএনিমেশনফ্রেমের সাথে থ্রোট করার সবচেয়ে বড় কারণ হ'ল ব্রাউজারগুলির অ্যানিমেশন ফ্রেমের সাথে কিছু কোড কার্যকর করা line বিষয়গুলি খুব মসৃণভাবে চলমান শেষ হয়, বিশেষত যদি আপনি উদাহরণস্বরূপ সংগীত ভিজ্যুয়ালাইজারগুলির মতো প্রতি ফ্রেমে ডেটাতে কিছু যুক্তি চালাচ্ছেন।
ক্রিস ডলফিন

4
এটি খারাপ কারণ মূল ব্যবহারটি requestAnimationFrameডিওএম ক্রিয়াকলাপগুলি সিঙ্ক্রোনাইজ করা (পড়ুন / লিখুন) সুতরাং এটি ব্যবহার না করে ডিওএম অ্যাক্সেস করার সময় কার্যকারিতা ক্ষতিগ্রস্থ হবে, যেহেতু অপারেশনগুলি একসাথে সঞ্চালনের জন্য সারি করা হবে না এবং অকারণে লেআউট পুনরায় রঙ করতে বাধ্য করবে।
vsync

1
"কল স্ট্যাক আপ" হওয়ার ঝুঁকি নেই, কারণ জাভাস্ক্রিপ্ট একক থ্রেডযুক্ত চালায় এবং আপনার কোডটি চলাকালীন কোনও টাইমআউট ইভেন্ট শুরু হয় না। সুতরাং যদি ফাংশনটি সময়সীমার চেয়ে বেশি সময় নেয় তবে এটি প্রায় যত দ্রুত সম্ভব চালায়, যখন ব্রাউজারটি পুনরায় আঁকবে এবং কলগুলির অভ্যন্তরে অন্য সময়সীমাগুলি ট্রিগার করবে।
ড্রোনাস

আমি জানি যে আপনি পৃষ্ঠাটি রিফ্রেশটি ডিসপ্লেতে fps সীমা চেয়ে দ্রুত আপডেট করতে পারবেন না cannot তবে, একটি পৃষ্ঠা রিফ্লো ট্রিগার করে দ্রুত রিফ্রেশ করা সম্ভব? বিপরীতে, একাধিক পৃষ্ঠার নেটিভ এফপিএস হারের চেয়ে দ্রুত সম্পন্ন করা হলে তা লক্ষ্য করা কি সম্ভব নয়?
ট্র্যাভিস জে

36

আমি আপনার কল মোড়কে করার পরামর্শ দিই requestAnimationFrameএকটি setTimeout। আপনি যদি setTimeoutঅ্যানিমেশন ফ্রেমের জন্য অনুরোধ করেছেন এমন ফাংশনটির মধ্যে থেকে কল করেন, আপনি এর উদ্দেশ্যটি পরাস্ত করছেন requestAnimationFrame। তবে আপনি যদি এর requestAnimationFrameমধ্যে থেকে কল setTimeoutকরেন তবে সহজেই কাজ করে:

var fps = 25
function animate() {
  setTimeout(function() {
    requestAnimationFrame(animate);
  }, 1000 / fps);
}

1
এটি প্রকৃতপক্ষে ফ্রেমরেটটি নিচে রাখার জন্য কাজ করে এবং তাই আমার সিপিইউ রান্না করছে না বলে মনে হচ্ছে। এবং এটি খুব সহজ। চিয়ার্স!
phps

এটি লাইটওয়েট অ্যানিমেশনের জন্য এটি করার একটি দুর্দান্ত, সহজ উপায়। এটি সিঙ্কের বাইরে কিছুটা হলেও কমপক্ষে কিছু ডিভাইসে আসে। আমি এই কৌশলটি আমার আগের ইঞ্জিনগুলির মধ্যে একটিতে ব্যবহার করেছি। জিনিস জটিল না হওয়া পর্যন্ত এটি ভাল কাজ করেছে। সবচেয়ে বড় সমস্যাটি যখন ওরিয়েন্টেশন সেন্সরগুলিতে ঝাঁকানো ছিল তখন তা পিছিয়ে থাকবে বা লাফিয়ে উঠবে। পরে আমি একটি পৃথক সেটআইন্টারওয়াল ব্যবহার করে এবং সেন্সর, সেটআইন্টারভাল ফ্রেম এবং আরএএফ ফ্রেমের মধ্যে অবজেক্ট প্রোপার্টিগুলির মাধ্যমে সেন্সর এবং আরএএফকে রিয়েল-টাইম যেতে মঞ্জুরি দিয়েছি, যখন অ্যানিমেশন সময়টি সেটআইন্টারভাল থেকে সম্পত্তি আপডেটের মাধ্যমে নিয়ন্ত্রণ করা যেতে পারে।
jdmayfield

সর্বোত্তম উত্তর ! ধন্যবাদ;)
538 রোম

আমার মনিটরটি 60 এফপিএস, যদি আমি var fps = 60 সেট করি তবে আমি এই কোডটি ব্যবহার করে প্রায় 50 টি এফপিএস পাই। আমি এটিকে 60 এ ধীরে ধীরে করতে চাই কারণ কিছু লোকের কাছে 120 টি এফপিএস মনিটর রয়েছে তবে আমি অন্য সবাইকে প্রভাবিত করতে চাই না। এটি আশ্চর্যজনকভাবে কঠিন।
কার্টিস

আপনি প্রত্যাশার চেয়ে কম এফপিএস পাওয়ার কারণ হ'ল সেটটাইমআউট নির্দিষ্ট বিলম্বের চেয়ে বেশি পরে কলব্যাক কার্যকর করতে পারে। এর বেশ কয়েকটি সম্ভাব্য কারণ রয়েছে। এবং প্রতিটি লুপে একটি নতুন টাইমার সেট করতে এবং নতুন টাইমআউট সেট করার আগে কিছু কোড কার্যকর করতে সময় লাগে। আপনার এটির সাথে নির্ভুল হওয়ার কোনও উপায় নেই, আপনি সর্বদা প্রত্যাশিত ফলাফলের চেয়ে ধীরে ধীরে বিবেচনা করা উচিত, তবে যতক্ষণ না আপনি জানেন না এটি কতটা ধীর হবে, বিলম্বকে হ্রাস করার চেষ্টা করাও ততই ভুল হবে। ব্রাউজারগুলিতে জেএস এর অর্থ এত নির্ভুল নয়।
pdepmcp

17

এগুলি তত্ত্বের সমস্ত ভাল ধারণা, যতক্ষণ না আপনি গভীর হয়ে যান। সমস্যাটি হ'ল আপনি কোনও আরএএফকে ডি-সিঙ্ক্রোনাইজ না করে গলা ফাটিয়ে ফেলতে পারবেন না, এটি বিদ্যমান জন্য এটি খুব উদ্দেশ্য defe সুতরাং আপনি এটি পুরো গতিতে চালানোর জন্য, এবং একটি পৃথক লুপ এ আপনার ডেটা আপডেট করার অনুমতি দিন , বা এমনকি একটি পৃথক থ্রেডে!

হ্যাঁ, আমি এটা বলেছি। আপনি ব্রাউজারে মাল্টি-থ্রেড জাভাস্ক্রিপ্ট করতে পারেন !

দুটি পদ্ধতি আছে যা আমি জানি যে জ্যাঙ্ক ছাড়াই অত্যন্ত ভাল কাজ করে, খুব কম রস ব্যবহার করে এবং কম তাপ তৈরি করে। সঠিক মানব-স্কেল সময় এবং মেশিনের দক্ষতার নেট ফলাফল।

যদি এটি কিছুটা শব্দযুক্ত হয় তবে দুঃখিত, তবে এখানে ...


পদ্ধতি 1: সেটআইন্টারওয়ালের মাধ্যমে ডেটা এবং আরএএফের মাধ্যমে গ্রাফিকগুলি আপডেট করুন।

অনুবাদ এবং রোটেশন মানগুলি, পদার্থবিজ্ঞান, সংঘর্ষ ইত্যাদি আপডেট করার জন্য একটি পৃথক সেটআইন্টারওয়াল ব্যবহার করুন each প্রতিটি অ্যানিমেটেড উপাদানগুলির জন্য কোনও মানগুলিতে এই মানগুলি রাখুন। প্রতিটি সেটইন্টারভাল 'ফ্রেম' অবজেক্টের ভেরিয়েবলকে ট্রান্সফর্ম স্ট্রিং বরাদ্দ করুন। এই বস্তুগুলিকে একটি অ্যারেতে রাখুন। এমএস: এমএস = (1000 / এফপিএস) আপনার কাঙ্ক্ষিত এফপিএসে আপনার বিরতি সেট করুন। এটি একটি অবিচল ঘড়ি রাখে যা আরএএফ গতি নির্বিশেষে যে কোনও ডিভাইসে একই এফপিএসের অনুমতি দেয়। এখানে উপাদানগুলিতে রূপান্তর বরাদ্দ করবেন না!

একটি অনুরোধে অ্যানিমেশন ফ্রেম লুপটিতে লুপের জন্য একটি পুরানো স্কুল দিয়ে আপনার অ্যারে দিয়ে পুনরাবৃত্তি করুন - নতুনতর ফর্মগুলি এখানে ব্যবহার করবেন না, এগুলি ধীর!

for(var i=0; i<sprite.length-1; i++){  rafUpdate(sprite[i]);  }

আপনার rafUpdate ফাংশনে, অ্যারের মধ্যে আপনার জেএস বস্তু থেকে রূপান্তর স্ট্রিংটি এবং এর উপাদানগুলির আইডি পান। আপনার 'স্প্রাইট' উপাদানগুলি ইতিমধ্যে একটি চলকগুলির সাথে সংযুক্ত থাকা বা অন্য মাধ্যমে সহজেই অ্যাক্সেসযোগ্য হওয়া উচিত যাতে আপনি আরএএএফ-এ সেগুলি পেতে 'সময়' হারাবেন না। তাদের এইচটিএমএল আইডির নাম অনুসারে কোনও আইটেমে রাখার কাজটি বেশ ভাল। এমনকি আপনার এসআই বা আরএএফ-এ যাওয়ার আগে এই অংশটি সেট করুন।

কেবলমাত্র আপনার ট্রান্সফর্ম আপডেট করতে আরএএফ ব্যবহার করুন , কেবলমাত্র 3 ডি ট্রান্সফর্ম (এমনকি 2 ডি এর জন্য) ব্যবহার করুন এবং সিএসএস "" বদলে যাবে: রূপান্তর করুন "সেট করুন; যে উপাদান পরিবর্তন হবে। এটি আপনার রূপান্তরগুলি যথাসম্ভব দেশীয় রিফ্রেশ রেটে সিঙ্ক করে রাখে, জিপিইউতে কিক দেয় এবং ব্রাউজারকে জানায় যে কোথায় সবচেয়ে বেশি মনোযোগ দেওয়া যায়।

সুতরাং আপনার এই সিউডোকোডের মতো কিছু হওয়া উচিত ...

// refs to elements to be transformed, kept in an array
var element = [
   mario: document.getElementById('mario'),
   luigi: document.getElementById('luigi')
   //...etc.
]

var sprite = [  // read/write this with SI.  read-only from RAF
   mario: { id: mario  ....physics data, id, and updated transform string (from SI) here  },
   luigi: {  id: luigi  .....same  }
   //...and so forth
] // also kept in an array (for efficient iteration)

//update one sprite js object
//data manipulation, CPU tasks for each sprite object
//(physics, collisions, and transform-string updates here.)
//pass the object (by reference).
var SIupdate = function(object){
  // get pos/rot and update with movement
  object.pos.x += object.mov.pos.x;  // example, motion along x axis
  // and so on for y and z movement
  // and xyz rotational motion, scripted scaling etc

  // build transform string ie
  object.transform =
   'translate3d('+
     object.pos.x+','+
     object.pos.y+','+
     object.pos.z+
   ') '+

   // assign rotations, order depends on purpose and set-up. 
   'rotationZ('+object.rot.z+') '+
   'rotationY('+object.rot.y+') '+
   'rotationX('+object.rot.x+') '+

   'scale3d('.... if desired
  ;  //...etc.  include 
}


var fps = 30; //desired controlled frame-rate


// CPU TASKS - SI psuedo-frame data manipulation
setInterval(function(){
  // update each objects data
  for(var i=0; i<sprite.length-1; i++){  SIupdate(sprite[i]);  }
},1000/fps); //  note ms = 1000/fps


// GPU TASKS - RAF callback, real frame graphics updates only
var rAf = function(){
  // update each objects graphics
  for(var i=0; i<sprite.length-1; i++){  rAF.update(sprite[i])  }
  window.requestAnimationFrame(rAF); // loop
}

// assign new transform to sprite's element, only if it's transform has changed.
rAF.update = function(object){     
  if(object.old_transform !== object.transform){
    element[object.id].style.transform = transform;
    object.old_transform = object.transform;
  }
} 

window.requestAnimationFrame(rAF); // begin RAF

এটি ডেটা অবজেক্টগুলিতে আপনার আপডেটগুলি রাখে এবং এসআই-তে পছন্দসই 'ফ্রেম' হারের সাথে সিঙ্ক হওয়া স্ট্রিংগুলিকে রূপান্তরিত করে, এবং আরএএফ-তে প্রকৃত রূপান্তর অ্যাসাইনমেন্টগুলি জিপিইউ রিফ্রেশ রেটে সিঙ্ক হয়। সুতরাং প্রকৃত গ্রাফিক্সের আপডেটগুলি কেবল আরএএফ-তে রয়েছে, তবে ডেটাতে পরিবর্তন এবং ট্রান্সফর্ম স্ট্রিং তৈরি করা এসআই-তে রয়েছে, সুতরাং জাঙ্কিগুলি ব্যতীত কাঙ্ক্ষিত ফ্রেম-রেটে 'সময়' প্রবাহিত হয় না।


প্রবাহ:

[setup js sprite objects and html element object references]

[setup RAF and SI single-object update functions]

[start SI at percieved/ideal frame-rate]
  [iterate through js objects, update data transform string for each]
  [loop back to SI]

[start RAF loop]
  [iterate through js objects, read object's transform string and assign it to it's html element]
  [loop back to RAF]

পদ্ধতি 2. এসআইকে একটি ওয়েব-কর্মীর মধ্যে রাখুন। এটি একটি FAAAST এবং মসৃণ!

পদ্ধতি 1 হিসাবে একই, তবে এসআইকে ওয়েব-কর্মীর মধ্যে রাখুন। এটি তখন সম্পূর্ণ আলাদা থ্রেডে চলবে, পৃষ্ঠাটি কেবল আরএএফ এবং ইউআইয়ের সাথে ডিল করার জন্য রেখে যাবে। 'ট্রান্সফেরেবল অবজেক্ট' হিসাবে পিছনে স্প্রাইট অ্যারে পাস করুন। এই বুকো দ্রুত। এটি ক্লোন বা সিরিয়ালাইজ করতে সময় লাগে না, তবে এটি রেফারেন্স দিয়ে যাওয়ার মতো নয় যে অন্য দিক থেকে রেফারেন্সটি নষ্ট হয়ে গেছে, সুতরাং আপনার উভয় পক্ষকে অন্য দিকে যেতে হবে, এবং উপস্থিত থাকলে কেবল সেগুলি আপডেট করুন, সাজান হাই-স্কুলে আপনার গার্লফ্রেন্ডের সাথে বার বার নোট পাস করার মতো।

একসাথে কেবল একজনই পড়তে এবং লিখতে পারবেন। এটি এতক্ষণ ঠিক আছে যেহেতু তারা পরীক্ষা করে এটি ত্রুটি এড়ানোর জন্য এটি অপরিবর্তিত নয় কিনা। আরএএফ দ্রুত এবং এটিকে তাড়াতাড়ি ফিরিয়ে আনবে, তারপরে জিপিইউ ফ্রেমের একটি গোছা দিয়ে দেখুন এটি এখনও পাঠানো হয়েছে কিনা তা পরীক্ষা করে। ওয়েব-কর্মীর এসআই-এর বেশিরভাগ সময় স্প্রিট অ্যারে থাকবে এবং অবস্থানিক, চলন এবং পদার্থবিজ্ঞানের ডেটা আপডেট করার পাশাপাশি নতুন ট্রান্সফর্ম স্ট্রিং তৈরি করার পরে এটি পৃষ্ঠায় আরএএফ-এ ফিরিয়ে দেবে।

স্ক্রিপ্টের মাধ্যমে উপাদানগুলি প্রাণবন্ত করতে আমি এটিই দ্রুততম উপায়। দুটি ফাংশন দুটি পৃথক প্রোগ্রাম হিসাবে চলবে, পৃথক দুটি থ্রেডে, একক জেএস স্ক্রিপ্টটি এমনভাবে নয় যে মাল্টি-কোর সিপিইউর সুবিধা গ্রহণ করবে। মাল্টি-থ্রেড জাভাস্ক্রিপ্ট অ্যানিমেশন।

এবং এটি জ্যাঙ্ক ছাড়াই এতো সহজেই করবে তবে প্রকৃত নির্দিষ্ট ফ্রেম-হারে খুব সামান্য বিচ্যুতি নিয়ে।


ফলাফল:

এই দুটি পদ্ধতির যে কোনও একটিই নিশ্চিত করবে যে আপনার স্ক্রিপ্টটি কোনও পিসি, ফোন, ট্যাবলেট ইত্যাদিতে (অবশ্যই ডিভাইস এবং ব্রাউজারের দক্ষতার মধ্যে) একই গতিতে চলবে।


পার্শ্ব নোট হিসাবে - 1 পদ্ধতিতে, যদি আপনার সেটআইন্টারওয়ালগুলিতে খুব বেশি ক্রিয়াকলাপ হয় তবে এটি সিআর-থ্রেডড অ্যাসিঙ্কের কারণে আপনার আরএএফকে ধীর করতে পারে। আপনি এই ক্রিয়াকলাপটি এসআই ফ্রেমের চেয়ে বেশি ভাঙ্গিয়ে প্রশমিত করতে পারেন, তাই অ্যাসিঙ্ক দ্রুত আরএএফ-তে নিয়ন্ত্রণ দ্রুত পাস করবে। মনে রাখবেন, আরএএফ সর্বাধিক ফ্রেম-হারে চলে যায় তবে প্রদর্শনটির সাথে গ্রাফিকাল পরিবর্তনগুলি সমন্বয় করে, তাই কয়েকটি আরএএফ ফ্রেমগুলি এড়ানো ঠিক আছে - যতক্ষণ না আপনি এসআই ফ্রেমের চেয়ে বেশি এড়িয়ে যাবেন না এটি জঞ্জাল হবে না।
jdmayfield 0

পদ্ধতি 2টি আরও দৃust়, কারণ এটি দুটি লুপকে একাধিক করে কাজ করছে, অ্যাসিঙ্কের মাধ্যমে পিছনে পিছনে স্যুইচ করছে না, তবে আপনি এখনও আপনার এসআই ফ্রেমটিকে আপনার পছন্দসই ফ্রেম-রেটের চেয়ে বেশি সময় নিতে এড়াতে চান, সুতরাং বিভক্ত এসআই ক্রিয়াকলাপটি এখনও হতে পারে কাঙ্ক্ষিত যদি এতে প্রচুর ডেটা-ম্যানিপুলেশন চলছে যা সম্পূর্ণ করতে একাধিক এসআই ফ্রেম লাগবে।
jdmayfield 0

আমি এটিকে উল্লেখ করার মতো মনে করেছি, আগ্রহের নোট হিসাবে, ক্রোমস ডেভটুলগুলিতে এই জাতীয় পেয়ারযুক্ত লুপগুলি নিবন্ধন করে যে জিপিইউ সেটআইন্টারভাল লুপে নির্দিষ্ট ফ্রেম-রেটে চলছে! এটি কেবল আরএএফ ফ্রেমগুলিতে প্রদর্শিত হয় যেখানে গ্রাফিকাল পরিবর্তনগুলি এফপিএস মিটার দ্বারা ফ্রেম হিসাবে গণনা করা হয়। সুতরাং আরএএফ ফ্রেমগুলি যেখানে কেবল অ-গ্রাফিকাল কাজ, এমনকি খালি ফাঁকা অংশগুলিও, জিপিইউ সম্পর্কিত যতটা গণনা করে না। আমি আরও গবেষণার সূচনা পয়েন্ট হিসাবে এটি আকর্ষণীয় মনে করি।
jdmayfield

আমি বিশ্বাস করি যে আরএএফ স্থগিত হয়ে গেলে এই সমাধানটিতে এমন সমস্যা রয়েছে যা এটি চলমান রাখে, যেমন ব্যবহারকারী অন্য ট্যাবে স্যুইচ করেছেন।
N4ppeL

1
পিএস আমি কিছু পাঠ করেছি এবং দেখে মনে হচ্ছে বেশিরভাগ ব্রাউজারগুলি যে কোনও উপায়ে ব্যাকগ্রাউন্ড ট্যাবগুলিতে প্রতি সেকেন্ডে সময়সীমার ঘটনা সীমাবদ্ধ করে (যা সম্ভবত কোনও উপায়ে পরিচালনাও করা উচিত)। আপনি যদি এখনও সমস্যাটি সম্বোধন করতে চান এবং দৃশ্যমান না হয়ে পুরোপুরি বিরতি দিন, visibilitychangeইভেন্টটি মনে হচ্ছে ।
N4ppeL

3

কোনও নির্দিষ্ট এফপিএসে কীভাবে সহজে থ্রোটল করবেন:

// timestamps are ms passed since document creation.
// lastTimestamp can be initialized to 0, if main loop is executed immediately
var lastTimestamp = 0,
    maxFPS = 30,
    timestep = 1000 / maxFPS; // ms for each frame

function main(timestamp) {
    window.requestAnimationFrame(main);

    // skip if timestep ms hasn't passed since last frame
    if (timestamp - lastTimestamp < timestep) return;

    lastTimestamp = timestamp;

    // draw frame here
}

window.requestAnimationFrame(main);

উত্স: আইজ্যাক সুকিনের জাভাস্ক্রিপ্ট গেম লুপস এবং টাইমিংয়ের বিশদ ব্যাখ্যা


1
যদি আমার মনিটরটি 60 এফপিএসে চলে এবং আমি চাই যে আমার গেমটি 58 ​​এফপিএসে চালিত হোক আমি ম্যাক্সএফপিএস = 58 সেট করি, এটি এটি 30 এফপিএসে চালিত করবে কারণ এটি প্রতি 2 য় ফ্রেম এড়িয়ে যাবে।
কার্টিস

হ্যাঁ, আমি এটিও চেষ্টা করেছি। আমি আসলে আরএএফকে নিজেই থ্রোটল্ট না করা বেছে নিয়েছি - কেবলমাত্র পরিবর্তনগুলি সেটটাইমআউট দ্বারা আপডেট হয়। কমপক্ষে ক্রোমে, এর ফলে ডিফলটুলসে পঠন অনুসারে কার্যকর fps টি সেটটাইমআউটস গতিতে চালিত হয়। অবশ্যই এটি কেবলমাত্র ভিডিও কার্ডের গতিতে বাস্তব ভিডিও ফ্রেমগুলি আপডেট করতে পারে এবং রিফ্রেশ রেটটি পর্যবেক্ষণ করতে পারে তবে এই পদ্ধতিটি কমপক্ষে জাঙ্কিগুলির সাথে কাজ করে বলে মনে হচ্ছে, তাই স্মুথ "স্পষ্ট" fps নিয়ন্ত্রণ, যা আমি যাচ্ছি।
jdmayfield

যেহেতু আমি জেএস বস্তুগুলিতে আরএএফ থেকে আলাদাভাবে সমস্ত গতির খোঁজ রাখি, এটি আরএএফ বা সেটটাইমআউট নির্বিশেষে কিছুটা অতিরিক্ত গণিত নিয়ে অ্যানিমেশন যুক্তি, সংঘর্ষ সনাক্তকরণ বা আপনার যা প্রয়োজন প্রয়োজন বোধ করে রাখে।
jdmayfield

2

স্কিপিং requestAnimationFrame কারণ মসৃণ না (পছন্দসই) কাস্টম FPS এ অ্যানিমেশান।

// Input/output DOM elements
var $results = $("#results");
var $fps = $("#fps");
var $period = $("#period");

// Array of FPS samples for graphing

// Animation state/parameters
var fpsInterval, lastDrawTime, frameCount_timed, frameCount, lastSampleTime, 
		currentFps=0, currentFps_timed=0;
var intervalID, requestID;

// Setup canvas being animated
var canvas = document.getElementById("c");
var canvas_timed = document.getElementById("c2");
canvas_timed.width = canvas.width = 300;
canvas_timed.height = canvas.height = 300;
var ctx = canvas.getContext("2d");
var ctx2 = canvas_timed.getContext("2d");


// Setup input event handlers

$fps.on('click change keyup', function() {
    if (this.value > 0) {
        fpsInterval = 1000 / +this.value;
    }
});

$period.on('click change keyup', function() {
    if (this.value > 0) {
        if (intervalID) {
            clearInterval(intervalID);
        }
        intervalID = setInterval(sampleFps, +this.value);
    }
});


function startAnimating(fps, sampleFreq) {

    ctx.fillStyle = ctx2.fillStyle = "#000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx2.fillRect(0, 0, canvas.width, canvas.height);
    ctx2.font = ctx.font = "32px sans";
    
    fpsInterval = 1000 / fps;
    lastDrawTime = performance.now();
    lastSampleTime = lastDrawTime;
    frameCount = 0;
    frameCount_timed = 0;
    animate();
    
    intervalID = setInterval(sampleFps, sampleFreq);
		animate_timed()
}

function sampleFps() {
    // sample FPS
    var now = performance.now();
    if (frameCount > 0) {
        currentFps =
            (frameCount / (now - lastSampleTime) * 1000).toFixed(2);
        currentFps_timed =
            (frameCount_timed / (now - lastSampleTime) * 1000).toFixed(2);
        $results.text(currentFps + " | " + currentFps_timed);
        
        frameCount = 0;
        frameCount_timed = 0;
    }
    lastSampleTime = now;
}

function drawNextFrame(now, canvas, ctx, fpsCount) {
    // Just draw an oscillating seconds-hand
    
    var length = Math.min(canvas.width, canvas.height) / 2.1;
    var step = 15000;
    var theta = (now % step) / step * 2 * Math.PI;

    var xCenter = canvas.width / 2;
    var yCenter = canvas.height / 2;
    
    var x = xCenter + length * Math.cos(theta);
    var y = yCenter + length * Math.sin(theta);
    
    ctx.beginPath();
    ctx.moveTo(xCenter, yCenter);
    ctx.lineTo(x, y);
  	ctx.fillStyle = ctx.strokeStyle = 'white';
    ctx.stroke();
    
    var theta2 = theta + 3.14/6;
    
    ctx.beginPath();
    ctx.moveTo(xCenter, yCenter);
    ctx.lineTo(x, y);
    ctx.arc(xCenter, yCenter, length*2, theta, theta2);

    ctx.fillStyle = "rgba(0,0,0,.1)"
    ctx.fill();
    
    ctx.fillStyle = "#000";
    ctx.fillRect(0,0,100,30);
    
    ctx.fillStyle = "#080";
    ctx.fillText(fpsCount,10,30);
}

// redraw second canvas each fpsInterval (1000/fps)
function animate_timed() {
    frameCount_timed++;
    drawNextFrame( performance.now(), canvas_timed, ctx2, currentFps_timed);
    
    setTimeout(animate_timed, fpsInterval);
}

function animate(now) {
    // request another frame
    requestAnimationFrame(animate);
    
    // calc elapsed time since last loop
    var elapsed = now - lastDrawTime;

    // if enough time has elapsed, draw the next frame
    if (elapsed > fpsInterval) {
        // Get ready for next frame by setting lastDrawTime=now, but...
        // Also, adjust for fpsInterval not being multiple of 16.67
        lastDrawTime = now - (elapsed % fpsInterval);

        frameCount++;
    		drawNextFrame(now, canvas, ctx, currentFps);
    }
}
startAnimating(+$fps.val(), +$period.val());
input{
  width:100px;
}
#tvs{
  color:red;
  padding:0px 25px;
}
H3{
  font-weight:400;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>requestAnimationFrame skipping <span id="tvs">vs.</span> setTimeout() redraw</h3>
<div>
    <input id="fps" type="number" value="33"/> FPS:
    <span id="results"></span>
</div>
<div>
    <input id="period" type="number" value="1000"/> Sample period (fps, ms)
</div>
<canvas id="c"></canvas><canvas id="c2"></canvas>

@ টভনব দ্বারা মূল কোড।


2
var time = 0;
var time_framerate = 1000; //in milliseconds

function animate(timestamp) {
  if(timestamp > time + time_framerate) {
    time = timestamp;    

    //your code
  }

  window.requestAnimationFrame(animate);
}

আপনার কোডটি কী করছে তা ব্যাখ্যা করার জন্য দয়া করে কয়েকটি বাক্য যুক্ত করুন, যাতে আপনি নিজের উত্তরের জন্য আরও বেশি প্রস্তাব পেতে পারেন।
অস্পষ্ট বিশ্লেষণ

1

টাইমস্ট্যাম্পগুলিতে গোলমাল না করে আমি সবসময় এটি খুব সহজ উপায়ে করি:

var fps, eachNthFrame, frameCount;

fps = 30;

//This variable specifies how many frames should be skipped.
//If it is 1 then no frames are skipped. If it is 2, one frame 
//is skipped so "eachSecondFrame" is renderd.
eachNthFrame = Math.round((1000 / fps) / 16.66);

//This variable is the number of the current frame. It is set to eachNthFrame so that the 
//first frame will be renderd.
frameCount = eachNthFrame;

requestAnimationFrame(frame);

//I think the rest is self-explanatory
fucntion frame() {
  if (frameCount == eachNthFrame) {
    frameCount = 0;
    animate();
  }
  frameCount++;
  requestAnimationFrame(frame);
}

1
আপনার মনিটরটি 120 এফপিএস হলে এটি খুব দ্রুত চলবে।
কার্টিস

0

এখানে আমি একটি ভাল ব্যাখ্যা পেয়েছি: ক্রিয়েটিভ জেএস.কম, একটি সেটটাইমো মোড়ানোর জন্য) অনুরোধটি অ্যানিমেশনফ্রেমে পাস করা ফাংশনের অভ্যন্তরে কল। একটি "সরল" অনুরোধের সাথে আমার উদ্বেগ অ্যানিমেশন ফ্রেম হবে, "আমি যদি কেবল এটি দ্বিতীয় বার তিনবার সঞ্চারিত করতে চাই ?" এমনকি অনুরোধের সাথে অ্যানিমেশনফ্রেম (সেটটাইমআউটের বিপরীতে) এটি এখনও কিছু পরিমাণ "শক্তি" অপচয় করে (যার অর্থ ব্রাউজার কোডটি কিছু করছে, এবং সম্ভবত সিস্টেমটি ধীর করে দিচ্ছে) 60 বা 120 বা তবে এক সেকেন্ডে বহুবার মাত্র দুই বা তিনবার সেকেন্ডের বিরোধিতা (যেমন আপনি চাইবেন)।

বেশিরভাগ সময়ে আমি intentially জাভাস্ক্রিপ্ট সঙ্গে আমার ব্রাউজার চালানো বন্ধ শুধু এই কারণে। তবে, আমি ইয়োসেমাইট 10.10.3 ব্যবহার করছি এবং আমি মনে করি এটির সাথে কোনও ধরণের টাইমার সমস্যা রয়েছে - কমপক্ষে আমার পুরানো সিস্টেমে (তুলনামূলকভাবে পুরানো - যার অর্থ 2011)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.