High Performance JavaScript provides techniques for optimizing JavaScript performance. It discusses how JavaScript execution blocks the browser UI thread, preventing responsive user experiences. It recommends limiting individual JavaScript jobs to under 50ms to avoid unresponsiveness. The document then provides techniques to improve load time performance such as dynamically loading scripts, and runtime techniques like timers and web workers to avoid blocking the UI thread during long-running processes.
41. Runaway Script Timer Limits Internet Explorer: 5 million statements Firefox: 10 seconds Safari: 5 seconds Chrome: Unknown, hooks into normal crash control mechanism Opera: none
42. How Long Is Too Long? “0.1 second [100ms] is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.” - Jakob Nielsen
50. Result UI Thread Download See ya! Hello world! Parse Run time The UI thread needs to wait for the script to download, parse, and run before continuing
51. Result UI Thread Download See ya! Hello world! Parse Run Variable Constant Download time takes the longest and is variable
54. Result UI Thread JavaScript UI Update UI Update JavaScript JavaScript time The more scripts to download in between UI updates, the longer the page takes to render
61. Using Dynamic Scripts UI Thread See ya! Hello world! UI Update Run time Download Parse Only code execution happens on the UI thread, which means less blocking of UI updates
68. Deferred scripts begin to download immediately, but don't execute until all UI updates complete
69. Using <script defer> UI Thread See ya! Hello world! More UI Run More UI time Download Parse Similar to dynamic script nodes, but with a guarantee that execution will happen last
70. Timing Note:Although scripts always execute after UI updates complete, the order of multiple <script defer> scripts is not guaranteed across browsers
75. Using <script async> UI Thread See ya! Hello world! UI Update Run time Download Parse Download begins immediately and execution is slotted in at first available spot
80. //create a new timer and delay by 500ms setTimeout(function(){ //code to execute here }, 500); setTimeout() schedules a function to be added to the UI queue after a delay
81. function timedProcessArray(items, process, callback){ //create a clone of the original var todo = items.concat(); setTimeout(function(){ var start = +new Date(); do { process(todo.shift()); } while (todo.length > 0 && (+new Date() - start < 50)); if (todo.length > 0){ setTimeout(arguments.callee, 25); } else { callback(items); } }, 25); }
82. When Clicked UI Thread time UI Queue UI Update onclick UI Update
83. When Clicked UI Thread UI Update time UI Queue onclick UI Update
84. When Clicked UI Thread onclick UI Update time UI Queue UI Update
85. When Clicked UI Thread UI Update UI Update onclick time UI Queue
86. After 25ms UI Thread UI Update UI Update onclick time UI Queue JavaScript
87. After 25ms UI Thread JavaScript UI Update UI Update onclick time UI Queue
88. After Another 25ms UI Thread JavaScript UI Update UI Update onclick time UI Queue JavaScript
89. After Another 25ms UI Thread JavaScript JavaScript UI Update UI Update onclick time UI Queue
92. //delay a function until after UI updates are done setImmediate(function(){ //code to execute here }); setImmediate() adds code to the UI queue after pending UI updates are finished
106. Web Workers Asynchronous JavaScript execution Execution happens outside the UI thread Doesn’t block UI updates Data-Driven API Data is serialized going into and out of the worker No access to DOM or BOM Separate execution environment
107. //in page var worker = new Worker("process.js"); worker.onmessage = function(event){ useData(event.data); }; worker.postMessage(values); //in process.js self.onmessage = function(event){ var items = event.data; for (var i=0,len=items.length; i < len; i++){ process(items[i]); } self.postMessage(items); };
108. When Clicked UI Thread time UI Queue UI Update onclick UI Update
109. When Clicked UI Thread UI Update time UI Queue onclick UI Update
110. When Clicked UI Thread onclick UI Update time UI Queue UI Update
111. When Clicked UI Thread onclick UI Update time UI Queue Worker Thread UI Update
112. When Clicked UI Thread UI Update UI Update onclick time UI Queue Worker Thread JavaScript
120. Avoid Slow JavaScript Don't allow JavaScript to execute for more than 50ms Break up long JavaScript processes using: Timers Script Yielding (future) Web Workers
121.
122.
123. Etcetera My blog: www.nczonline.net Twitter: @slicknet These Slides: slideshare.net/nzakas Hire us: projects@stubbornella.org
Over the past couple of years, we've seen JavaScript development earn recognition as a true discipline. The idea that you should architect your code, use patterns and good programming practices has really elevated the role of the front end engineer. In my opinion, part of this elevation has been the adoption of what has traditionally been considered back end methodologies. We now focus on performance and algorithms, there's unit testing for JavaScript, and so much more. One of the areas that I've seen a much slower than adoption that I'd like is in the area of error handling.How many people have an error handling strategy for their backend? How many have dashboards that display problems with uptime and performance? How many have anything similar for the front end?Typically, the front end has been this black hole of information. You may get a few customer reports here and there, but you have no information about what's going on, how often it's occurring, or how many people have been affected.
So what have we talked about? Maintainable JavaScript is made up of four components.First is Code Conventions that describe the format of the code you’re writing.Second is Loose Coupling – keeping HTML, JavaScript, and CSS on separate layers and keeping application logic out of event handlers.Third is Programming Practices that ensure your code is readable and easily debugged.Fourth is creating a Build Process