Category Archives: Uncategorized

OnDemand Deferred Rendering with CreateJS & Canvas


I wanted to highlight how we handle rendering on <canvas> with CreateJS/EaselJS as this approach has drastically improved our app performance. First lets look at how things are typically done. There are 2 common approaches to rendering:

  • Constant Rendering – Render at a frame rate… 30 frames per second.
  • OnDemand Rendering – Render frames as you need them…. now….now…wait…now etc.

The constant frame rendering approach attempts to render at a frame rate typically aligned with the browser RequestAnimationFrame. The problem here is that typically you are rendering more than you need. If the canvas contents are idle (no visual change) every frame render is a drain on system performance. Essentially you are doing work with no real benefit.

The OnDemand Rendering approach renders frames as you need them rendered. The problem here is that the frequency of rendering can become faster than you need during heavy use. Typically you have many elements that call render so if you update many items at once, there will be a flood of rendering calls. Unlike the constant frame rendering with onDemand rendering it is easy to create a hotspot where you are rendering a ton, then none.

We tested both of these approaches when designing our print applications (walmartstationery/expressionery/iprint) and we fell into a middle ground… OnDemand Deferred Rendering. With this approach our code calls the renderer as we need to but actual rendering is deferred to align with a frame rate we set which happens to align with RequestAnimationFrame. It is a mix of both models in that things always render at a set frame rate but we choose when we render.

Here is how it works:

  • Create a “render” function to call when we want a render to be performed.
    • This call simply sets a “renderFrame” variable to true regardless of its value.
    • Even if every element calls render, it simply sets “renderFrame” to true.
    • This is a very light operation
  • Create the “real” rendering function to update the stage only when “renderFrame” is true and then reset “renderFrame” to false
    • function realRenderer(){ if( renderFrame ){ stage.update();renderFrame=false; } }
  • Create a Ticker event to call a realRenderer() at a frame rate aligned with RAF:
    • createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
    • createjs.Ticker.setFPS( 30 );
    • createjs.Ticker.addEventListener( "tick" , realRenderer );

So we have a frame rate but you must call render() for it to really do any real rendering. If you never call render(), nothing happens and <canvas> is essentially an image. If you flood the render() call, it will only render 1 time within a frame rate. If render() is called after realRenderer() is called, you just get 2 frames properly distanced at the frame rate, then back to no rendering.

With this technique we found that performance was very high even on mobile devices, yet we never overloaded the system during heavy interactivity. Better still when the user stopped interacting, the system would go idle and allow the system time to recover. In many cases graphics performance was 3x that of using a constant framerate and we never had a hotspot in our rendering.

Cheers,

Ted :)

Salesforce “Hackathon” revisited


Having participated in the Salesforce “Hackathon” and watched the controversy unfold during judging and today, I want to share my opinion.

The event at Dreamforce was NOT a “hackathon” by definition, it was something new and something very different. The entries were more serious, the teams working on solutions were professional, and overall the stakes were higher in terms of raw prize money and visibility at Dreamforce. Along these lines, Salesforce deserves credit for creating a new type of event and should be given the license to make mistakes and innovate, rather than being judged as a classic “Hackathon”.

I feel that the “hackathon” should change into a longer year-long developer event to create new solutions against Salesforce/Heroku and steer clear of the short-term “hackathon” distinction. Here is my thoughts on next years event given that plan are afoot:

Dreamforce “Appathon” – A year long developer contest to create the best salesforce/heroku app, judged at Dreamforce.

  • 12 months to develop, start now.
  • Due week prior to Dreamforce.
  • NDA Developer access to new APIS.
  • Award top 25 teams a mini-booth at Dreamforce to present solutions.
  • Attendee Voting: Dreamforce attendees vote for top 10 solutions.
  • Judging: Judging panel determines top 5 and winner.

If the goal is to create new apps that integrate deeply with Salesforce/Heroku and to provide visibility to what is created then shifting towards an “Appathon” seems more appropriate.

Regardless, I am looking forward to participating again next year.

Ted :)

SalesForce $1M Hackathon: What I learned


This morning I received an email that zip.ly was rejected as a finalist in the Salesforce Hackathon, thus ending a 3 week sprint of software development. Attempting to assemble a product in 3 weeks is an act of insanity but having turned off consulting for the year, a good domain name, and the desire to work on something new; our team jumped in head first. The experience was well worth it as I found myself learning more in these 3 weeks than I learned all year. It was very rewarding and yielded some unexpected fruit in terms of skills and a foundation to build services.

Special thanks to the team at SalesForce who executed the Hackathon. It was perfect but the only thing I would change is adding a RedBull soda fountain onsite next year and forging a partnership with Mel’s dinner around the corner and keep them open all night for Hackathon attendees. As someone who has run developer events, the execution at Dreamforce was world class.

I learned a metric ton in building zip.ly and I wanted to share the list of technology and what worked great and what did not. As with all technology decisions, perspective matters and over the course of development my option shifted on several technologies in use.

Server-Side I used Python/Flask/Jinga/SQLAlchemy/Postgresql and this was by far the best decision. The server was easy to change and the mature ecosystem surrounding python is a great asset. I quickly found key libraries for handling Imaging and PDF generation in PIL, ReportLab.pdfgen, pyPdf, and xhtml2pdf. If you need to generate any type of PDF document between these 4 you can get the job done fast. The hardest element here was not generating the files themselves but working around not having a file system on Heroku. I found several key workarounds using Python’s StringIO and BytesIO that proved to be excellent solutions to avoiding reading and writing to disk.

For persisting files, I leaned on Amazon Web Services via the Python Boto library. It is a great library and makes working with AWS easy. Once you get keys and permissions set, you can control AWS like a boss with very little code. For example here is the code in boto to write a pdf to S3:

s3 = S3Connection()
s3b = s3.get_bucket( 'my_bucket' , validate=False )
key = s3b.new_key( 'path/to/file.pdf' )
key.set_contents_from_file( StringIO( pdf_data ) )

The trick with Boto is that keys are optionally pulled from environmental variables so this aligned well with Heroku.

Jinga templating was also a standout as I switched to using “extends” templating late and it saved us. I was quickly able to reuse assets from a library of markup and violently change our ui late. Looking back I would not have finished the app had we not done this. Jinga just works.

SQLAlchemy is amazing. It is easily one of the best DB/ORM abstractions I have every used. Yes I have used Hibernate, but SQLAlchemy falls into the ORM you can control and avoids the dark mysteries of schema migration hell. Rather than having things be automatic in SQLAlchemy, you have to tell it what to do. Here are a few great examples:

app.config[ 'SQLALCHEMY_DATABASE_URI' ] = os.environ[ 'DATABASE_URL' ]
db = SQLAlchemy( app )

class Draft( db.Model ):
    id = db.Column( db.Integer , primary_key=True )
    userid = db.Column( db.Integer )
    name = db.Column( db.String( 100 ) )
    text = db.Column( db.Text )
    signers = db.Column( db.Text )

#careful with these 2
db.drop_all() #drop em all
db.create_all() #generate tables from model classes

In zip.ly I did the db.drop_all() and db.create_all() as part of updating the app. It was trivial to generate schema changes or a whole new schema from our model classes. I will be using this library for years to come… A+.

About 1 week into development, the $99 entrance fee was refunded by SalesForce so I decided to spend those funds on an SSL Certificate for zip.ly. I purchased the cert from RapidSSL and learned the ins and outs of generating .CSR .KEY .PEM and applying them successfully to a domain on Heroku. With the SSL cert in place it enabled us to integrate SalesForce.com OAUTH and thus call the SalesForce REST API.

In the process of integrating SalesForce OAUTH2, I struggled with several libraries but quickly fall back to use Requests in Python. In short order I had OAUTH fully working and was able to call the SalesForce REST API for Identity and adding Contacts. The REST API at SalesForce is a real gem to work with given it’s simplicity. Once you get the AuthToken, you can call any API by setting the “Authorization:Bearer” header with the AuthToken and adding a JSON payload. This was a gem to work with and makes deeper SalesForce integration easy.

Client-side was a frustratingly bumpy road and while I had great ambitions of having a great Single Page Application, late in development things came unglued so we fell back to server-side page rendering. As part of the learning on the app, we started using AngularJS which is an amazing library when you know what you are doing. Unfortunately while integrating AngularJS with our JSON API, I started to see errors that I did not understand and worse the only choice I could make was to rip it out with the Hackathon deadline looming at 36 hours to go. We will return to AngularJS after learning far more.

The “B” word… “Bootstrap”. We picked Bootstrap early and I regret the decision. Bootstrap is brittle as you must accept things the “Bootstrap way” or you will struggle. For some projects it is great and will get you started fast but it is hard technology to integrate when you know exactly what you want. The CSS is filled with “important!” so you quickly go into “important! hell” and are covered in some sticky goo that you need solvent to remove. I will not go back to Bootstrap unless they restructure and remove the “important!” mess within the framework. Again it is great for some things but for detail work it can get hellish. I am tempted to move towards using Topcoat or Pure when we revisit UI selection.

EaselJS, I LOVE YOU! If you want to rock the canvas in an app, look no further than EaselJS. I had to rebuild the signing aspect of the app late to support multiple signatures and embedded text and had it fully working inside of 5hr session onsite at the hackathon. I am now extremely biased towards EaselJS as when pressed for time, this library was predictable and easy to get things pixel perfect. I even had time to spare on this element and decided to add layouts for device orientation to the signature panel. Canvas also pairs really well with FormData in JavaScript as I was able to snap images of the signature panel and iterate over the stored data and upload via XHR. Here is a snippet:

var formData = new FormData();
 var len = ziply.imageData.length;
 formData.append( "signature_length" , len );
 for ( var i=0 ; i<len ; i++ ){ 
 formData.append( "s_" + i , ziply.imageData[i] );
 }
 var xhr = new XMLHttpRequest();

When it was all said and done, the big discovery in writing zip.ly is the HTML/Markdown/Images to PDF developer workflow. It allowed me to manipulate the PDF generation late in development and template it for end users all while generating PDF rapidly server-side. Our team will be investing more to make zip.ly both a Heroku Add-on and a small business centric native app for document signing on the go. This feels like the right pivot to make in the wake of this 3 week development sprint but we will see what time does to that decision.

I had a great time participating in the SalesForce $1M Hackathon and I walked away having learned a ton and met some great people. I would encourage you to take a risk and build something outside your comfort zone, and see what happens. You will learn a ton and you will be surprised by the results.

Cheers,

Ted :)

RFC 6455 – Websocket


I have been exploring Websocket RFC 6455 recently and wanted to share my thoughts on this HTML5 addition to web technologies. Websocket provides an API and HTTP upgrade mechanism to take a standard HTTP request and upgrade it to a bi-directional socket connection. The standard includes a simple JavaScript API to instantiate a new socket and listen for events connect, close, message while being able to send messages programmatically.

Port 80/443 - The first barrier with any network communication is firewall traversal. Port 80(HTTP) and Port 443(HTTPS) are typically open both ways within firewalls. Although Websockets can operate on custom ports, they default operation to using port 80/443 depending on the protocol selected. The key is that HTTP has always used TCP/IP Sockets to communicate. When you make a URL GET/POST/HEAD request you make a TCP/IP socket connection to the target server and send a header. The server responds and closes the connection unless it is using HTTP1.1 which simply provides more persistant connections supporting multiple requests.

2 Way – Websockets allows the server or client to send messages at any time without requiring a request. After the initial HTTP handshake, you can send data to the server and the server can send data to the client. The key is that a request does not imply the server will respond and thus there are 2 independent channels of messages.

I tested Websocket using Play (Java) and Tornado(Python) Frameworks and found it trivial to get up and working with Websockets quickly. Both frameworks provide a simple means to defining a route to serve the Websocket handshake and provide events for events. Given the symmetry within the Websocket, both client and server are very similar in API. Here is the Websocket Class in Play and Tornado:

#Tornado Framework - Websocket Class
class EchoWebSocket( tornado.websocket.WebSocketHandler ):
  def open( self ):
    print "WebSocket opened"

  def on_message( self , message ):
    print "You said: " + message
    self.write_message( message )

  def on_close( self ):
    print "WebSocket closed"
//Play Framework - Websocket Controller
public class Application extends Controller {
  public static WebSocket<String> live() {
    return new WebSocket<String>() {
      public void onReady(final WebSocket.In<String> in, final WebSocket.Out<String> out){
        in.onMessage(new Callback<String>() {
          public void invoke(String event) {
            out.write("onmessage:" + event);
          } 
        });

        in.onClose(new Callback0() {
          public void invoke() {
            Logger.info("onclose");
          }
        });
        out.write("Connected");
      }
    }
  }
}

Compatibility – Today the Websocket API is deployed in the following browsers: IE10+, FF14+, Chrome 21+, Safari 6+, Opera 12, IOS 6+, Chrome Android 4+, and BB7+. With proper fallback to Flash Player on desktop browsers, this provides a very solid base of support.

JavaScript API – The JavaScript API is fairly simple to use. You simply create a new instance of WebSocket and pass in a ws:// or wss:// uri to the target server. Here is an sample:

socket = new WebSocket( "ws://example.com/live" );
socket.onopen = function( event ) { onOpen( event ) };
socket.onclose = function( event ) { onClose( event ) }; 
socket.onmessage = function( event ) { onMessage( event ) }; 
socket.onerror = function( event ) { onError( event ) };

There are some interesting service possibilities with Websockets allowing clients to query a services layer within a persistant socket connection. The hard part with Websockets is handling scalable server architectures where messages must traverse multiple servers between multiple clients. Although this is a very solvable problem with messaging libraries like ZeroMQ and server to server socket connections.

Try Websockets out! Here is a full Websockets server written in Tornado Framework in Python. It is a single file and should be fairly easy to run once you install the Tornado libraries into Python locally. Instructions for installation are located within the file itself.

Cheers,

Ted :)

Changes


Friday 9/28 will be my last day at Sencha and marks 20 days until the birth of my daughter. I am departing Sencha to focus on family and return to working as a consultant and entrepreneur.

I have been extremely lucky over the past 7 years to work for some amazing companies (Adobe, Barnes & Noble, Sencha) and I have learned a ton about business and large scale software development in the process. Sencha has been a great experience working inside a world class, fast growth startup at the heart of HTML5. In my short time at Sencha, we focused on enterprise, delivered major releases of every product, added 30+ people to the company, and welcomed a ton of application developers to the platform. It has been a distinct honor to work at Sencha, build a great developer relations team, and work with so many amazing developers in the community.

As an evangelist I only advocate for technologies that I believe in and my path has included Flash, Flex, Android, and Sencha. In the case of Sencha, I am giving up employment to build services using Sencha as a platform. I am not sure there is a better validation of Sencha and given the large scale use of Sencha frameworks at Adobe, SalesForce, Cisco, Concur, Morgan Stanley, and many others; I know this is a very sound decision.

Having started-up straight out of college, I have yet to see an entrepreneurial climate as good as today. With a command line, I can launch hundreds of servers, leverage a ton of revolutionary code, and work with amazing people remotely. The costs of starting-up have literally fallen an order of magnitude in the past 10 years and executing projects has never been easier. During my time at NOOK, I launched 63 apps which turned into a solid recurring revenue business. This success enabled me to leap quickly to Sencha and with upcoming family changes has evolved into my return to being a consultant and entrepreneur.

Long story short, I am an entrepreneur at heart, I love solving problems, and I love building things. This change allows me to focus on family while executing on a project that has been burning a hole in my pocket. For now… family, family, family!

Regards,

Ted :)

Which Framework? Document to Interactive to Application


Since joining Sencha, I have been constantly asked to compare Sencha’s web frameworks to others. Truth is comparing frameworks really depends on the user experience you want to deliver and the resources available to deliver that experience. There is an infinite spectrum of experiences possible between Document to Interactive to Application and there is a parallel set of frameworks, boilerplate, scripts, libraries for every type experience possible. Name a web toolset and you can place it on the Document to Interactive to Application spectrum fairly easily.

Sencha’s frameworks sit at the far right of this spectrum on the Application use case and fade in purpose towards the Interactive center. While you can use Sencha to deliver interactive pages, documents, or mobile websites, our tools are really 100% geared towards professional developers building native-like application experiences with web technology. Sencha provides an object-oriented and component-based paradigm for building web applications for desktop and mobile. Here are some features of Sencha’s frameworks to make it clear what I am talking about:

  • OOP - Inheritance, Packages, Mixins, Class loading with dependency support.
  • MVC – Integrated Model, View, Controller with route support
  • XTYPE – Declarative component composition. Create and load views easily.
  • DATA – Models, Stores, Connectors for simple typed server/service integration
  • UI – Modern UI Controls and Containers
  • Integrated – Everything is designed to work together.
  • Cross-Browser – Pixel perfect on every supported browser engine

While I would love it if everyone starting using Sencha frameworks, not every experience should use Sencha frameworks. I would strongly encourage you to learn and understand the diverse set of frameworks and options out there. I have learned a ton by trying out all the different web frameworks and understanding what types of experiences they best make. In many cases, their might be a better framework fit for the project you are building and you should explore your options. Most importantly get really specific about what type of experience you are creating:

  • Is it an application?
  • Is it interactive?
  • Is it media driven?
  • Is it a game?
  • Lots of pages without much interactivity?

Choose carefully, I keep seeing projects start with one framework only to watch the experience drive the chosen framework to its absolute limit. There is nothing worse than building on the wrong stack and having to refactor and rebuild with a framework switch. Make sure you know and understand the framework limitations and make sure the highest risk part of your experience is covered.

Now if you are building mobile or desktop applications experiences with web technology, we should chat. :)

On Tuesday 2/14, I will be presenting a webinar on Flex to Sencha which will focus on explaining the details of Sencha’s frameworks.

Cheers,

Ted :)

Thanks NOOK!


Today I resigned from B&N NOOK Apps to embark on a new journey in my career. Before I talk about the next destination, I wanted to talk openly about my time at NOOK Apps and say thanks to those who made it great.

NOOK Apps was an amazing journey and will always be a highlight of my career. The opportunity to build a marketplace for applications atop a new class of content centric device was big, complex, and a ton of fun. I joined a small team and we built out all the required elements to succeed from scratch in 5 months.  We launched NOOK Apps with 136 apps within an operating system update to NOOK Color. We went from 0 to millions of app installs per month and worked non-stop to make the platform better for all developers building applications. Over the past year we have helped thousands of app developers monetize great content on a new platform in a new market.

The best part of working on NOOK Apps was the team. I have worked with great teams before but never quite as good as the team on NOOK Apps. Every role was filled with a person with vast experience in the mobile space and together we made NOOK Apps a success.

Claudia, Simon, Tavares, Steven, Josh, Gideon, Cary, Titus, Eric, Ron…

Thanks, You made my time at NOOK great and we accomplished allot working together as a team.

As for next steps for me…  I will save that for tomorrow.

GO NOOK GO!

Thanks for all the fish!

Ted :)