As you design and code widgets, use the following general best practices as a guideline:
Self-contain your widgets
As you plan, design, and develop widgets, remember that they are not isolated from other components. To ensure that your widgets are compatible with those other components, make sure all artifacts that are pushed into any global objects or namespaces are unique and do not collide with other components, including a second copy of the same widget.
Since you can never assume that a full browser context is available, confirm that your widget runs properly both in an iFrame and inline with another copy of itself. In addition, use the following best practices for self-containing your widgets:
Multiple components should share the same view and models
Since multiple components such as widgets and page-level controls are rendered together on the same page, they should share the same view and models, for example:
The browser's Document Object Model (DOM)
To assist in other environments, prefix all HTML ID attributes with the widget unique identifier, _IWID_ for iWidgets and __MODULEID__ for gadgets. The loader replaces these attributes with unique tokens so that a scoped search can use the browser's methods to improve efficiency.
Use a scoping instance to encapsulate all methods and variables the widget defines and uses.The cascading style sheet (CSS) model
Style sheets define the look and feel for multiple components on the page.Scope object lookups
scoping objects and object lookups within the browser DOM. As part of a proposal for inlining OpenSocial gadgets, IBM
® is proposing the scoping portion of this functionality. To scope object lookups, use __MODULEID__
as part of relevant names so that they become specific to the instance of the iWidget.
Plan for other shared areas
objects before using them and avoid polluting the global namespace by using the scoping object to store all data.
When necessary, use a Java-style package naming convention such as dojo.io.script. For performance reasons, look up the global namespace only once within an object and store it in a local or instance variable. For more information, see Packaging for performance and multiple environments
Use the programming model
environment offers great flexibility, always use the programming model for optimal performance. Follow these best practices for using the programming model:
- Store customizations as user preferences.
- Use one of the communication features, such as iContext.io.request for iWidgets or gadget.io.makerequest for OpenSocial gadgets, instead of raw XHR to communicate with server components.
- Use the event feature for temporal interactions with other widgets.
- Use metadata to describe your widget and its resources, including the Dojo library, CSS files, and shared components such as Lotus® Connections utilities.
Use standard client-side libraries for abstraction
Use the following best practices for libraries:
- Use libraries such as Dojo or jquery to avoid compatibility issues between browsers. Be sure to declare them in your metadata.
- If the design of the widget requires using the library's onload callback, such as dynamically requiring additional Dojo capabilities, register the library when processing the environment's onLoad callback. For more information, see the Dojo afterOnLoad example on the OpenAjax website.
- Do not use library or browser abstractions to communicate between widgets, as these abstractions work for widgets in separate iFrames. Use the container communication APIs instead, as described above.
- Do not use library or browser life cycle abstractions, such as the onload handler. The life cycle of the widget is controlled by its container and not directly by the browser or library. Use the life cycle events provided by the container instead.
Note that you cannot load two widgets with different versions of the same library that is using a global namespace. A possible reason is that the widget is rejected on deployment or when it is added to the page. Another possible reason is that it might be sandboxed as long as a global namespace conflict exists on the page. However, no automated support is currently available.
Design for high-latency/low-bandwidth networks
Your widget may run on a high-latency/low-bandwidth network, which may cause long loading times when making several connections. Use the following best practices to ensure that your widget performs well in these environments:
- Reference all resources within the metadata so the system can apply performance optimizations, such as loading all components using a file combiner of a multipart request and response.
- Keep all resources under 15K so that the iPhone caches them.
- Use CSS sprites whenever possible to limit the number of images to be downloaded. Also reduce the spacing between images in the sprite to conserve memory in the browser.
- Convert GIF files to PNG files.
- Strip metadata such as EXIF and IPTC from JPEG files.
- Resize images in the beginning instead of downloading a larger file and then scaling it in the browser.
- Combine CSS files into one file and strip all comments to make the file as small as possible.
- Strip all comments from HTML files to make them as small as possible.
- When using Dojo, use the Dojo build process.
Note that you can often combine and shrink files during the build process. Combining and shrinking files do not typically affect the design or architecture of the widget.
Test your widget in a reference container
Currently, the reference container for OpenSocial gadgets is Apache Shindig. For more information, see the Apache Shindig website
Parent topic: Best practices for developing gadgets and widgets