Tag Archives: event

Thumbnail

How to Create and Optimize an Effective Exit Popup

exit-popup-11

What if you could boost email signups by 1,375 percent (or more)? And what if I told you that the secret to those kinds of results lies in something as simple as an exit popup? Craft blogger Nikki McGonigal used to just have an email signup form in her website’s sidebar. Then she added an exit popup. Her conversion rate increased by more than 1,300 percent. Before you dismiss her results as industry related or as an aberration, you should know that businesses in just about every industry use exit popups. How do you get results from exit popups? I’m going…

The post How to Create and Optimize an Effective Exit Popup appeared first on The Daily Egg.

Taken from – 

How to Create and Optimize an Effective Exit Popup

Thumbnail

Once Upon A Time: Using Story Structure For Better Engagement




Once Upon A Time: Using Story Structure For Better Engagement

John Rhea



Stories form the connective tissue of our lives. They’re our experiences, our memories, and our entertainment. They have rhythms and structures that keep us engaged. In this article, we’ll look at how those same rhythms and structures can help us enrich and enhance the user experience.

In his seminal work Hero With A Thousand Faces, Joseph Campbell identified a structure that rings true across a wide variety of stories. He called this “The Hero’s Journey,” but his book explaining it was 300+ pages so we’ll use a simplified version of Campbell’s work or a jazzified version of the plot structure you probably learned about in elementary school:


The Hero’s journey begins in the ordinary world. An inciting incident happens to draw the hero into the story. The hero prepares to face the ordeal/climax. The hero actually faces the ordeal. Then the hero must return to the ordinary world and finally there is resolution to the story.


Once upon a time… a hero went on a journey.

The ordinary world/exposition is where our hero/protagonist/person/thing/main character starts. It’s the every day, the safe, the boring, the life the hero already knows.

The inciting incident is the event or thing that pulls or (more often) pushes the hero into the story. It’s what gets them involved in the story whether they want to be or not.

In the rising action/preparation phase, the hero prepares (sometimes unknowingly) for the ordeal/climax which is when they go up against the villain (and prevail!).

After the hero prevails against the villain, they must return to their ordinary world and bring back the new knowledge and/or mythical object they got from/for defeating the villain.

Finally, in the Resolution, we tie up all the loose ends and throw a dance party.

We can apply this same structure to the experience of the user or — as I like to call it — the “user journey.”

  • Ordinary World
    Where the user starts (their every day).
  • Inciting Incident
    They have a problem they need solved.
  • Rising Action
    They’ve found your product/service/website and they think it might work to solve their problem, but they need to decide that this is the product/service/website will solve their problem. So in this step they gather facts and figures and feelings to determine if this thing will work. It could be deciding if the type of video game news covered on this site is the kind of news they want to consume or deciding whether this type of pen will solve their writing needs or whether the graphic design prowess of this agency can make their new website super awesome.
  • The Ordeal
    The fight to make a decision about purchasing that pen or adding that news site to your regularly checked sites or contacting that agency for a quote.
  • The Road Back
    Decision made, the road back is about moving forward with that purchase, regular reading, or requesting the quote.
  • Resolution
    Where they apply your product/service/website to their problem and it is mightily solved.

If we consider this structure as we look at user interactions, there are lots of ways we can put ourselves in the user’s shoes and optimize their experience, providing support (and sometimes a good shove) exactly when they need it.

Here are some techniques. Some apply to just one part of the User Journey while some apply to several parts at once:

Journey With Your Users

Stories take time. Movies aren’t done in two minutes; they take two hours to watch and absorb. They are a journey.

If you always only ever shout “BUY! BUY! BUY!” you may make a few quick sales, but you won’t encourage long-term loyalty. Journey with your users, and they’ll count on you when they have a problem you can solve.

InVision’s newsletter journeys with you. In this recent newsletter, they sent an article about Questlove and what we can learn from him concerning creativity. If you click through, other than the URL, the word “InVision” does not appear on the page. They’re not pushing the sale, but providing relevant, interesting content to the main audience of people who use their products. I haven’t yet been in the market for their services, but if/when I am, there won’t be much of an Ordeal or fight for approval. They’ve proven their worth as a traveling companion. They’re someone I can count on.


InVision provides great, usable content that addresses customer interests and needs without shoving their products in your face.


InVision is on a quest to have you love them.

Journeying with your users can take many forms, only one of which is content marketing. You could also build training programs that help them move from beginner to expert in using your app or site. You could add high touch parts to your sales process or specific technical support that will help you come alongside your user and their needs. In contexts of quick visits to a website you might use visuals or wording that’s down-to-earth, warm, welcoming, and feels personable to your main audience. You want to show the user they can count on you when they have a problem.

Give ‘Em A Shove

Users need an inciting incident to push them into the user journey, often more than one push. They have a lot going on in their lives. Maybe they’re working on a big project or are on vacation or their kid played frisbee with their laptop. They may have lost or never opened your first email. So don’t hesitate to send them a follow-up. Show them the difference between life without your product or service and life with it. Heroes are pushed into a story because their old life, their ordinary world, is no longer tenable given the knowledge or circumstances they now have.

Nick Stephenson helps authors sell more books (and uses the hero’s journey to think through his websites and marketing). Last fall he sent out a friendly reminder about a webinar he was doing. He gets straight to the point reminding us about his webinar, but provides value by giving us a way to ask questions and voice concerns. He also lets us know that this is a limited time offer, if we want the new life his webinar can bring we’ve got to step into the story before it’s too late.


Nick Stephenson follows up with content and value to help his audience not miss out on opportunities.


Didn’t want you to miss out if your cat barfed on your keyboard and deleted my last email.

Give your users more than one opportunity to buy your product. That doesn’t mean shove it down their throat every chance you get, but follow up and follow through will do wonders for your bottom line and help you continue to build trust. Many heroes need a push to get them into the story. Your users may need a shove or well-placed follow up email or blaring call to action too.

Give Out Magic Swords

By now you know your users will face an ordeal. So why not pass out magic swords, tools that will help them slay the ordeal easily?

Whenever I have tried to use Amazon’s Web Services, I’ve always been overwhelmed by the choices and the number of steps needed to get something to work. A one button solution it is not.

But on their homepage, they hand me a magic sword to help me slay my dragon of fear.


AWS touts how easy it is to get up and running.


The horror-stories-of-hard are false. You can do this.

They use a 1-2-3 graphic to emphasize ease. With the gradient, they also subtly show the change from where you started (1) to where you’ll end (3) just like what a character does in a story. My discussion above could make this ring hollow, but I believe they do two things that prevent that.

First, number two offers lots of 10-minute tutorials for “multiple use cases” There seems to be meat there, not a fluffy tutorial that won’t apply to your situation. Ten minutes isn’t long, but can show something substantially and “multiple use cases” hints that one of these may well apply to your situation.

Second, number three is not “You’ll be done.” It’s “Start building with AWS.” You’ll be up and running in as easy as 1, 2, 3. At step 3 you’ll be ready to bring your awesome to their platform. The building is what I know and can pwn. Get me past the crazy setup and I’m good.

Find out what your user’s ordeal is. Is it that a competitor has a lower price? Or they’re scared of the time and expertise it’ll take to get your solution to work? Whatever it is, develop resources that will help them say Yes to you. If the price is a factor, provide information on the value they get or how you take care of all the work or show them it will cost them more, in the long run, to go with a different solution.

No One is Average

So many stories are about someone specific because we can identify with them. Ever sat through a movie with a bland, “everyman” character? Not if you could help it and definitely not a second time. If you sell to the average person, you’ll be selling to no one. No one believes themselves to be average.

Coke’s recent “Share a Coke” campaign used this brilliantly. First, they printed a wide variety of names on their products. This could have backfired.


For Coke’s Share a Coke campaign they printed the names of many different people on their bottles.


You got friends? We got their name on our product. Buy it or be a terrible friend. Your choice. (Photo by Mike Mozart from Funny YouTube, USA)

My name isn’t Natasha, Sandy or Maurice. But it wasn’t “Buy a Coke,” it was “Share a Coke.” And I know a Natasha, a Sandy, and a Maurice. I could buy it for those friends for the novelty of it or buy my name if I found it ( “John” is so uncommon in the U.S. it’s hard to find anything that has my name on it besides unidentified men and commodes.)

So often we target an average user to broaden the appeal for a product/service/website, and to an extent, this is a good thing, but when we get overly broad, we risk interesting no one.

You Ain’t The Protagonist

You are not the protagonist of your website. You are a guide, a map, a directional sign. You are Obi-Wan Kenobi on Luke’s journey to understand the force. That’s because the story of your product is not your story, this isn’t the Clone Wars (I disavow Episodes I-III), it’s your user’s story, it’s A New Hope. Your users are the ones who should take the journey. First, they had a big hairy problem. They found your product or service that solved that big hairy problem. There was much rejoicing, but if you want them to buy you aren’t the hero that saves the day, you’re the teacher who enables them to save their day. (I am indebted to Donald Miller and his excellent “Story Brand” podcast for driving this point home for me.)

Zaxby’s focuses on how they’ll help you with messages like “Cure your craving” and “Bring some FLAVOR to your next Event!” The emphasis on “flavor” and “your” is borne out in the design and helps to communicate what they do and how they will help you solve your problem. But “you”, the user, is the hero, because you’re the one bringing it to the event. You will get the high fives from colleagues for bringing the flavor. Zaxby’s helps you get that victory.


Zaxby’s focuses all of their language on how their chicken helps you.


With Zaxby’s chicken YOU’re unstoppable.

Furthermore, we’re all self-centered, some more than others, and frankly, users don’t care about you unless it helps them. They only care about the awards you’ve won if it helps them get the best product or service they can. They are not independently happy for you.

At a recent marketers event I attended, the social media managers for a hospital said one of their most shared articles was a piece about the number of their doctors who were considered the top doctors in the region by an independent ranking. People rarely shared the hospital’s successes before, but they shared this article like crazy. I believe it’s because the user could say, “I’m so great at choosing doctors. I picked one of the best in the region!” Rather than “look at the hospital” users were saying “look at me!” Whenever you can make your success their success you’ll continue your success.

Celebrate Their Win

Similar to above, their success is your success. Celebrate their success and they’ll thank you for it.

Putting together any email campaign is arduous. There are a thousand things to do and it takes time and effort to get them right. Once I’ve completed that arduous journey, I never want to see another email again. But MailChimp turns that around. They have this tiny animation where their monkey mascot, Freddie, gives you the rock on sign. It’s short, delightful, and ignorable if you want to. And that little celebration animation energizes me to grab the giant email ball of horrors and run for the end zone yet again. Exactly what Mailchimp wants me to do.


Mailchimp celebrates your completed mail campaign with a rock on sign.


Gosh, creating that email campaign made me want to curl into the fetal position and weep, but now I almost want to make another one.

So celebrate your user’s victories as if they were your own. When they succeed at using your product or get through your tutorial or you deliver their website, throw a dance party and make them feel awesome.

The Purchase Is Not The Finish Line

The end of one story is often the beginning of another. If we get the client to buy and then drop off the face of the Earth that client won’t be back. I’ve seen this with a lot of web agencies that excel in the sales game, but when the real work of building the website happens, they pass you off to an unresponsive project manager.

Squarespace handles this transition well with a “We got you” email. You click purchase, and they send you an email detailing their 24/7 support and fast response times. You also get the smiling faces of five people who may or may not, have or still work there. And it doesn’t matter if they work there or never did. This email tells the user “We’ve got you, we understand, and we will make sure you succeed.”


Squarespace doesn’t leave you once they’ve gotten you to buy. They send you an email showing off their 24/7 support and how they’re going to make you awesome.


We’ve got your back, person-who-listened-to-a-podcast-recently and wanted to start a website.

This harkens all the way back to journeying with your user. Would you want to travel with the guy who leaves as soon as you got him past the hard part? No, stick with your users and they’ll stick with you.

The Resolution

We are storytelling animals. Story structure resonates with the rhythms of our lives. It provides a framework for looking at user experience and can help you understand their point of view at different points in the process. It also helps you tweak it such that it’s a satisfying experience for you and your users.

You got to the end of this article. Allow me to celebrate your success with a dance party.

Celebrating your conquest of this article with a gif dance party.
Let the embarrassing dancing commence!
Smashing Editorial
(cc, ra, il)


Originally posted here: 

Once Upon A Time: Using Story Structure For Better Engagement

Thumbnail

Keeping Node.js Fast: Tools, Techniques, And Tips For Making High-Performance Node.js Servers




Keeping Node.js Fast: Tools, Techniques, And Tips For Making High-Performance Node.js Servers

David Mark Clements



If you’ve been building anything with Node.js for long enough, then you’ve no doubt experienced the pain of unexpected speed issues. JavaScript is an evented, asynchronous language. That can make reasoning about performance tricky, as will become apparent. The surging popularity of Node.js has exposed the need for tooling, techniques and thinking suited to the constraints of server-side JavaScript.

When it comes to performance, what works in the browser doesn’t necessarily suit Node.js. So, how do we make sure a Node.js implementation is fast and fit for purpose? Let’s walk through a hands-on example.

Tools

Node is a very versatile platform, but one of the predominant applications is creating networked processes. We’re going to focus on profiling the most common of these: HTTP web servers.

We’ll need a tool that can blast a server with lots of requests while measuring the performance. For example, we can use AutoCannon:

npm install -g autocannon

Other good HTTP benchmarking tools include Apache Bench (ab) and wrk2, but AutoCannon is written in Node, provides similar (or sometimes greater) load pressure, and is very easy to install on Windows, Linux, and Mac OS X.

After we’ve established a baseline performance measurement, if we decide our process could be faster we’ll need some way to diagnose problems with the process. A great tool for diagnosing various performance issues is Node Clinic, which can also be installed with npm:

npm --install -g clinic

This actually installs a suite of tools. We’ll be using Clinic Doctor and Clinic Flame (a wrapper around 0x) as we go.

Note: For this hands-on example we’ll need Node 8.11.2 or higher.

The Code

Our example case is a simple REST server with a single resource: a large JSON payload exposed as a GET route at /seed/v1. The server is an app folder which consists of a package.json file (depending on restify 7.1.0), an index.js file and a util.js file.

The index.js file for our server looks like so:

'use strict'

const restify = require('restify')
const  etagger, timestamp, fetchContent  = require('./util')()
const server = restify.createServer()

server.use(etagger().bind(server))

server.get('/seed/v1', function (req, res, next) 
  fetchContent(req.url, (err, content) => 
    if (err) return next(err)
    res.send(data: content, url: req.url, ts: timestamp())
    next()
  })
})

server.listen(3000)

This server is representative of the common case of serving client-cached dynamic content. This is achieved with the etagger middleware, which calculates an ETag header for the latest state of the content.

The util.js file provides implementation pieces that would commonly be used in such a scenario, a function to fetch the relevant content from a backend, the etag middleware and a timestamp function that supplies timestamps on a minute-by-minute basis:

'use strict'

require('events').defaultMaxListeners = Infinity
const crypto = require('crypto')

module.exports = () => 
  const content = crypto.rng(5000).toString('hex')
  const ONE_MINUTE = 60000
  var last = Date.now()

  function timestamp () 
    var now = Date.now()
    if (now — last >= ONE_MINUTE) last = now
    return last
  
  
  function etagger () 
    var cache = 
    var afterEventAttached = false
    function attachAfterEvent (server) 
      if (attachAfterEvent === true) return
      afterEventAttached = true
      server.on('after', (req, res) => 
        if (res.statusCode !== 200) return
        if (!res._body) return
        const key = crypto.createHash('sha512')
          .update(req.url)
          .digest()
          .toString('hex')
        const etag = crypto.createHash('sha512')
          .update(JSON.stringify(res._body))
          .digest()
          .toString('hex')
        if (cache[key] !== etag) cache[key] = etag
      )
    }
    return function (req, res, next) 
      attachAfterEvent(this)
      const key = crypto.createHash('sha512')
        .update(req.url)
        .digest()
        .toString('hex')
      if (key in cache) res.set('Etag', cache[key])
      res.set('Cache-Control', 'public, max-age=120')
      next()
    
  }

  function fetchContent (url, cb) 
    setImmediate(() => 
      if (url !== '/seed/v1') cb(Object.assign(Error('Not Found'), statusCode: 404))
      else cb(null, content)
    })
  }

  return  timestamp, etagger, fetchContent 
  
}

By no means take this code as an example of best practices! There are multiple code smells in this file, but we’ll locate them as we measure and profile the application.

To get the full source for our starting point, the slow server can be found over here.

Profiling

In order to profile, we need two terminals, one for starting the application, and the other for load testing it.

In one terminal, within the app, folder we can run:

node index.js

In another terminal we can profile it like so:

autocannon -c100 localhost:3000/seed/v1

This will open 100 concurrent connections and bombard the server with requests for ten seconds.

The results should be something similar to the following (Running 10s test @ http://localhost:3000/seed/v1 — 100 connections):

Stat Avg Stdev Max
Latency (ms) 3086.81 1725.2 5554
Req/Sec 23.1 19.18 65
Bytes/Sec 237.98 kB 197.7 kB 688.13 kB

231 requests in 10s, 2.4 MB read

Results will vary depending on the machine. However, considering that a “Hello World” Node.js server is easily capable of thirty thousand requests per second on that machine that produced these results, 23 requests per second with an average latency exceeding 3 seconds is dismal.

Diagnosing

Discovering The Problem Area

We can diagnose the application with a single command, thanks to Clinic Doctor’s –on-port command. Within the app folder we run:

clinic doctor --on-port=’autocannon -c100 localhost:$PORT/seed/v1’ -- node index.js

This will create an HTML file that will automatically open in our browser when profiling is complete.

The results should look something like the following:


Clinic Doctor has detected an Event Loop issue


Clinic Doctor results

The Doctor is telling us that we have probably had an Event Loop issue.

Along with the message near the top of the UI, we can also see that the Event Loop chart is red, and shows a constantly increasing delay. Before we dig deeper into what this means, let’s first understand the effect the diagnosed issue is having on the other metrics.

We can see the CPU is consistently at or above 100% as the process works hard to process queued requests. Node’s JavaScript engine (V8) actually uses two CPU cores. One for the Event Loop and the other for Garbage Collection. When we see the CPU spiking up to 120% in some cases, the process is collecting objects related to handled requests.

We see this correlated in the Memory graph. The solid line in the Memory chart is the Heap Used metric. Any time there’s a spike in CPU we see a fall in the Heap Used line, showing that memory is being deallocated.

Active Handles are unaffected by the Event Loop delay. An active handle is an object that represents either I/O (such as a socket or file handle) or a timer (such as a setInterval). We instructed AutoCannon to open 100 connections (-c100). Active handles stay a consistent count of 103. The other three are handles for STDOUT, STDERR, and the handle for the server itself.

If we click the Recommendations panel at the bottom of the screen, we should see something like the following:


Clinic Doctor recommendations panel opened


Viewing issue specific recommendations

Short-Term Mitigation

Root cause analysis of serious performance issues can take time. In the case of a live deployed project, it’s worth adding overload protection to servers or services. The idea of overload protection is to monitor event loop delay (among other things), and respond with “503 Service Unavailable” if a threshold is passed. This allows a load balancer to fail over to other instances, or in the worst case means users will have to refresh. The overload-protection module can provide this with minimum overhead for Express, Koa, and Restify. The Hapi framework has a load configuration setting which provides the same protection.

Understanding The Problem Area

As the short explanation in Clinic Doctor explains, if the Event Loop is delayed to the level that we’re observing it’s very likely that one or more functions are “blocking” the Event Loop.

It’s especially important with Node.js to recognize this primary JavaScript characteristic: asynchronous events cannot occur until currently executing code has completed.

This is why a setTimeout cannot be precise.

For instance, try running the following in a browser’s DevTools or the Node REPL:

console.time('timeout')
setTimeout(console.timeEnd, 100, 'timeout')
let n = 1e7
while (n--) Math.random()

The resulting time measurement will never be 100ms. It will likely be in the range of 150ms to 250ms. The setTimeout scheduled an asynchronous operation (console.timeEnd), but the currently executing code has not yet complete; there are two more lines. The currently executing code is known as the current “tick.” For the tick to complete, Math.random has to be called ten million times. If this takes 100ms, then the total time before the timeout resolves will be 200ms (plus however long it takes the setTimeout function to actually queue the timeout beforehand, usually a couple of milliseconds).

In a server-side context, if an operation in the current tick is taking a long time to complete requests cannot be handled, and data fetching cannot occur because asynchronous code will not be executed until the current tick has completed. This means that computationally expensive code will slow down all interactions with the server. So it’s recommended to split out resource intense work into separate processes and call them from the main server, this will avoid cases where on rarely used but expensive route slows down the performance of other frequently used but inexpensive routes.

The example server has some code that is blocking the Event Loop, so the next step is to locate that code.

Analyzing

One way to quickly identify poorly performing code is to create and analyze a flame graph. A flame graph represents function calls as blocks sitting on top of each other — not over time but in aggregate. The reason it’s called a ‘flame graph’ is because it typically uses an orange to red color scheme, where the redder a block is the “hotter” a function is, meaning, the more it’s likely to be blocking the event loop. Capturing data for a flame graph is conducted through sampling the CPU — meaning that a snapshot of the function that is currently being executed and it’s stack is taken. The heat is determined by the percentage of time during profiling that a given function is at the top of the stack (e.g. the function currently being executed) for each sample. If it’s not the last function to ever be called within that stack, then it’s likely to be blocking the event loop.

Let’s use clinic flame to generate a flame graph of the example application:

clinic flame --on-port=’autocannon -c100 localhost:$PORT/seed/v1’ -- node index.js

The result should open in our browser with something like the following:


Clinic’s flame graph shows that server.on is the bottleneck


Clinic’s flame graph visualization

The width of a block represents how much time it spent on CPU overall. Three main stacks can be observed taking up the most time, all of them highlighting server.on as the hottest function. In truth, all three stacks are the same. They diverge because during profiling optimized and unoptimized functions are treated as separate call frames. Functions prefixed with a * are optimized by the JavaScript engine, and those prefixed with a ~ are unoptimized. If the optimized state isn’t important to us, we can simplify the graph further by pressing the Merge button. This should lead to view similar to the following:


Merged flame graph


Merging the flame graph

From the outset, we can infer that the offending code is in the util.js file of the application code.

The slow function is also an event handler: the functions leading up to the function are part of the core events module, and server.on is a fallback name for an anonymous function provided as an event handling function. We can also see that this code isn’t in the same tick as code that actually handles the request. If there were functions in the core, http, net, and stream would be in the stack.

Such core functions can be found by expanding other, much smaller, parts of the flame graph. For instance, try using the search input on the top right of the UI to search for send (the name of both restify and http internal methods). It should be on the right of the graph (functions are alphabetically sorted):


Flame graph has two small blocks highlighted which represent HTTP processing function


Searching the flame graph for HTTP processing functions

Notice how comparatively small all the actual HTTP handling blocks are.

We can click one of the blocks highlighted in cyan which will expand to show functions like writeHead and write in the http_outgoing.js file (part of Node core http library):


Flame graph has zoomed into a different view showing HTTP related stacks


Expanding the flame graph into HTTP relevant stacks

We can click all stacks to return to the main view.

The key point here is that even though the server.on function isn’t in the same tick as the actual request handling code, it’s still affecting the overall server performance by delaying the execution of otherwise performant code.

Debugging

We know from the flame graph that the problematic function is the event handler passed to server.on in the util.js file.

Let’s take a look:

server.on('after', (req, res) => 
  if (res.statusCode !== 200) return
  if (!res._body) return
  const key = crypto.createHash('sha512')
    .update(req.url)
    .digest()
    .toString('hex')
  const etag = crypto.createHash('sha512')
    .update(JSON.stringify(res._body))
    .digest()
    .toString('hex')
  if (cache[key] !== etag) cache[key] = etag
)

It’s well known that cryptography tends to be expensive, as does serialization (JSON.stringify) but why don’t they appear in the flame graph? These operations are in the captured samples, but they’re hidden behind the cpp filter. If we press the cpp button we should see something like the following:


Additional blocks related to C++ have been revealed in the flame graph (main view)


Revealing serialization and cryptography C++ frames

The internal V8 instructions relating to both serialization and cryptography are now shown as the hottest stacks and as taking up most of the time. The JSON.stringify method directly calls C++ code; this is why we don’t see a JavaScript function. In the cryptography case, functions like createHash and update are in the data, but they are either inlined (which means they disappear in the merged view) or too small to render.

Once we start to reason about the code in the etagger function it can quickly become apparent that it’s poorly designed. Why are we taking the server instance from the function context? There’s a lot of hashing going on, is all of that necessary? There’s also no If-None-Match header support in the implementation which would mitigate some of the load in some real-world scenarios because clients would only make a head request to determine freshness.

Let’s ignore all of these points for the moment and validate the finding that the actual work being performed in server.on is indeed the bottleneck. This can be achieved by setting the server.on code to an empty function and generating a new flamegraph.

Alter the etagger function to the following:

function etagger () 
  var cache = 
  var afterEventAttached = false
  function attachAfterEvent (server) 
    if (attachAfterEvent === true) return
    afterEventAttached = true
    server.on('after', (req, res) => )
  }
  return function (req, res, next) 
    attachAfterEvent(this)
    const key = crypto.createHash('sha512')
      .update(req.url)
      .digest()
      .toString('hex')
    if (key in cache) res.set('Etag', cache[key])
    res.set('Cache-Control', 'public, max-age=120')
    next()
  
}

The event listener function passed to server.on is now a no-op.

Let’s run clinic flame again:

clinic flame --on-port='autocannon -c100 localhost:$PORT/seed/v1' -- node index.js

This should produce a flame graph similar to the following:


Flame graph shows that Node.js event system stacks are still the bottleneck


Flame graph of the server when server.on is an empty function

This looks better, and we should have noticed an increase in request per second. But why is the event emitting code so hot? We would expect at this point for the HTTP processing code to take up the majority of CPU time, there’s nothing executing at all in the server.on event.

This type of bottleneck is caused by a function being executed more than it should be.

The following suspicious code at the top of util.js may be a clue:

require('events').defaultMaxListeners = Infinity

Let’s remove this line and start our process with the --trace-warnings flag:

node --trace-warnings index.js

If we profile with AutoCannon in another terminal, like so:

autocannon -c100 localhost:3000/seed/v1

Our process will output something similar to:

(node:96371) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 after listeners added. Use emitter.setMaxListeners() to increase limit
  at _addListener (events.js:280:19)
  at Server.addListener (events.js:297:10)
  at attachAfterEvent 
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/util.js:22:14)
  at Server.
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/util.js:25:7)
  at call
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/chain.js:164:9)
  at next
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/chain.js:120:9)
  at Chain.run
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/chain.js:123:5)
  at Server._runUse
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/server.js:976:19)
  at Server._runRoute
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/server.js:918:10)
  at Server._afterPre
    (/Users/davidclements/z/nearForm/keeping-node-fast/slow/node_modules/restify/lib/server.js:888:10)

Node is telling us that lots of events are being attached to the server object. This is strange because there’s a boolean that checks if the event has been attached and then returns early essentially making attachAfterEvent a no-op after the first event is attached.

Let’s take a look at the attachAfterEvent function:

var afterEventAttached = false
function attachAfterEvent (server) 
  if (attachAfterEvent === true) return
  afterEventAttached = true
  server.on('after', (req, res) => )
}

The conditional check is wrong! It checks whether attachAfterEvent is true instead of afterEventAttached. This means a new event is being attached to the server instance on every request, and then all prior attached events are being fired after each request. Whoops!

Optimizing

Now that we’ve discovered the problem areas, let’s see if we can make the server faster.

Low-Hanging Fruit

Let’s put the server.on listener code back (instead of an empty function) and use the correct boolean name in the conditional check. Our etagger function looks as follows:

function etagger () 
  var cache = 
  var afterEventAttached = false
  function attachAfterEvent (server) 
    if (afterEventAttached === true) return
    afterEventAttached = true
    server.on('after', (req, res) => 
      if (res.statusCode !== 200) return
      if (!res._body) return
      const key = crypto.createHash('sha512')
        .update(req.url)
        .digest()
        .toString('hex')
      const etag = crypto.createHash('sha512')
        .update(JSON.stringify(res._body))
        .digest()
        .toString('hex')
      if (cache[key] !== etag) cache[key] = etag
    )
  }
  return function (req, res, next) 
    attachAfterEvent(this)
    const key = crypto.createHash('sha512')
      .update(req.url)
      .digest()
      .toString('hex')
    if (key in cache) res.set('Etag', cache[key])
    res.set('Cache-Control', 'public, max-age=120')
    next()
  
}

Now we check our fix by profiling again. Start the server in one terminal:

node index.js

Then profile with AutoCannon:

autocannon -c100 localhost:3000/seed/v1

We should see results somewhere in the range of a 200 times improvement (Running 10s test @ http://localhost:3000/seed/v1 — 100 connections):

Stat Avg Stdev Max
Latency (ms) 19.47 4.29 103
Req/Sec 5011.11 506.2 5487
Bytes/Sec 51.8 MB 5.45 MB 58.72 MB

50k requests in 10s, 519.64 MB read

It’s important to balance potential server cost reductions with development costs. We need to define, in our own situational contexts, how far we need to go in optimizing a project. Otherwise, it can be all too easy to put 80% of the effort into 20% of the speed enhancements. Do the constraints of the project justify this?

In some scenarios, it could be appropriate to achieve a 200 times improvement with a low hanging fruit and call it a day. In others, we may want to make our implementation as fast as it can possibly be. It really depends on project priorities.

One way to control resource spend is to set a goal. For instance, 10 times improvement, or 4000 requests per second. Basing this on business needs makes the most sense. For instance, if server costs are 100% over budget, we can set a goal of 2x improvement.

Taking It Further

If we produce a new flame graph of our server, we should see something similar to the following:


Flame graph still shows server.on as the bottleneck, but a smaller bottleneck


Flame graph after the performance bug fix has been made

The event listener is still the bottleneck, it’s still taking up one-third of CPU time during profiling (the width is about one third the whole graph).

What additional gains can be made, and are the changes (along with their associated disruption) worth making?

With an optimized implementation, which is nonetheless slightly more constrained, the following performance characteristics can be achieved (Running 10s test @ http://localhost:3000/seed/v1 — 10 connections):

Stat Avg Stdev Max
Latency (ms) 0.64 0.86 17
Req/Sec 8330.91 757.63 8991
Bytes/Sec 84.17 MB 7.64 MB 92.27 MB

92k requests in 11s, 937.22 MB read

While a 1.6x improvement is significant, it arguable depends on the situation whether the effort, changes, and code disruption necessary to create this improvement are justified. Especially when compared to the 200x improvement on the original implementation with a single bug fix.

To achieve this improvement, the same iterative technique of profile, generate flamegraph, analyze, debug, and optimize was used to arrive at the final optimized server, the code for which can be found here.

The final changes to reach 8000 req/s were:

These changes are slightly more involved, a little more disruptive to the code base, and leave the etagger middleware a little less flexible because it puts the burden on the route to provide the Etag value. But it achieves an extra 3000 requests per second on the profiling machine.

Let’s take a look at a flame graph for these final improvements:


Flame graph shows that internal code related to the net module is now the bottleneck


Healthy flame graph after all performance improvements

The hottest part of the flame graph is part of Node core, in the net module. This is ideal.

Preventing Performance Problems

To round off, here are some suggestions on ways to prevent performance issues in before they are deployed.

Using performance tools as informal checkpoints during development can filter out performance bugs before they make it into production. Making AutoCannon and Clinic (or equivalents) part of everyday development tooling is recommended.

When buying into a framework, find out what it’s policy on performance is. If the framework does not prioritize performance, then it’s important to check whether that aligns with infrastructural practices and business goals. For instance, Restify has clearly (since the release of version 7) invested in enhancing the library’s performance. However, if low cost and high speed is an absolute priority, consider Fastify which has been measured as 17% faster by a Restify contributor.

Watch out for other widely impacting library choices — especially consider logging. As developers fix issues, they may decide to add additional log output to help debug related problems in the future. If an unperformant logger is used, this can strangle performance over time after the fashion of the boiling frog fable. The pino logger is the fastest newline delimited JSON logger available for Node.js.

Finally, always remember that the Event Loop is a shared resource. A Node.js server is ultimately constrained by the slowest logic in the hottest path.

Smashing Editorial
(rb, ra, il)


Continue at source:  

Keeping Node.js Fast: Tools, Techniques, And Tips For Making High-Performance Node.js Servers

Thumbnail

Announcing Call to Action Conference 2018: A Revolution for Today’s Marketing Evolution

Webster’s Dictionary defines a ‘conference’ as, “An event at which industry professionals talk at other industry professionals who’ve stockpiled seven complimentary croissants in their bag to eat later. See also: Room temperature orange juice.”   

Whether it’s to learn some new tricks, make some new connections or drum up some new business, conferences are a necessary (and sometimes cool) part of being a marketer—but not all of them are worth your time. While your typical marketing conference has morphed from weak coffee and dry PowerPoints to free t-shirts and celebrity thought leaders, it can be tough to leave feeling like you’ve really gotten something out of the event.

We saw a need to change the conference experience. Because the experience of being a marketer has changed. 

Marketing now is harder than ever— it’s hyper-competitive, oversaturated and comprised of tired tactics that used to work. We need new solutions to old problems and actionable solutions to new problems. Especially when we’re forking out hundreds, or even thousands, of dollars on a conference ticket (money we could’ve sacrificed to the AdWords gods).

Enter Call to Action Conference.

“CTAConf has set the bar for what a marketing event should be: fun, engaging and insightful. No matter the experience level or skill set, every attendee left with a new set of philosophies and tactics to apply in their marketing practice”

Ray Silva, Strategy Lead at Apply Digital and CTAConf 2017 attendee.

Now in its fifth year (only 55 more ’til we get that diamond!), CTAConf 2018 is going to be more exciting, more targeted and more committed to your future success than ever.

Already sold on joining us? Get 10% off Early Bird tickets by using the promo code “CTAConfRevolution” at checkout.

Why this conference is different (we promise)

CTAConf merges carefully curated, usable content with…well, having a great time. It’s single track, allergic to fluff and ensures you’ll walk away with leading-edge tactics, all wrapped up in an amazing experience you’ll truly enjoy.

We’re talking hands-on workshops, a concert atmosphere, all-you-can-eat snacks and gourmet food trucks, organic networking, a genuinely friendly team and fun parties in the beautiful setting of Vancouver, B.C. (Credit to Mother Nature for that one.)

Even the sessions themselves, held in the historic and fully immersive Queen Elizabeth Theatre, will make you feel less like you’re at a “work event” and more like you’re at a Broadway show about email marketing called Don’t Spamalot. 



Most importantly, it’s designed to deliver practical know-how and future-proofing strategies from true experts covering every facet of digital marketing.

A glimpse at who’s talking and what you’ll learn

April Dunford, Wind at Your Back: Making your Market Category Work for You

April has spent her career launching innovative tech products and is a seasoned expert at getting traction in increasingly noisy markets. Prior to founding Rocket Launch Marketing, where she works with companies on market strategy and positioning, she was VP of Marketing at a series of successful high-growth startups and an executive at global companies including IBM, Nortel and Siebel Systems. She was also the top-rated speaker at last year’s CTAConf (she happens to be equal parts genius and hilarious).

In her talk, you’ll learn :

  • How to shift to a favourable market category to give your marketing programs added velocity
  • How to completely change the way customers think about your offering to remove friction in your funnel
  • The three steps for shifting market categories, from isolating your differentiators to finding your downstream customers and picking the best market current to ride
Rob Bucci, What Google Serves Up For Local Searches

Rob is the founder and CEO of STAT Search Analytics, a rank tracking and SERP analytics service for SEO experts. A developer and entrepreneur in the SEO space since 2005, Rob especially loves tackling big-data challenges in data mining and analytics.

He’ll be bringing his SEO expertise to the stage to teach us:

  • How Google interprets different levels of local intent and what searchers are seeing most often
  • How to refine your SEO keyword lists by comparing SERPs
  • How to better tailor your content to build more targeted ad campaigns that achieve better results
Hana Abaza, Product Marketing: Inside and Out

Hana is the Head of Marketing for Shopify Plus, a division of Shopify that powers some of the world’s fastest growing and most iconic brands (Rebecca Minkoff, Nestle, The New York Times and FAO Schwartz, to name a few). Prior to joining Shopify, Hana led marketing and growth in a variety of industries and has a proven track record for scaling teams, revenue and customers.

You’ll leave her talk knowing:

  • The guidelines for how and when to invest in product marketing
  • How to develop a go-to-market framework for your company
  • How to set up product marketing as a cross-functional powerhouse
Ross Simmonds, Beyond Google: How To Attract Relevant Traffic Through Diverse Channels

Ross is the founder of Foundation Marketing and creator and co-founder of content curation tool, Crate, and Hustle & Grind, an online store for entrepreneurs.

Over the last several years, he’s worked to help some of the fastest-growing startups and a variety of Fortune 500 brands succeed in their digital marketing efforts. His talk focuses on typically under-used and ignored channels as missed opportunities for quality traffic.

During his talk, you’ll learn:

  • What brands can do to spread their story beyond SEO & SEM
  • How brands can leverage communities and other networks to drive consistent traffic
  • Research and data on the importance of diverse channels
  • Examples of what happens when you embrace a more diverse content approach
Krista Seiden, Measurement for Growth

Currently a Product Manager and Analytics Evangelist for the Google Analytics team, Krista is a leader in the digital analytics industry and co-chair for the San Francisco chapter of the Digital Analytics Association. She has nearly a decade of experience in digital marketing, analytics, and product management, having led analytics and optimization at Adobe and The Apollo Group prior to joining Google.

Her talk will cover:

  • What growth marketing really is, beyond the buzzwords
  • How effective growth marketing is rooted in analytics, experimentation, and product development
  • How to strategically measure and use data for targeted growth
Cyrus Shepard, SEO Success: The One Engagement Metric to Rule Them All

Former Head of SEO and Content Development at Moz, Cyrus now runs Zyppy, a fast-growing SEO company. When he’s not consulting with companies big and small on how to improve their rankings, traffic and profits, he travels the world as a speaker, making complex SEO equations easy to understand.

This August Cyrus will take the stage to teach us:

  • How much speed and rankings matter and steps to improve the right areas
  • What “fuzzy” engagement metrics like bounce rate, time on site, pages per visit really mean and what you need to focus on
  • How to use SEO data to improve conversions
Oli Gardner, Content Marketing is Broken and Only Your M.O.M. Can Save You

Oli is not only an Unbounce co-founder, he’s an expert and international speaker on conversion optimization, data-driven design and landing pages (he claims to have seen more landing pages than anyone on the planet).

He’s often the highest-rated speaker at events around the world, including previous Call to Action Conferences. This year, he’ll be talking:

  • Data and lessons learned from his biggest ever content marketing experiment, and how those lessons have changed his approach to content
  • A context-to-content-to-conversion strategy for big content that converts, based on designing for your customer’s “aha!” moments
  • Advanced methods for creating “choose your own adventure” navigational experiences to build event-based behavioural profiles of your visitors 
  • Innovative ways to productize and market the technology you already have, with use cases your customers had never considered

What’s happening off stage

Learn by doing with Unbounce workshops

Get your hands proverbially dirty with interactive workshops on A/B testing, landing page optimization, PPC, analytics and mastering Unbounce for more conversions across every type of digital campaign. A full-day event prior to the conference, the workshops are a chance to work directly with seasoned pros on solutions to real marketing problems. Workshops have been so popular in previous years they were standing room only.

Make your first (or hundredth!) landing page, popup or sticky bar with us at the workshops, and learn all the insider tips you can take home to your team.  

Eat to your stomach’s content, on us

Call to Action Conference food trucks
When we say free food, we don’t mean “Enjoy these sweaty muffins! If you want lunch, there’s a Chipotle two blocks away.” We mean constantly replenished drinks, foodie-approved snacks and a lunchtime convoy of the city’s finest food trucks delivering everything from truly tasty salads to life-changing mac ‘n’ cheese. All included.

Meet, connect and party with great people


Call to Action Conference hovers around 1,200 attendees for a refreshingly intimate experience with the buzzing energy of a big-time event. Meet fellow passionate marketers from cities all over the world, mingle with industry leaders and see just how stereotypically Canadian the friendly Unbounce crew is.

“CTAConf was amazing! My favourite part? The caliber of attendees and the energy they brought. Met so many remarkable marketers!”

—Jes Kirkwood, Head of Content Marketing at ProsperWorks and 2017 attendee.

Soak up Vancouver at the best time of year


Business and pleasure do mix! Especially in summer. CTAConf 2018 is happening August 27-29, smack dab in the middle of Vancouver’s sunshine season. Take a seawall stroll between sessions, taste-test your way through a diverse food scene, hone your craft beer palate at one of many world-renowned breweries or tack on an extra day and get outside the city to those calling mountains. We turn into human prunes waiting out months of rain for a Vancouver summer and it’s totally worth it. Come see for yourself.

Enjoy champagne hotels at boxed-wine prices


We’ve secured 40-50% discounts on rooms at the Four Seasons Hotel Vancouver, Fairmont Hotel Vancouver and Delta Hotels Vancouver Downtown Suites, exclusive to CTAConf 2018 attendees and just steps away from the conference venue. Rooms are at first come, first serve and book up fast so grab yours ASAP and prepare your senses for the fluffiest of robes.

Join the revolution

Call to Action Conference 2018 is coming up fast and early bird prices are ending soon. Get your single, group or customer ticket before May 31, 2018 and come hold us to our promise. You’ll leave feeling inspired, energized and ready for marketing victory with tactics and strategies you can put into action the very next day. In other words, you’ll really get something out of this.

Don’t forget to sweeten that Early Bird deal. Use the promo code “CTAConfRevolution” at checkout to get 10% off all ticket rates. See you in August!

P.S. If you’re joining us from the United States, you’re in luck. Ticket prices are in Canadian dollars. Your boss basically can’t say no (and if you happen to be the boss, you can take your whole team). You’re welcome, eh.

Original article: 

Announcing Call to Action Conference 2018: A Revolution for Today’s Marketing Evolution

Getting Started In Public Speaking: Global Diversity CFP Day

A CFP, or Call For Proposals (sometimes also known as a Call For Papers), is a request for speakers to send their proposed talk ideas to a conference. The conference will review the proposals and decide who to ask to speak. Popular conferences can receive hundreds of proposals for a handful of speaking slots, therefore creating a great proposal is an important skill to learn as a speaker. To help encourage people to write and submit to CFPs, Global Diversity CFP Day aims to help underrepresented people submit proposals to speak at conferences.

Source:  

Getting Started In Public Speaking: Global Diversity CFP Day

How To Make A Drag-and-Drop File Uploader With Vanilla JavaScript

It’s a known fact that file selection inputs are difficult to style the way developers want to, so many simply hide it and create a button that opens the file selection dialog instead. Nowadays, though, we have an even fancier way of handling file selection: drag and drop.
Technically, this was already possible because most (if not all) implementations of the file selection input allowed you to drag files over it to select them, but this requires you to actually show the file element.

Read this article:  

How To Make A Drag-and-Drop File Uploader With Vanilla JavaScript

Backend Java Developer – Casumo – (Malta / Barcelona / Remote (from EU zone)) – FullTime

What would be your role?
Casumo is agile so we expect you to take on a broad spectrum of tasks. Together we will work to realize our dreams and visions of how the world’s best gaming site should look and work. We are looking for developers who are driven and won’t say no to a challenge but also they have to care for what they do as we expect taking responsibility for the code written.

Continue at source: 

Backend Java Developer – Casumo – (Malta / Barcelona / Remote (from EU zone)) – FullTime

We’ve Got A Lil’ Announcement To Make: Rachel Andrew Is SmashingMag’s New Editor-In-Chief

Sometimes things evolve faster than you think. Something that started as a simple WordPress blog back in September 2006, has evolved into a little Smashing universe — with books, eBooks, conferences, workshops, consultancy, job board and, most recently, 56 fancy cats (upcoming, also known as Smashing Membership). We have a wonderful team making it all happen, but every project requires attention and focus and every project desperately needs time to evolve and flourish and improve.

View original post here:  

We’ve Got A Lil’ Announcement To Make: Rachel Andrew Is SmashingMag’s New Editor-In-Chief

In a Pinch? Here Are 4 Fast Acting Tactics to Meet Your Growth Goals Every Month

hit your goals

Want to make sure you never miss a monthly growth goal? Perhaps you need a boost right now to get the month moving in the right direction? Then, you’ve come to the right place. Big companies like Facebook and HubSpot have lofty growth goals and continue to meet them every month. But, exactly how do they do it? Planning of course. That is, planning ahead consistently to meet their goals and then planning for the occasional situation when they need to scrape together their resources and make ends meet. I call this having an ace in the hole. This is…

The post In a Pinch? Here Are 4 Fast Acting Tactics to Meet Your Growth Goals Every Month appeared first on The Daily Egg.

See original article here: 

In a Pinch? Here Are 4 Fast Acting Tactics to Meet Your Growth Goals Every Month