Rendering The Fat

  • 3,859 views
Uploaded on

A look at how to create slim item renderers for large applications to keep performance up on DataGrid and AdvancedDataGrid in Flex 3.

A look at how to create slim item renderers for large applications to keep performance up on DataGrid and AdvancedDataGrid in Flex 3.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,859
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
23
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Rendering the Fat:
    How to Keep Your DataGrid Healthy
    Ben Schmidtke III
    Digital Primates
    bschmidtke@digitalprimates.net
    Twitter: stunnedgrowth
  • 2. Who Am I
    Ben Schmidtke III
    Consultant - Digital Primates IT Consulting Group
    Flash Platform Developer for 11 years
    Adobe Certified Instructor
    Twitter: stunnedgrowth
  • 3. Agenda
    Overview of List Components
    DataGrid and AdvancedDataGrid
    Why should we take care of them
    ItemRenderers
    Building Slim ItemRenderers
    Tips and Guidelines
    Questions
  • 4. Get To It
    Focus will be looking at best practices for dealing with custom cell formatting
    Data customization in DataGrid and AdvancedDataGrid
    Many of the concepts can be used in the other List components
  • 5. The Interwebs
    The Internet is full of examples about how to use Flex components.
    Some are great
    Some are ok
    Others, let’s pretend they don’t exist.
  • 6. Out Of The Box
    Flex 3 provides several components for presenting data in a list format:
    List Controls
    List
    Tree
    DataGrid
    TileList
    Menu
    And More…
    • Data Visualization
    AdvancedDataGrid
    OLAPDataGrid
  • 7. General Features
    Support Multiple Data Types
    Drag and Drop
    Scrolling - Vertical and Horizontal
    Cell Editing
    Variable Row Height
    labelFunction
    And more...
  • 8. DataGrid: What Is It?
    Presents data in a Table format
    Rows
    Columns
    Can automatically create rows & columns based on the data
    Single Column Sorting
    Column Reordering
  • 9. AdvancedDataGrid
    Supports all the functionality of DataGrid
    Provides support for Hierarchical Data
    Understands how to display parent/child relationships.
    XML, XMLList, HierarchicalData, HierarchicalCollectionView
    Custom objects with “parent” and “children” properties
    Advanced Sorting (Multiple Columns)
    Column Grouping
  • 10. In Short They…
    Are a view for the data model
    Can render data multiple ways
    Flat, Hierarchical Data, Grouped
    Are a control that render other controls
    Headers
    Renderers
    Editors
    ScrollBars, Lines & Other UI Stuff
  • 11. Why should we take care of it?
    Performance
    Troubleshooting
    Flexibility
    Maintainability
  • 12. It Takes Work
    Large quantities of information
    Each cell is a component
    The more rows and columns displayed decreases performance
  • 13. What Could Go Wrong?
    Cells appear slow to display
    Content placed incorrectly “sometimes work, sometimes not work”
    Content shift a few pixels for no reason
    Scrolling is jumpy or lag
    Sorting & Column reordering take a long time to process
    In worst case, it crashes.
  • 14. It All Boils Down To
    Unexpected Results
    Poor User Experience
    Cranky Client 
    Your Personal Health: Stress
  • 15. The Fat : ItemRenderers
    What are they?
    Purpose:
    Read data
    Present the data (Text, Icons, Controls, etc.)
    What are they not?
    Things that compute data to display
    mx.containers.* (HBox, Canvas, etc.)
  • 16. ItemRenderer Lifecycle
    In general, list components will only create as many ItemRenderers as needed to display
    1 Column X 10 Visible Rows = 10 Renderers
    100 data objects = 10 Renderers
    Plus one or two extra for performance reasons
    ItemRenderers are Recycled
  • 17. The Default: It’s Text!
    DataGrid
    DataGridItemRenderer
    Extends UITextField > FlexTextField > TextField
    AdvancedDataGrid
    AdvancedDataGridItemRenderer
    Extends UITextField > FlexTextField > TextFIeld
  • 18. Why Is It Text?
    Extremely lightweight
    Direct and to the point
    Take the least amount of time to create and display
    No container overhead
  • 19. But Containers Are Easy…
    Containers provide a lot of useful functionality:
    Automatic Layout: Horizontal & Vertical
    Absolute Layout: Coordinates X and Y
    Scrollbars
    Dividers, Tabs, etc.
  • 20. Too Much Functionality
    Containers are performance heavy
    Everything that makes them easy, slows them down
    10 Rows + 10 Columns = 100 Containers
  • 21. Custom ItemRenderers
    Depending on the project requirements, it most likely require a custom ItemRenderer
    Different text colors based on the data
    Support for icons
    Support for other Controls
    CheckBox, ComboBox, etc.
  • 22. Do you need one?
    If you do not need one, do not create one
    Custom String Manipulation
    Use a label function if possible
    Can be done with out creating a renderer
  • 23. Typical Label Function
    public function myLabelFunction(item:Object,column:DataGridColumn):String
    {
    return item.firstName + " " + item.lastName;
    }
    <mx:DataGrid dataProvider="{myDataProvider}">
    <mx:columns>
    <mx:DataGridColumn labelFunction=“myLabelFunction"/>
    </mx:columns>
    </mx:DataGrid>
  • 24. That doesn’t cut it
    A single question is the determining factor for the approach of a ItemRenderer.
    Q: Does the content require something other than text or a label function can provide?
    A) No, formatting, custom styling, truncated text
    B) Yes, I need some icons or checkbox
  • 25. Just some formatting…
    Extend the Base ItemRenderer Class for the component
    AdvancedDataGridItemRenderer
    DataGridItemRenderer
    Etc.
    They extend UITextField
    Override validateProperties();
  • 26. ValidateProperties()
    The part of DataGridItemRender that:
    Sets the Text property on the TextField
    Sets the Tooltip
    Applies WordWrap based on Column settings
    Apply any necessary formatting based on the data here
  • 27. Unhealthy Text Renderer
    <mx:AdvancedDataGridColumn headerText=“Add User">
    <mx:itemRenderer>
    <mx:Component>
    <mx:HBox width="100%" height="100%">
    <mx:Label id=“userLabel” text="{data.name}“
    styleName="{((data.name == 'Jack') ? 0x990000 : 0x000000)}”/>
    <mx:Image source=“{data.imageURL}” />
    </mx:HBox>
    </mx:Component>
    </mx:itemRenderer>
    </mx:AdvancedDataGridColumn>
  • 28. What is wrong with it?
    Improper use of a Container
    Unknown length of the user name
    ScrollBars
    Inline ItemRenders are unable to be reused elsewhere in the application
  • 29. Healthy Text Renderer
    public class ExpiredUserItemRenderer extends AdvancedDataGridItemRenderer
    {
    override public function validateProperties():void
    {
    super.validateProperties();
    if (data && listData)
    {
    text = listData.label;
    if((data is Person) && (data as Person).isExpired == true)
    {
    setStyle("color", "0x990000");
    toolTip = “Warning! “ + listData.label;
    }
    else
    {
    setStyle("color", "0x000000");
    toolTip = listData.label;
    }
    }
    }
    }
  • 30. Why Is It Healthy?
    It is still just a TextField
    Does the least amount of work to present the custom text
    No additional overhead from Container classes or UIComponent
  • 31. Rendering Other Controls
    When rendering images or multiple controls:
    Extend UIComponent
    Implement Interfaces
    IDataRenderer
    IListItemRenderer
    IDropInListItemRenderer (Optional)
    Build Custom Functionality
  • 32. Interfaces Part 1
    IDataRenderer
    data (value:Object)
    Provides the data object for the entire row
  • 33. Interfaces Part 2
    IListItemRenderer
    All renderers must implement this interface
    Does not define any new methods
    Extends several other Flex Interfaces
    UIComponent already has required properties and methods
  • 34. Interfaces Part 3
    IDropInListItemRenderer (Optional)
    listData (value:BaseListData)
    Provides additional information to the renderer: Column Index, Row Index, dataField
    Allows the renderer to be re-used with different data fields and List components
  • 35. Custom Functionality
    Since we are extending UIComponent, we have the Flex Component Life Cycle
    createChildren()
    commitProperties()
    measure()
    updateDipslayList(…)
  • 36. Unhealthy Renderer
    <?xml version="1.0" encoding="utf-8"?>
    <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
    <![CDATA[
    protected function linkbutton_clickHandler(event:MouseEvent):void
    {
    // navigate to data.url
    }
    ]]>
    </mx:Script>
    <mx:HBox>
    <mx:Label id="city" text="City: {data.city}" />
    <mx:Label id="state" text="State: {data.state}“ />
    </mx:HBox>
    <mx:LinkButton label="More Information“ click="linkbutton_clickHandler(event)"/>
    </mx:VBox>
  • 37. Another Unhealthy Renderer
    override protected function commitProperties():void {
    if(dataChanged) {
    // start over
    removeChild(pdfIcon);
    removeChild(labelField);
    }
    }
    override protected function updateDisplayList( … ):void {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    if(data && !pdfIcon) {
    createPDFIcon();
    }
    if(data && !labelField) {
    createLabelField();
    }
    // position & sizing logic

  • 38. What is wrong with it?
    Improper use of the display list
    Using removeChild() & addChild() every time the data changes when unnecessary
    If you know what you need, create it once and update it when the data changes
  • 39. Healthy Version
    override protected function commitProperties():void {
    if(dataChanged) {
    // update the text on the label
    if(data) {
    labelField.text = data.labelField;
    labelField.visible = true;
    } else {
    labelField.text = “”;
    labelField.visible = false; }
    }
    }
  • 40. Healthy Component Renderer
    Example of a Text & Icon Renderer
  • 41. Tips for Healthy ItemRenderers
    Avoid extending or containing anything in the mx.containers.* package.
    Using a Repeater
    Using Remote Objects! Don’t Do it!
    Inappropriate use of the display list.
    • addChild(), removeChild(), etc.
    Excessive recursion in the UIComponent lifecycle.
    Directly modifying the data model, remember it’s a view
  • 42. Guidelines
    When displaying:
    Text: Extend base ItemRenderer component
    Images & Controls: Extend UIComponent
    Add items to the display list once.
    Avoid removing items from the display list unless necessary
  • 43. Summary
    Know the issues related to a poorly performing DataGrid
    Ask the right question before creating a custom ItemRenderer
    Base ItemRenderer classes, UITextField and UIComponent are your friends
    Don’t be afraid to get in there
  • 44. Questions?
  • 45. Thank You
    Ben Schmidtke III
    Consultant - Digital Primates IT Consulting Group
    bschmidtke@digitalprimates.net
  • 46. Bonus Slides
  • 47. Performance Note
    A majority of all performance issues with AdvancedDataGrid are related to improper use of a custom item renderer.
    Even if when updating the dataProvider collection more than necessary, a single poorly made item renderer can decrease performance severely.
  • 48. The DataProvider
    Will accept pretty much anything
    override public function set dataProvider (value:Object):void
    Behind the scenes if it does not meet certain criteria, it becomes something else.
  • 49. The DataProvider
    All data is or becomes one of two types:
    ICollectionView
    ArrayCollection
    XMLListCollection
    IHierarchicalCollectionView
    HierarchicalCollectionView
  • 50. Behind The Scenes
    if (value is Array) {
    collection = new ArrayCollection(value as Array);
    } else if (value is XMLList) {
    collection = new XMLListCollection(value as XMLList);
    }
    ...
    else {
    // convert it to an array containing this one item
    var tmp:Array = [];
    if (value != null)
    tmp.push(value);
    collection = new ArrayCollection(tmp);
    }
  • 51. CollectionEvent
    collection.addEventListener(
    CollectionEvent.COLLECTION_CHANGE, …);
    AdvancedDataGrid watches for CollectionEvent to respond accordingly keeping things up to date.
    HierarchicalCollectionView Caches parent/child relationships for quick lookups and respond to the parent & children properties changing.
  • 52. Issue 1: CollectionEvent
    Every time a collection event is dispatched on the dataProvider, AdvancedDataGrid may perform a considerable amount of work including:
    Rebuilding the data view
    Reconstructing Hierarchical Structures & Updating Cached Collections if necessary
    Setting the data on all visible renderers
  • 53. DataProvider Guidelines
    Manage your data prior setting the dataProvider
    ArrayCollection, XMLListCollection or HierarchicalCollection
    Apply updates to data objects in bulk if possible
    Example: When editing a property, set the value once not one character at a time.