Professional Documents
Culture Documents
OPTIMIZATIONS
There have been many optimizations in the past that focused on different elements of web browsing. Content delivery
networks (CDNs) optimize the middle mile; VM optimizations run the code faster on the server or the client, front end
optimizations (FEO) optimize the static content in the page but almost all of these optimizations are predominantly
applicable to the static, homogeneous and predictable world of desktop browsing. Your users now live in a highly dynamic,
mobile, and heterogeneous online world. Instead of wired Ethernet, we have 3G, 4G, and LTE, along with public and private
Wi-Fi. Standard desktop displays are now accompanied with high-resolution Retina and 4K HD displays all the way down to
small devices with their own high-resolution displays. The browser landscape has moved away from few slow-changing
desktop browsers to many rapidly-changing desktop and mobile browsers. More importantly, fairly static web pages are now
replaced by highly dynamic content adjusted to user context, location, device, and profile. (I realize many of you reading this
are already quite aware of this, but it helps set the stage for the points I make below.)
The current dynamism of the web has two important implications:
Standalone optimizations applied only to static content will not pay off as much.
It is too costly to both develop the content and manually optimize it for different targets and scenarios.
When it comes to optimizing content for faster delivery and rendering, three major choices stand out:
Automated Front End Optimizations run on the origin server and manipulate the structure of the page and inline,
externalize, combine, or transform resources such as CSS, JavaScript, or images. These optimizations are
particularly limited to what is statically specified in the page (for example, only applying to tags in HTML) and cannot
deal with cases where JavaScript dynamically requests and manipulates resources on the client side.
CDN optimizations run between the origin server and client browser and mainly reduce the latency of the requested
resources by caching them as close as possible to the client device. These optimizations are applied at the
granularity of individual resources and independent of how they might be used in a certain webpage or application.
They are also fairly reactive and only respond to what the client is requesting. And CDNs were developed for the
wired era and dont address new challenges with wireless networks.
Browser-side optimizations such as caching and prefetching try to identify individual resources in the page and
reduce the latency of requesting them by either reusing a previously downloaded one, or making the request sooner.
Once again, these optimizations are fairly static. Prefetching can only work on statically-referenced resources in the
page, and caching does not consider the criticality of the resource.
To apply the concept of streaming to the web page, we need to introduce the notion of timeline in the page and control the
overall process of page load according to this timeline. When loading a web page, browser, CDN, and resource origin servers
react to the requests made by the page (or application). For example, if JavaScript code requests several images, the
browser must download the JS code, execute the code, request the images, and then render them. However, it could have
utilized the network better by downloading only the part of the JS code that was needed for execution as well as the first parts
of all images that were needed for initial positioning and rendering of the images; and then while the JS is executing, it could
download the rest of the JS code and the rest of the images. Unless this is explicitly hardcoded in the application, individual
elements of the system such as browser and CDN cannot automatically and independently identify this timeline and optimize
the delivery and processing.
Static optimization approaches usually rely on patterns, such as the typical way web apps and content are created and organized.
However, the number of possible patterns in a dynamic application quickly becomes monumental and cannot be relied on for
efficient optimization. Instead of relying on patterns, our NanoVisor.js client focuses on the behavior of applications. A behavior is
in fact the result of executing a pattern. The key insight here is that many patterns exhibit the same behavior when executed in
the browser. For example, HTML offers many ways to create and configure an image element (via tag and various JavaScript
API), but all of these mechanisms at the end create an image object in the Document Object Model (DOM) of the page.
To capture and control the behavior of the application, NanoVisor.js creates a thin virtualization layer between the web app and
the browser. This virtual layer allows us to intercept all browser API calls and potentially (a) change their function, (b) postpone
them, or (c) use the result of some speculative action done in advance. This is closely analogous to what hardware virtualization
techniques such as VMWare, Hyper-V, and Xen do. While those approaches intercept OS or system calls, we intercept the
browser calls.
The NanoVisor.js virtual layer also enables us to consider a more holistic and global view rather than focusing only on point
optimizations of certain content. For example, instead of optimizing and streaming all images in a certain page, we can learn from
the behavior of that page and decide on which images in the page we should apply our streaming approach.
One of our methods is to stream the images of the page so that the page loads significantly faster and becomes interactive much
sooner. In my next blog post Ill drill deeper into the image streaming technology we have implemented on top of our NanoVisor.js
and AppSequencer client-server architecture. Stay tuned.