jouni-kantola / learning-wpo

Learning material for web and rendering performance optimization.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Web Performance Optimization

Learning material for web and rendering performance optimization.

Goals

Goal 1: Optimize Test page: Janky Animation to cheaper animation

Goal 2: A measurable performance (before/after) optimization in https://github.com/jouni-kantola/grid-snake

Study material

  1. Get Started With Analyzing Runtime Performance (added: 2021-03-03)
  2. Rendering Performance (added: 2021-03-15)
  3. Test page: Janky Animation (added: 2021-03-22)
  4. How browser rendering works β€” behind the scenes (added: 2021-03-29)
  5. The Anatomy of a Frame
  6. Critical Rendering Path (added: 2021-03-29)

Reference material

Q & A

Question Answer
How should I defined performance? Art of doing less to produce equal or better results
What is a frame? Naive explanation: Single picture, in a sequence of images
What is rendering? Drawing an image to the screen
What is FPS? Non-linear metric to show how many renders are made per second
What is jank? When frame rate drops noticeably, causing content to judder on screen, because screen updates aren't done fast enough
What is good FPS? Follow device refresh rate. Normally about 16 ms (1 second / 60 frames = 16.66ms). It's really stricter because of housekeeping work the browser does, so budget is rather 10 ms
What is pixel-to-screen pipeline? The steps taken in the process of rendering updates to screen
What is rasterization? TBA
What is a render tree? TBA
What is debouncing? TBA
How do I schedule a requestAnimationFrame visual change batch (debounce)? TBA

Checklist

  1. Run runtime performance audits in incognito mode, to not be affected by browser extensions
  2. Undock DevTools to all charts in the Performance tab
  3. Simulate a slow CPU to clearly detect bottlenecks
  4. Open FPS meter and check % of frames successfully rendered
  5. Check CPU use in Performance Monitor (ctrl+shift+P: Show Performance monitor)
  6. Run audit and looks for red lines in the FPS chart. Compare below.

Bad, CPU fully occupied: image

Better, CPU idle now and then: image

  1. In Summary tab, check what process occupies main thread the most.
  2. In the Main panel, find activities with "red triangles", which signals events with issues. Zoom in on those.
  3. Dig deeper, find which specific events are causing problems. In the Summary, find which code blocks affect performance.

image

  1. Measure Style Recalculation Cost, by finding how many elements are affected by a style recalculation.

image

  1. Compare with What forces layout / reflow and CSS Triggers to find better solution.

  2. For animations or modifying DOM nodes, use tool Show paint flashing rectangles to verify only expected elements are painted.

  3. Long running tasks, where the UI thread is busy for >50 ms, can be observed with the Long Task API

const observer = new PerformanceObserver(list => {
    const entries = list.getEntries();
    console.warn("Long Task", entries);
});

observer.observe({ entryTypes: ["longtask"] });

Pixel-to-Screen pipeline

The work required for visual changes. The less work, the cheaper the process. When optimizing it's preferable to do as few steps as possible in the Pixel-to-Screen pipeline.

🐒 Change element's geometry (e.g. width): JavaScript / CSS > Style > Layout > Paint > Composite

πŸ„ Change paint only property (e.g. background): JavaScript / CSS > Style > Paint > Composite

πŸ‡ Change composite only property (e.g. transform): JavaScript / CSS > Style > Composite

JavaScript / CSS trigger visual change

Adding, removing or modifying DOM elements trigger visual change. Triggered by JavaScript, CSS animations or CSS transitions.

Style

Recalculating DOM element's styles are called computed style calculation. This is done in two steps:

  1. The browser figures out what selectors apply to a given element
  2. Take style rules for given element and assess what updated styles are

Layout

As changes to a specific element may affect others, the browser needs to consider parent and child nodes when an element's size and position is calculated. If an element's geometry is changed, the browser needs to reflow the page.

Paint

Painting, often the most expensive part of the pipeline, is the process of "filling in the pixels". Paint consists of two tasks:

  1. Create a list of draw calls
  2. Rasterization, the process of filling in/drawing visual parts of an element

Compositing

Handle order of drawing layers, so that page renders correctly. Put together painted parts for displaying on screen.

JavaScript optimization

Find the bottlenecks before optimizing; micro-optimizations do not pay off in the end!

  1. πŸ™‡ Use requestAnimationFrame (start of the frame) instead of setTimeout or setInterval (some point in the frame) for visual changes.
  2. πŸ’ Avoid forced synchronous layouts ("layout thrashing"). Batch style reads together, to reuse the previous frame's layout values. Once calculations are performed, then perform writes.
  3. 🎑 For large operations that require DOM access, batch work in separate requestAnimationFrame tasks. This may require status indicators to clearly signal a long running process. Worth noting, poor implementation of tasks results in "laggy" visuals (without clearly showing in performance debugger).
  4. 😴 Input handlers are scheduled before requestAnimationFrame (rAF). If style writes are done in input handlers and then read in rAF this causes layout trashing. To not block the compositor thread, batch changes together by debouncing to next rAF callback.
  5. πŸ‘· Move computational work to web workers to offload main thread and prevent blocking visual updates.

CSS optimization

  1. Don't focus on CSS as a bottle neck when it comes to selectors, but prefer more specific selectors to affect as few elements as possible when style calculations are applied.
  2. In animations, prefer transform (and/or opacity) to avoid both Layout and Paint.
  3. GPU acceleration via layer compositioning can be utilized to improve performance. will-change: transform or transform: translateZ(0) promotes a layer, and thereby reduces paint areas (and affects fewer elements) in animations. Use with care and profile to check the overhead doesn't actually decrease performance.

Debug tooling

  • Microsoft Edge has a 3D View to show page layers. Activate with Shift+Ctrl+P and toggle Show 3D View

image

Log

  1. 2021-03-03: Find study material
  2. 2021-03-04: Goal 1 defined
  3. 2021-03-04: Defined Q&A section
  4. 2021-03-15: Defined checklist section
  5. 2021-03-15: Cleared tutorial https://www.youtube.com/watch?v=7HSkc9TLF5U and https://developers.google.com/web/tools/chrome-devtools/evaluate-performance
  6. 2021-03-15: Defined next tutorial to go through
  7. 2021-03-22: Defined section to describe the pixel-to-screen pipeline
  8. 2021-03-22: Added section for what to think about when optimizing JavaScript
  9. 2021-03-22: Added section for CSS optimizations
  10. 2021-03-22: Updated goals to use the Test Page Demo before moving on to unkown territory
  11. 2021-03-22: Read https://developers.google.com/web/fundamentals/performance/rendering, https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution and https://developers.google.com/web/fundamentals/performance/rendering/reduce-the-scope-and-complexity-of-style-calculations
  12. 2021-03-29: Read https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing
  13. 2021-03-29: Included further study material to understand how browser rendering works
  14. 2021-04-07: Start looking for tooling in other browsers
  15. 2021-04-07: Finished Rendering Performance course
  16. 2021-04-13: Forked exercise devtools-samples/jank
  17. 2021-04-13: Put reading to practice
  18. 2021-04-19: Start looking for bottlenecks in Grid Snake
  19. 2021-04-26: Programmatically observe long running tasks

About

Learning material for web and rendering performance optimization.


Languages

Language:JavaScript 67.6%Language:HTML 18.6%Language:CSS 13.8%