GeorgieP

reading and tinkering

Web Fundamentals: Critical Rendering Path

Goal: Prioritize and display the content the visitor wants to read first.

Also, making sure it bloody works! See my old hero Eric Meyer getting 'a bit antsy' about modern web sites.

Constructing the Object Model

Before the browser can render it needs to construct th DOM and CSSOM. It does it's processing in this order:
bytes-characters-tokens-nodes-object model

HTML => DOM, CSS => CSSOM

The DOM and CSSOM are independent of each other.

The DOM is the browser's representation of the HTML. The browser builds the HTML incrementally.

Render Tree Construction, Layout and Paint

DOM + CSSOM = Render Tree

The render tree only consists of items it requires, that is, it won't have items set to display:none or the head.

Layout computes exact pixel positions.

Paint is the last step.

Render Tree Construction Process:

  1. Traverse the DOM, check for visible nodes, check CSS for more nodes to be hidden.
  2. Apply CSS rules to visible nodes.
  3. Emit visible nodes (emit to the next step) NB: visiblity:hidden != display:none

The browser is now ready to being the Layout process. (painting or 'rasterizing' follows after that)

NB: Always include:

<meta name="viewport" content="width=device-width">
to get accurate widths.

Modifying the DOM or CSS will restart the whole Render Tree construction, Layout and Paint process!

Render Blocking CSS

CSS is a render blocking resource, so:

Adding Interactivity with JavaScript

Note that JavaScript can manipulate CSS style, so the browser must wait for the CSSOM model to be built before it can process any JavaScript.

Make sure to async any JavaScript where possible to prevent it being Render Blocking.

Important points about JavaScript in the CRP:

  1. The location in the file (the "when") is very important.
  2. DOM construction is paused until a script is finished.
  3. JavaScript can query and modify the DOM and CSSOM
  4. JavaScript is delayed until the CSSOM is ready.

Optimizing the Critical Rendering Path is optimizing the relationship graph of CSS, HTML and JavaScript.

Measuring the CRP with Navigation Timing

The following time stamps tell us about the timing of key events:

Analyzing CRP Performance

In the Network Profile in Chrome Dev Tools: the Blue Line = DOMContentLoaded, the Red Line = "onload" event.

Note: async JavaScript doesn't block the CRP and inlined CSS is faster.

Some CRP vocabulary:

Optimizing the CRP

  1. Minimize the number of critical resources
  2. Minimize the number of critical bytes
  3. Minimize the critical path length

General sequence of steps to optimize CRP:

  1. Analyze the critical path: number of resources, bytes, length
  2. Minimize number of critical resources: eliminate, defer download, async
  3. Optimize order - critical assets: first and early
  4. Optimize size: reduce bytes in critical resources (and reduces round-trips.

PageSpeed Rules and Recommendations

Optimizing Performance

Eliminating Unnecessary Downloads

The fastest and most optimized resource, is a resource not sent.

Optimizing Encoding and Transfer of textual assets

Data compression 101

Minification: Preprocessing & context specific optimizations

All best done as part of a build / release cycle

Text Compression with Gzip

HTML5 Boilerplate project contains sample config files for all common servers. NB: really really small files, might actually grow with GZip.

Image Optimization

Eliminating and Replacing Images

Vector Vs Raster Images

Implications of High Res Screens

HRSs have multiple device pixels per CSS pixel. High resolution images require significantly higher number of bytes per pixel. Image optimization techniques are the same regardless of resolution.

Fore high DPI, deliver multiple versions / variants of raster images (not so for vectors).

Vectors should be minified and Gzipped (svgo).

Lossy Vs Lossless Image compression

Every image will benefit differently from each different compressor, find the best one for each image.

Fomats

Tools

gifsicle, jpegtran, optipng (lossless), pngquant (lossy)

Delivering Scaled Image Assets

NB: Hovering over an image in Dev Tools will show the displayed and natural images dimensions. Resizing images takes processor time as well as showing unnecessary pixels that have shipped.

Summary for Image Optimization

  1. Prefer vectors
  2. Minify SVGs and GZip 'em too
  3. Pick the best raster format for the image
  4. Remove unnecessary meta data
  5. Serve scaled images
  6. Automate, automate, automate

Webfont Optimization

Webfont are selectable, zoomable, searchable, high DPI friendly, and can actually reduce loading times - if done correctly.

Formats:

* need to be compressed

Serve WOFF2 when possible.

Defining Font-Family with @font-face

Paste links like this into the browser to get the full CSS for inlining into a CSS file back: fonts.googleapis.com/css?family=Pacifico returns:

/* latin */
@font-face {
font-family: 'Pacifico';
font-style: normal;
font-weight: 400;
src: local('Pacifico Regular'), local('Pacifico-Regular'), url(http://fonts.gstatic.com/s/pacifico/v7/Q_Z9mv4hySLTMoMjnk_rCXYhjbSpvc47ee6xR_80Hnw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
        

Optimizing Loading and Rendering

Painting of fonts is different in browsers and can cause blank text (temporarily) or font-repaints after it has downloaded.

Font loading API

Can tell the browser to fetch and load a font before it's too late. CSS inlining in CSS stylesheets overrides lazyload. Put the fonts in separate CSS file to prevent redownloads when regular CSS gets some changes.

Optimize font reuse with HTTP Caching

Give them a long max-age expiry. Specify both: conditional ETag header, and optimal Cache-Control policy (don't use localStorage).

Webfonts Summary Checklist

  1. Audit and Monitor Font use, use few fonts and few variants.
  2. Subset font resources, Unicode ranges.
  3. Deliver optimized formats (WOFF etc) and ZIP when possible.
  4. Specify revalidation and optimal caching policies
  5. Use Font Loading API and optimize the CRP

HTTP Caching

The ability to cache and reuse previously fetched resources is critical.

Validating Cached Responses with ETags

Client sends the next requests with if-none-match: headers, if resource has not changed it responds with 304 Not Modified.

The browser and server do all this work, we just need to ensure the server is properly set up (HTML5 Boilerplate) and is in fact, providing theETag tokens.

Cache-Control

The best request doesn't go to the server, a local copy can avoid this.

"no-cache" forces the client to always check for a change first before going to the local copy, if allowed to.
"no-store" forces re-download every time (good for banking and things like that).

"Public" and "Private"

Public - can be cached

Private - intended for a single user, not allowed to be cached by an intermediate like a CDN.

"max-age"

Max time in seconds that the fetched response is allowed to be used e.g. "max-age - 60" means the response can be cached and reused for the next 60 seconds.

Ideally you should try to Cache as many responses as possible for as long as possible, and provide validation tokens for each response.

Summary

Audit your pages to identify which resources can be cached and for how long, and ensure they are returning appropriate Cache-Control and ETag headers.

Invalidating and Updating Cached Responses

We can't force an update to a cached resource without changing its URL. This is done by embedding a version number or date in the file name.

Caching Checklist

  1. Use consistent URLs to allow things to get cached
  2. Ensure server is providing valid ETags
  3. Identify which resources can be cached by intermediaries like CDNs
  4. Determine optimal cache lifetime for each resource
  5. Determine best cache hierarchy, HTML -> "no-cache", fingerprinted UTLs etc.
  6. Minimize "churn" files that get updated frequently might be delivered separately like or less frequently like CSS with @font-face definitions.

Rendering Performance

Pages should be as smooth as butter and stick to the finger like glue.

60FPS: Most devices refresh the screen 60 times per second. That is 16.66 milliseconds per frame, which should be the target. The best practice target is 10 ms.

The Pixel Pipeline

JS -> Style -> Layout -> Paint -> Composite

PERFORMANCE is the Art of Avoiding Work, and making work that you have to do efficient.

Some of the Types of recalculations that can be costly:

*best

Optimize JavaScript Execution

Badly timed or long-running JS can cause bottlenecks.

NB: The JavaScript you write looks nothing like the JavaScript that gets executed.

Scrolling Animation Target: 3-4 ms

Web Workers and task-splitting let you keep the main thread active while processing data (for example) in the background (use a spinner or progress bar to tell the user it is working).

Beware: of micro-optimizations that don't actually help a lot.

Reduce Speed and Complexity of Style Calculations

Changing the DOM by adding, removing, attributes, classes, animations, all recalculate the Render Tree with reflow etc.

50% of time is finding the element, 50% is rendering.

Avoid Large, Complex Layouts and Layout Thrashing

The 2 Biggest Concerns / Factors

FastDOM automatically batches reads and writes for layout, and prevents triggering forced synchronous layouts.

Simplify Paint Complexity And Reduce Paint Areas

Painting is often the biggest delay of all, avoid it if at all possible.

In sum: Layout -> Always triggers paint
NB: If using paint in Profile only use Paint, because it has a significant profiler performance hit.

Promote Elements to Move or Fade

Make use of the layer compositing

Using the CSS property will-change: transform; will effectively make the element a layer

For browsers like mobile Safari (mis)use a 3D transform: translate: translateZ(0);

NB: Don't create too many layers as they all require separate memory management. Beware: Don't promote elements without profiling to prove performance improvement.

Avoid paint during animations in particular, as the 10 ms you have is not usually enough, especially on mobile.

Stick to Composite-Only Properties and Manage Layer Content

NB: Also look at FLIP animation principle from Google and Udacity

Dev Tools > Profiler > Paint. Can show what layers are being used and how many.

Debounce Your Input Handlers (WTF?)

Input handlers can cause additional layout and block frames from completing.