Meet the JavaScript AST

Posted on Apr 12, 2018

I was developing a tool to inlinify the external Web Worker references in a JavaScript file. It checks all external Web Worker references like: new Worker('worker.js') and then reads the content from worker.js, eventually transforms the external reference to inline reference like: new Worker(window.URL.createObjectURL(new Blob(["/* the code of worker.js */"]))). The function of the tool seems to be very simple, I was considering to use Regular expression to find out the value of the external Web Worker reference, however it turned out that a lot of edge cases cannot be covered by the Regular expression solution. In the end, JavaScript AST (Abstract Syntax Tree) parser became the life saver. Read all

Performance issue of using massive transferable objects in Web Worker

Posted on Jan 23, 2018

I was recently developing a text file parser based on File Reader API in browsers. To prevent the heavy file parsing job from blocking the UI thread, using Web Worker to parse the file would be the best choice. Web Worker needs to parse the text file into lines and transfer each line to the main thread. We will encounter performance issues on transfer speed and memory usage when Web Worker needs to pass hundreds of thousands, or even millions of lines. Most browsers implement the structured clone algorithm that allows you to pass more complex types in/out of Web Worker such as File, Blob, ArrayBuffer, and JSON objects. However, when passing these types of data using postMessage(), a copy is still made. Therefore, if you are passing a large 100MB file, there's a noticeable overhead in getting that file between the worker and the main thread. To solve this problem, postMessage() method was designed to support passing Transferable Objects. When passing Transferable Objects, data is transferred from one context (worker thread or main thread) to another without additional memory consumption, and the transfer speed is really quick since no copy is made. However I still see notable performance issue when Web Worker needs to pass massive Transferable Objects. Read all

Processing huge files using FileReader.readAsArrayBuffer() in web browser

Posted on Sep 05, 2017

The FileReader API in HTML5 allows web browsers to access user files without uploading the files to the web servers. It not only lightens the load of web server but also saves the time of uploading files. It is very easy to use FileReader.readAsText() to process a 300K log file. However, when the file size grows to 1GB, or even 2GB, then the page might crash in browser or not function correctly. This is because readAsText() loads the full file into memory before processing it. As a result, the process memory exceeds the limitation. To prevent this issue, we should use FileReader.readAsArrayBuffer() to stream the file when the web application needs to process huge files, so you only hold a part of the file in the memory. Read all

ES6: Arrow Functions

Posted on Feb 17, 2017

It is very common to use anonymous functions as parameters in JavaScript. Event binding, async callback and so on all use anonymous function. ES6 introduced new Arrow Functions which has shorter syntax as a replacement for anonymous function. The basic syntax is: (arguments) => {expression or return value}. Read all

JavaScript ES5: the Object.defineProperty() method

Posted on Feb 09, 2017

We can use the form: to get and set the value of an object: var obj = {a:1} in JavaScript. This is the most common and convenient way we code in JS, however the property that is created in this way can be easily modified and is enumerable. The Object.defineProperty() allows precise addition to or modification of a property on an object. It has been widely used in some popular two-way binding JS libraries. Read all

A new way to declare variables in JavaScript with "let"

Posted on Aug 08, 2015

ECMAScript 2015 (ES6) provides a stricter way to declare variables: let which can be used to supersede legacy var statement. The let statement declares a block scope local variable while the variables declared with var are scoped to the function block level. Although it is very loose and comfortable to declare variables with var, but this characteristic usually leads to some unexpected behaviors, especially in a complicated project. Read all

How to develop high performance onScroll event?

Posted on Jun 19, 2015

We need to take special care of the performance while hooking up to the onscroll event as it fires more frequently with shorter interval time comparing to other events like mouse and keyboard. The FPS drops if your onscroll event contains elaborate logic or animations. In addition, user usually scrolls the mouse wheel continuously, it may aggravate the FPS drop, increase the browser CPU usage and impact the user experience. Developers sometimes don't notice such kind of issue since most development machines have better performance than normal user machines. Next, let's talk about how to prevent the performance issue caused by onscroll event. Read all

Remove blocking JavaScript and CSS

Posted on Jun 05, 2015

External file references in web page like: JavaScript and CSS may block page rendering. They force the browser to wait for the files to be downloaded, parsed and execute. Assuming that there is a JavaScript file reference which needs 2 seconds to be loaded, then the browser will stop rendering until the JS file is loaded after 2 seconds. We need to eliminate any potential blocking external JavaScript and CSS files when optimize web page. Read all

JavaScript: What's the difference between HTML attribute and DOM property?

Posted on May 23, 2015

It is easy to confuse attribute with property when manipulating DOM object by JavaScript. document.getElementById('test').getAttribute('id'), $('#test').attr('id'), document.getElementById('test').id and $('#test').prop('id') return the same id: "test". In this article, I will explain the differences between attribute and property. Read all