Posts mit dem Label JavaScript werden angezeigt. Alle Posts anzeigen
Posts mit dem Label JavaScript werden angezeigt. Alle Posts anzeigen

2012-07-02

HTML5 und Mobile Apps

Warum mögen sich HTML5 und Mobile Apps nicht?


Immer wieder hört und liest man, dass HTML5 keine brauchbare Alternative zu nativen Apps ist - Hauptproblem: Performance!

So hat sich jetzt zum Beispiel angeblich auch Facebook dazu entschlossen, ihre iOS App noch einmal von Grund auf neu zu entwickeln (Facebook Abandoning HTML5 to Speed Up iOS App).

Auf der anderen Seite schafft es aber zum Beispiel ZaptoLab das beliebte Cut the Rope auf HTML5 / JavaScript zu portieren (Behind the Scenes). - Zwar mussten sich die Entwickler sehr auf die Performance konzentrieren, aber es ist ihnen gelungen.

Nun frage ich mich, ob die Performance-Probleme durch die Zwischenschicht zwischen nativ und HTML zustande kommen, ob die meisten HTML-Apps einfach schlecht entwickelt sind oder ob die Hardware der mobilen Geräte der ausschlaggebende Grund sind.



2010-10-24

"Append JavaScript at the end of my html file" - Component for Tapestry 5.1

This post describes a service, that enables Tapestry to append JavaScript files and script parts at the end of a html file. Script files and scripts can be "dropped into the service" from any page class or component and will be rendered in that order (FIFO) at the end of the page.

Upgrade Tapestry 5.0.x to Tapestry 5.1. loads included JavaScript files in the HTML head. Reasons are discussed in the Upgrade Notes: http://tapestry.apache.org/tapestry5.1/upgrade.html
project-wide release notes. They told me that in fix for bug TAP5-544:
Firstly, JavaScript libraries would have to move (back) to the head, permanently, no configuration [...].
Maybe I did not understand the real concern, but: Why isn't it up to the developer to decide where to place script files?
I decided to write a component that appends my script files at the end of my html files. The most important reason for this descicion is, that--following Yahoo's performance guidelines--I'd like to first load my HTML DOM before loading the script files.

Write a Service to Collect Files to Append
We need an Interface to be able to use the perthread scope (more about scoypes: "a per-thread instance is created on demand, behind a shared proxy").
The Interface just consists of 4 methods. 2 to add Script files and Scripts to the list and 2 to get the lists when they should be rendered:

public interface IAppendedScriptsService {

    /**
     * Add a script file to the list of script files to append.
     *
     * @param scriptFile
     */
    public void addScriptFile(String scriptFile);

    /**
     * Add a script to the list of scripts to append.
     *
     * @param script
     */
    public void addScript(String script);

    /**
     * Returns a list with script files to append. Needs to be a list to preserve order of script files.
     *
     * @return list with script files to append.
     */
    public List
getScriptFiles();

    /**
     * Returns a list with scripts to append. Needs to be a list to preserve order of scripts.
     *
     * @return list with scripts to append.
     */
    public List
getScripts();
}

The implementation of the Interface could looks like the following block. Don't forget to set the scope to perthread.

@Scope(value = ScopeConstants.PERTHREAD)
public class AppendedScriptsService implements IAppendedScriptsService {

    private final List
scriptFiles = new ArrayList();
    private final List
scripts = new ArrayList();

    @Override
    public void addScriptFile(String scriptFile) {
        this.scriptFiles.add(scriptFile);
    }

    @Override
    public void addScript(String script) {
        this.scripts.add(script);
    }

    @Override
    public List
getScriptFiles() {
        return this.scriptFiles;
    }

    @Override
    public List
getScripts() {
        return this.scripts;
    }

}

Build the Component
The Component was easy to write. It consists of just one method to render the scripts:
    // Inject the service we just wrote.
    @Inject
    private IAppendedScriptsService appendedScriptsService;


    // This method is called when component should be rendered. (Markup writer infos)
    void beginRender(MarkupWriter markupWriter) {


        // Output script files.
        if (!this.appendedScriptsService.getScriptFiles().isEmpty()) {
            for (final String file : this.appendedScriptsService.getScriptFiles()) {
                // There might be another (tapestry conform way) to create the source link. My way is
                String fileUrl = "MyAssetsServerURL".resolveRelative(file);
                markupWriter.element("script", "type", "text/javascript", "src", fileUrl);
                markupWriter.end();
            }
        }


        // Output script snippets.
        if (!this.appendedScriptsService.getScripts().isEmpty()) {
            for (final String script : this.appendedScriptsService.getScripts()) {
                markupWriter.element("script", "type", "text/javascript");
                markupWriter.getElement().text(script);
                markupWriter.end();
            }
        }


    }

That's all to implement. Just one last step to make this run:

Activate Service in AppModule
To activate your Service, following method must be inserted into AppModule.java (or just insert the binder-line if there is already such a method):
public static void bind(ServiceBinder binder) {
  binder.bind(IAppendedScriptsService.class, AppendedScriptsService.class);
}
User Component
To use this Component, you just have to add this into a class of a page or component: 
@Inject
private IAppendedScriptsService appendedScriptsService;


/**
* Append JavaScripts
**/
void setupRender() {
    this.appendedScriptsService.addScriptFile("UrlToScript");
    appendedScriptsService.addScript("var x = 'cool';");
}
The order of scripts and script files is preserved.

Do you have any comments? Let's discuss this in the Nabble Forum. I posted the Topic: "Append JavaScript at the end of my html file" - Component for Tapestry 5.1
EDIT: Howard Lewis Ship commented in the Nabble Forum:
The correct approach is to modify the DocumentLinker service (which is internal) to place the

2009-06-30

Google's OpenSocial

OpenSocial ist eine Menge von Programmierschnittstellen für Anwendungen in webbasierten sozialen Netzwerken. OpenSocial wird von Google entwickelt und wurde am 1. November 2007 veröffentlicht. (Quelle: Wikipedia-OpenSocial)
Stichworte zum Bauen von Social Applications
  • Gadgets bestehen hauptsächlich aus HTML und JavaScript.
  • API Namensräume (Javascript) sind opensocial.* und gadgets.*
  • Als Views gibt es in der Klasse gadgets.views.ViewType: Profile View, Canvas View und Home View.
  • Datenhandling/Persistenz findet über opensocial.DataRequest statt. Hierzu zählt auch der Zugriff auf Personen, Beziehungen, Aktivitäten und Nachrichten.
  • Der soziale Graph ist über opensocial.Person erreichbar. Rollen werden in VIEWER und OWNER unterschieden.
  • Aktivitäten: opensocial.Activity. Activity Templates können hierbei häufige Updates kumulieren.
  • Nachrichtenversand: opensocial.Message
  • Internationalisierung über Message Bundles in der XML-Spezifikation des Gadgets möglich.
  • Backend Requests, die über die Möglichkeiten von JavaScript und HTML hinausgehen sollen, können mit gadgets.io.makeRequest() abgesetzt werden. Somit ist der Transfer von HTML-, XML-, JSON- und ATOM-Files möglich. -> JSON, XML und AtomPub können auch über die RESTful API genutzt werden, die neben der JavaScript API existiert.
Quelle: OpenSocial Artikel von Matthias Häsel und Karsten Rieke - http://www.springerlink.com/content/d7624423x371w5v6/

Weitere Infos
Host OpenSocial Apps basierend auf Java oder PHP: Apache Shindig
Let's get this Shindig started


XING und OpenSocial:
XING and OpenSocial


Reblog this post [with Zemanta]

2009-05-10

Was mir neu war über JavaScript (bzw. was ich wieder vergessen hatte)

Beim Lesen des lesenswerten Buches "Das Beste an JavaScript" von O'Reilly und Yahoo!Press habe ich folgende Notizen zusammengestellt. Sie bieten einen guten Überblick über die Aspekte von JavaScript, die über Syntax-Fragen hinaus gehen
  • Vererbung über Prototypen (keine Klassen)
  • Prototyp-Verknüpfungen ermöglichen Vererbung. Dies kann Objekt-Initialisierungen und Speicherverbrauch reduzieren.
  • Objekte werden per Referenz übergeben und nicht als Kopie
  • Delegation über Prototyp-Ketten Object.prototype
  • Um zu verhindern, dass man (zB bei for..in) auch Funktionen in die Hand bekommt, sollte mit hasOwnProperty und typeof gefilter werden.
  • Die Funktions-Aufrufmuster bestimmen, wie der Parameter this initialisiert wird. Es gibt: Methoden-Aufrufmuster, Funktions-Aufrufmuster, Konstruktor-Aufrufmuster und Apply-Aufrufmuster.
  • Anzahl der Aufrufparameter einer Funktion wird nicht zur Laufzeit geprüft. Zu viele Parameter werden abgeschnitten, zu wenige, werden mit undefined gefüllt.
  • Muster:
    • Methode: Funktion als Eigenschaft eines Objekts. this wird an das Objekt gebunden.
    • Funktion: Funktion ist keine Eigenschaft eines Objekts. this wird an das globale Objekt gebunden (Fehler im Design der Sprache!) -> Methode kann innere Funktion nicht nutzen. Workaround: Methode definiert Variable that und weist ihr den Wert von this zu.
    • Konstruktor: (in Variablen mit Großbuchstaben) Funktionsaufruf mit new erzeugt ein neues Objekt und bindet this an das neue Objekt. (Konstruktoren NIE ohne new aufrufen!)
    • Apply: Wert von this wählbar, Array von Argumenten.
  • Eine funktion gibt immer einen Wert zurück. Ohne return-Wert wird undefined zurückgegeben.
  • Einer throw-Anweisung wird ein exception-Objekt übergeben, welches mindestens eine name- und eine message-Eigenschaft besitzt.
  • Hinzufügen einer Methode zu Object.prototype, macht diese für alle Objekte verfügbar (auch wenn diese schon erzeugt wurden).
  • Tail Recursion wird von JavaScript momentan nicht unterstützt.
  • Variablen besitzten keinen Block- sondern einen Funktions-Geltungsbereich. -> Variablen zu Beginn der Funktion deklarieren und nicht erst vor der Verwendung (am besten alle nach EINEM var). -> Zugriff auf Variablen außerhalb der Funktion möglich (außer this und arguments).
  • Kombination von Closures und Funktionen heißen Module. (Javascript Best Practices Folie 30). Dies ist der Begriff für die Technik, um so etwas wie Namespaces für Variablen abbilden zu können. Bei Closures wird einem Objekt keine Funktion zugewiesen, sondern das Ergebnis des Aufrufs dieser Funktion.
  • Callbacks damit der Client nicht steht, bis das Ergebnis kommt.
  • Kaskaden verwenden, indem eine Methode this zurückliefert.
  • Curry
  • Memoization: Bereits in Methoden berechnete Werte "merken". Diese Werte können in ein in einem Closure versteckten Array gespeichert werden.
Darüber hinaus gibt es:
  • Array-Methoden
  • Function-Methoden
  • Number-Methoden
  • Object-Methoden
  • RegEx-Methoden
  • String-Methoden
Da Funktionen Werte sind, zum Verständnis immer besser: var foo = function foo() {};


So, das reicht erst mal. Wenn ich das nächste Mal an JavaScript sitze, werde ich bestimmt wieder etwas hinzufügen können.