Tipy a techniky

by 2 contributors:

This translation is incomplete. Please help translate this article from English.

Jeden z nejlepších zdrojů na tipy, triky a techniky pro vývoj open Web Apps -- obzvláště aplikací pro Firefox OS -- je náš výborný tým Firefox OS a Gaia vývojářů. Tato stránka přináší několik jejich nápadů. Užij si to!

Instalace a aktualizace

Následují tipy a řešení (workarounds) související s instalačním a aktualizačním procesem, manifesty aplikací, a tak dále.

Aplikace se neaktualizuje, i když používám appcache manifest

Please check if you send Cache Headers for your appcache manifest. If you don't, Gecko will use heuristic caching and will serve it from its cache for a few hours. We recommend that you configure an immediate expiration for your appcache manifest. The following Apache config will do just that:

AddType text/cache-manifest .appcache
ExpiresByType text/cache-manifest "access"

This might be a good idea for your webapp manifest too:

AddType application/x-web-app-manifest+json .webapp
ExpiresByType application/x-web-app-manifest+json "access"

Performance

Here, we assemble advice that will help you create Web apps that perform well, without bogging down the device hardware.

Use CSS animations and transitions

Instead of using some library’s animate() function, which probably currently uses many badly performing technologies (window.setTimeout() or top/left positioning, for example) use CSS animations. In many cases, you can actually use CSS Transitions to get the job done. This works well because the browser is designed to optimize these effects and use the GPU to handle them smoothly with minimal impact on processor performance. Another benefit is that you can define these effects in CSS along with the rest of your app's look-and-feel, using a standardized syntax.

CSS animations give you very granular control over your effects using keyframes, and you can even watch events fired during the animation process in order to handle other tasks that need to be performed at set points in the animation process. You can easily trigger these animations with the :hover, :focus, or :target, or by dynamically adding and removing classes on parent elements.

If you want to create animations on the fly or modify them in JavaScript, James Long has written a simple library for that called CSS-animations.js.

Use CSS transforms

Instead of tweaking absolute positioning and fiddling with all that math yourself, use the transform CSS property to adjust the position, scale, and so forth of your content. The reason is, once again, hardware acceleration. The browser can do these tasks on your GPU, letting the CPU handle other things.

In addition, transforms give you capabilities you might not otherwise have. Not only can you translate elements in 2D space, but you can transform in three dimensions, skew and rotate, and so forth. Paul Irish has an in-depth analysis of the benefits of translate() from a performance point of view. In general, however, you have the same benefits you get from using CSS animations: you use the right tool for the job and leave the optimization to the browser. You also use an easily extensible way of positioning elements — something that needs a lot of extra code if you simulate translation with top and left positioning. Another bonus is that this is just like working in an <canvas>.

Use requestAnimationFrame() instead of setInterval()

Calls to window.setInterval() run code at a presumed frame rate that may or may not be possible under current circumstances. It tells the browser to render results even while the browser isn't actually drawing; that is, while the video hardware hasn't reached the next display cycle. This wastes processor time (and can even lead to reduced battery life on the user's device).

Instead, you should try to use window.requestAnimationFrame(). This waits until the browser is actually ready to start building the next frame of your animation, and won't bother if the hardware isn't going to actually draw anything. Another benefit to this API is that animations won't run while your app isn't visible on the screen (such as if it's in the background and some other task is operating). This will save battery life and prevent users from cursing your name into the night sky.

Make events immediate

As old-school, accessibility aware web developers we love click events as they also come with the added benefit of supporting keyboard input. On mobile devices, these are too slow. You should use touchstart and touchend instead. The reason is that these don’t have a delay that makes the interaction with the app appear sluggish. If you test for touch support first, you don’t sacrifice accessibility either. For example, the Financial Times uses a library called fastclick for that purpose, which is available for you to use.

Keep your interface simple

One big performance issue we found in HTML5 apps was that moving lots of DOM elements around makes everything sluggish — especially when they feature lots of gradients and drop shadows. Simplyfying your look-and-feel and moving a proxy element around when you drag and drop helps a lot.

When, for example, you have a long list of elements (let’s say tweets), don’t move them all. Instead, keep in your DOM tree only the ones that are visible and a few on either side of the currently visible set of tweets. Hide or remove the rest. Keeping the data in a JavaScript object instead of accessing the DOM can vastly improve your app's performance. Think of the display as a presentation of your data rather than the data itself. That doesn’t mean you can't use straight HTML as the source; just read it once and then scroll 10 elements, changing the content of the first and last accordingly to your position in the results list, instead of moving 100 elements that aren’t visible. The same trick applies in games to sprites: if they aren’t currently on the screen, there is no need to poll them. Instead re-use elements that scroll off screen as new ones coming in.

Media presentation

Currently, for security reasons, the h.264 decoder on Firefox OS devices is only available to privileged code. Because of that, you can't use the <video> element to present h.264 content at this time. You can, however, use a Web Activity. Here's a code snippet that can help:

var activity = new MozActivity({
  name: "view",
  data: {
    type: [
      "video/webm",
      "video/mp4",
      "video/3gpp",
      "video/youtube"
    ],
    url: "http://example.com/myvideo.mp4"
  }
});

This asks Firefox OS to present the MP4 video at the specified URL. You can include one or more video format types in the type list to permit.

Troubleshooting

Whitelist "app:/" protocol with AngularJS

If you have developed a packaged app with AngularJS, you may run into this error message:

The address wasn't understood 
Firefox doesn't know how to open this address, because the protocol (unsafe) isn't associated with any program. 

When you use Angular data binding to generate a URL, Angular will match the URL against its whitelist. If the URL does not match, Angular prefixes the url with "unsafe:" (see the Angular documentation). To make you app work with AngularJS, you can add "app:/"--the protocol FirefoxOS packaged apps use--to Angular's whitelist. In your app's configuration, this is how to whitelist "app:/":

var app = angular.module( 'myApp', [] ).config(['$compileProvider', function($compileProvider) {
        $compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|app):/);
    }
]);

Or in AngularJS 1.1+

var app = angular.module( 'myApp', [] ).config(['$compileProvider', function($compileProvider) {
        $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|app):/);
    }
]);

Document Tags and Contributors

Contributors to this page: teoli, mist
Last updated by: teoli,