webForumDet fria alternativet

Flash hacka i webbläsare men inte i standalone

Flashur Flash, Shockwave

9 svar · 1 262 visningar · startad av oskob

Medlem sedan maj 20021 558 inlägg
Frågan#1

Hej!

Jag har återkommande stött på problemet att frameraten blir betydligt lägre när jag lägger flashen i en html-fil. Även då det inte är några specielt tunga animationer det handlar om så blir det onödigt segt, precis tillräckligt för att man ska störa sig på det. Det finns flash-spel och annat som är betydligt mer avancerat som flyter på helt utan problem. Vad beror detta på? Finns det något man kan tänka på för att få lite snabbare kod? Vad bör man undvika?

Tack på förhand!

Medlem sedan maj 2003750 inlägg
#2

Min erfarenhet är att Flashplayern i webbläsaren är uppemot 50% långsammare än standalone. Sedan har jag för mig att animationer via Actionscript är snabbare än "tweens".

Sedan är det en fråga om optimeringar, optimeringar och ännu mer optimeringar.

t.ex:

*) Håll antalet filter, semitransparanta objekt, omskalningar av bitmaps/videos etc så låg som möjligt.
*) Se till att stänga ner alla onEnterFrame som inte används.
*) Sätt en lämplig FPS. En för hög framerate kan vara lika minst förödande för en jämn playback som en för låg.
*) Undvik vektoriserade bitmappar.
*) Publicerar du för flash 8 så använd bitmap cache på sånt som inte förändras så ofta.

Medlem sedan maj 2005704 inlägg
#3

Utöver de utmärkta tips mirandadir föreslog så är det en bra idé att om du kör animeringar med actionscript basera rörelsen på tid istället för frames.

Alltså istället för t.ex. onEnterFrame=function(){ this._x+=10;}, använd getTimer() för att kolla hur lång tid har förflutit sedan sista uppdateringeringen och använd det värdet för att bestämma hur mycket objektet skall förflyttas. Förutom att ge en jämnare rörelse så blir hastigheten konstant i olika miljöer.

Om du inte kör med Flash 8 och därmed inte kan använda cacheAsBitmap, försök hålla dig till bitmaps så mycket som möjligt.
Undvik inte bara semitranspararenta objekt, utan även helt transparenta.

Det kan även vara ditt actionscript som är segt att exekvera. Där finns det mängder med sätt att optimera. Är det ett riktigt krävande spel t.ex. kan det vara bäst att undvika att använda OOP metodik och köra på enklare AS1 kod.
Håll dig till en loop för allt som måste uppdateras istället för att ha flera onEnterFrames, och fokusera på att optimera den loopen.
Vad som är optimalt beror en del på vilken version du publicerar för.
Om det är en version tidigare än 8 är denna artikel full av bra tips:
http://www.gotoandplay.it/_articles/2004/01/as_optimizations.php
För version 8 eller 9 är det mesta av tipsen dock irrelevanta.

Prestandavinsten är mycket stor om du kodar i AS3 och publicerar för Flash 9, och för spelutveckling kan det vara värt att börja med det redan nu även om det kommer dröja ett tag innan pluggen är riktigt vida spridd.

Medlem sedan jan. 2000640 inlägg
#4

- sätt window mode på opaque när du exporterar

eller

- http://board.flashkit.com/board/showthread.php?p=3330768

Medlem sedan maj 20021 558 inlägg
#5

Tack för all feedback!

Jag använder förvisso en del onEnterFrames men jag är alltid väldigt noga med att ta bort sånt när det inte används. När jag ska döda en onEnterFrame så skriver jag onEnterFrame = null; Är det rätt sätt?

Ang. helt transparenta objekt. Jag gör så att jag steg för steg drar ner opaciteten tills den blir 0 och sätter då _visible = false på objektet (fortfarande _alpha = 0). Då har jag fått för mig att den är helt i "vila".

Frameraten har jag satt till 30. Är det för högt kanske? Kan en för högt satt framerate påverka så att den egentliga frameraten blir lägre än om jag från början satt en låg?

Det här med getTimer(), är det bara för att förebygga att en animation som är 30 frames inte tar 30 sekunder på en långsam maskin och 1 sekund på en snabb eller är det även i sig bättre prestandamässigt?

Hur är det med ifsatser. I några animationer har jag byggt upp det med en massa else ifs. Tex:

var loadNew:Boolean = false;

function bytBild(nyBild) {
	
	var loadNew:Boolean = false;

	this.onEnterFrame = function() {
	
		if ( mrMc._alpha > 0 && !loadNew ) {
			mrMc._alpha -= 10;			// fadar ut
		}else if (mrMc._alpha <= 0 && !loadNew){
			mrMc.loadMovie(nyBild);			// laddar nästa bild
			loadNew = true;
		}else if (mrMc._alpha < 100 && loadNew){	// fadar in
			mrMc._alpha += 10;
		}else{
			this.onEnterFrame = null;		// dödar onEnterFrame
		}
	
	}

}

Hur är det t.ex. med variablar. Man "ska" väl deklarera allt genom var hej:Number; men det fungerar ju även om man bara skriver hej = 2;. Är det ens värt att ödsla tid på?

Medlem sedan maj 2005704 inlägg
#6

oskob skrev:

Tack för all feedback!

Jag använder förvisso en del onEnterFrames men jag är alltid väldigt noga med att ta bort sånt när det inte används. När jag ska döda en onEnterFrame så skriver jag onEnterFrame = null; Är det rätt sätt?

Är inte säker om det funkar rätt.
Kör "delete this.onEnterFrame;" istället för säkerhets skull.

oskob skrev:

Ang. helt transparenta objekt. Jag gör så att jag steg för steg drar ner opaciteten tills den blir 0 och sätter då _visible = false på objektet (fortfarande _alpha = 0). Då har jag fått för mig att den är helt i "vila".

De behöver inte renderas om de är satta till _visible=false så det skall inte spela någon roll om de är transparenta eller inte.
Däremot är det inte samma sak som att ta bort clippet med removeMovieClip, vilket är det bästa om det inte måste återskapas snart.

oskob skrev:

Frameraten har jag satt till 30. Är det för högt kanske? Kan en för högt satt framerate påverka så att den egentliga frameraten blir lägre än om jag från början satt en låg?

Är frameraten för hög så går det inte snabbare än med en låg framrate, men blir hackigare och större skillnad mellan olika miljöer.
Runt 30 brukar vara bra, men det beror förstås på applikationen.
Håll även ett öga på hur mycket CPU den drar. För ett spel kan man väl i princip ta över användarens dator, men en banner som drar 80% CPU för att se aningen smidigare ut än en som drar 10-20% är mycket irriterande tycker jag. Tänk på användaren och inte bara på att det skall se så bra ut det kan till varje pris.

oskob skrev:

Det här med getTimer(), är det bara för att förebygga att en animation som är 30 frames inte tar 30 sekunder på en långsam maskin och 1 sekund på en snabb eller är det även i sig bättre prestandamässigt?

Det påverkar inte prestandan och är främst för att se till att animeringen tar lika lång tid på olika miljöer.
Ofta så ger det ett intryck av att röra sig jämnare på en maskin som inte riktigt hänger med, men om maskinen inte alls kan hänga med kan det bli ännu ryckigare.

oskob skrev:

Hur är det med ifsatser. I några animationer har jag byggt upp det med en massa else ifs. Tex:

var loadNew:Boolean = false;

function bytBild(nyBild) {
	
	var loadNew:Boolean = false;

	this.onEnterFrame = function() {
	
		if ( mrMc._alpha > 0 && !loadNew ) {
			mrMc._alpha -= 10;			// fadar ut
		}else if (mrMc._alpha <= 0 && !loadNew){
			mrMc.loadMovie(nyBild);			// laddar nästa bild
			loadNew = true;
		}else if (mrMc._alpha < 100 && loadNew){	// fadar in
			mrMc._alpha += 10;
		}else{
			this.onEnterFrame = null;		// dödar onEnterFrame
		}
	
	}

}

Varje if sats tar tid förståss, men om den första värderar till true så kommer inte else satserna köras.
Det betyder att de som är mest sannolika att värdera till true bör vara först för snabbast möjliga exekvering.
Det är även snabbare att dela upp varje villkor i en separat sats om möjligt.
I ditt exempel är det kanske inte möjligt, men av nedanstående exempel är det andra snabbast:

if(foo==true && bar==true){
      // gör grejer
}

if(foo==true){
   if(bar==true){
      // gör grejer
   }
}

Skillnaderna är små, men om du har en loop som kör mängder med if satser varje frame är det värt att kolla hur man får absolut maximal presatnda från sin kod.

oskob skrev:

Hur är det t.ex. med variablar. Man "ska" väl deklarera allt genom var hej:Number; men det fungerar ju även om man bara skriver hej = 2;. Är det ens värt att ödsla tid på?

Använder du "var" innan du deklarerar en variabel i en funktion så blir den lokal i funktionen och tas bort då funktionen körts klart. Det gör att det blir mindre oanvända variabler som ligger och dräller vilket är bra för prestandan.
Om du kör med strikt typing eller inte (var num:Number) spelar dock ingen roll prestandamässigt då det inte finns någon typing i den kompilerade koden, men det kan vara smidigt för att undvika buggar och påverkar inte prestandan negativt.

Medlem sedan maj 20021 558 inlägg
#7

Blixtsystems skrev:

http://www.gotoandplay.it/_articles/2004/01/as_optimizations.php

Skitbra sida! Fick svar på många frågor där (y)!

Mr Nils skrev:

sätt window mode på opaque när du exporterar

Det gjorde faktiskt skillnad! Tack för det :bire

Medlem sedan maj 20021 558 inlägg
#8

Tack åter igen Blixsystems för alla svar! Väldigt användbart! Nu klarar jag mig ett tag till :i :birp

Medlem sedan maj 2005704 inlägg
#9

oskob skrev:

Skitbra sida! Fick svar på många frågor där (y)!

Helt klart en hel del bra tips, men mycket är som sagt inte relevant längre.
T.ex så var "while" loop snabbare i flash 7 än en "for" loop, men så är icke fallet med flash 8.

För råd då det gäller flash 8 kan jag rekommendera: http://www.oddhammer.com/actionscriptperformance/set3/

Medlem sedan maj 20021 558 inlägg
#10

Tack en tredje gång! Ska ta en titt

136 ms totalt · 3 externa anrop · v20260731065814-full.55e59744
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)