First Input Delay (FID) is the measurement of how long a page takes to respond to a user’s first interaction, like clicking a link or button.
First Contentful Paint (FCP) measures how long a page takes from the initial load to the first rendered content displaying on the screen.
In this article, we look at techniques that improve FID and FCP measurements.
Quickly jump to a topic:
Eliminate render-blocking resources
Leveraging browser caching
Reducing server response time
Code coverage
Minify
Lazy loading
Eliminate Render-Blocking Resources (Primarily JavaScript)
Browsers (and Google) render pages. Ideally, they should start by downloading the HTML and above-the-fold images. Then, they can format everything. That’s the CSS. Then they can do all that nifty interactive stuff.
This process is impacted when the browser is forced to load and process render-blocking resources, like JavaScript and CSS files.
JavaScript is typically a blocking resource. The browser has to stop loading and rendering other resources until the full script loads. That can take a while and create a poor user experience, which directly impacts conversion rates.
The fix is easy: Put JavaScript last so that the browser will load everything else first.
If that’s impossible or just doesn’t work, consider deferring or asynchronously loading the scripts.
<script type="text/javascript" src="/js/script.js" defer></script>
<script type="text/javascript" src="/js/script.js" async></script>
The less assets there are to download and process, the faster a browser can parse and paint and be interactive to the user.
Eliminating render-blocking resources is all about improving the critical rendering path.
It is also important to asynchronously load CSS that is not critical for above-the-fold content. That eliminates CSS as a render-blocking resource. We discuss implementing a critical CSS system in further detail in our article about improving Largest Contentful Paint (LCP).
Leveraging Browser Caching with Expires Headers
Expires headers are a web server’s way of telling a visiting browser, “This file won’t be changing for a while.” Used correctly, they reduce the number of HTTP requests required per visit, and that’s a huge performance gain and helps reduce use of the pipe.
Here’s a simple example:
- You land on eigene-homepage-erstellen.net for the first time.
- Your browser begins to request files from the site’s server: images, CSS, JavaScript, etc.
- During the request process, your browser acquires the main header logo for the site (i.e., portent_logo.png).
- Simultaneously, the server tells your browser that the logo won’t change any time soon.
- Therefore, your browser doesn’t reload the logo on future visits. Instead, it uses the version cached on your hard drive. That’s one less file to transfer.
If the server does not have expires headers defined for PNG files, your browser requests and re-loads it every time it loads a page.
A typical page on our site has 100-200 separate files or resources. Without expires headers, visiting browsers have to load each file every time they hit the site. It seems like a waste, doesn’t it?
Using expires headers, we reduce those requests by 50%.
Warning: Be sure to understand what files you need to keep relatively fresh, and set their expires headers accordingly. Think about which files do change.
NGINX expires configurations
This configuration is super-aggressive, telling NGINX to set the expiration of a huge number of file types to 1 year (31536000 seconds) from the first load date.
# Aggressive caching for static files that rarely/never change
location ~* \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|
gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|
mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|otf|pdf|png|pot|pps|
ppt|pptx|ra|ram|svg|svgz|swf|tar|t?gz|tif|tiff|ttf|wav|webm|wma|woff|
wri|xla|xls|xlsx|xlt|xlw|zip)$ {
expires 31536000s;
add_header Pragma public;
add_header Cache-Control "max-age=31536000, public";
}
This is a lot less aggressive. It tells NGINX to set the expiration data of CSS and javascript files to 24 hours (86400 seconds).
location ~* \.(css|js)$ {
expires 86400s;
add_header Pragma public;
add_header Cache-Control "max-age=86400, public";
}
Apache expires configurations
The same can be done with Apache:
<IfModule mod_mime.c>
AddType text/css .css
AddType application/x-javascript .js
AddType text/x-component .htc
AddType text/html .html .htm
AddType text/richtext .rtf .rtx
AddType image/svg+xml .svg .svgz
AddType text/plain .txt
AddType text/xsd .xsd
AddType text/xsl .xsl
AddType text/xml .xml
AddType video/asf .asf .asx .wax .wmv .wmx
AddType video/avi .avi
AddType image/bmp .bmp
AddType application/java .class
AddType video/divx .divx
AddType application/msword .doc .docx
AddType application/vnd.ms-fontobject .eot
AddType application/x-msdownload .exe
AddType image/gif .gif
AddType application/x-gzip .gz .gzip
AddType image/x-icon .ico
AddType image/jpeg .jpg .jpeg .jpe
AddType application/vnd.ms-access .mdb
AddType audio/midi .mid .midi
AddType video/quicktime .mov .qt
AddType audio/mpeg .mp3 .m4a
AddType video/mp4 .mp4 .m4v
AddType video/mpeg .mpeg .mpg .mpe
AddType application/vnd.ms-project .mpp
AddType application/x-font-otf .otf
AddType application/vnd.oasis.opendocument.database .odb
AddType application/vnd.oasis.opendocument.chart .odc
AddType application/vnd.oasis.opendocument.formula .odf
AddType application/vnd.oasis.opendocument.graphics .odg
AddType application/vnd.oasis.opendocument.presentation .odp
AddType application/vnd.oasis.opendocument.spreadsheet .ods
AddType application/vnd.oasis.opendocument.text .odt
AddType audio/ogg .ogg
AddType application/pdf .pdf
AddType image/png .png
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
AddType audio/x-realaudio .ra .ram
AddType application/x-shockwave-flash .swf
AddType application/x-tar .tar
AddType image/tiff .tif .tiff
AddType application/x-font-ttf .ttf .ttc
AddType audio/wav .wav
AddType audio/wma .wma
AddType application/vnd.ms-write .wri
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
AddType application/zip .zip
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css A86400
ExpiresByType application/x-javascript A86400
ExpiresByType text/x-component A31536000
ExpiresByType text/html A3600
ExpiresByType text/richtext A3600
ExpiresByType image/svg+xml A3600
ExpiresByType text/plain A3600
ExpiresByType text/xsd A3600
ExpiresByType text/xsl A3600
ExpiresByType text/xml A3600
ExpiresByType video/asf A31536000
ExpiresByType video/avi A31536000
ExpiresByType image/bmp A31536000
ExpiresByType application/java A31536000
ExpiresByType video/divx A31536000
ExpiresByType application/msword A31536000
ExpiresByType application/vnd.ms-fontobject A31536000
ExpiresByType application/x-msdownload A31536000
ExpiresByType image/gif A31536000
ExpiresByType application/x-gzip A31536000
ExpiresByType image/x-icon A31536000
ExpiresByType image/jpeg A31536000
ExpiresByType application/vnd.ms-access A31536000
ExpiresByType audio/midi A31536000
ExpiresByType video/quicktime A31536000
ExpiresByType audio/mpeg A31536000
ExpiresByType video/mp4 A31536000
ExpiresByType video/mpeg A31536000
ExpiresByType application/vnd.ms-project A31536000
ExpiresByType application/x-font-otf A31536000
ExpiresByType application/vnd.oasis.opendocument.database A31536000
ExpiresByType application/vnd.oasis.opendocument.chart A31536000
ExpiresByType application/vnd.oasis.opendocument.formula A31536000
ExpiresByType application/vnd.oasis.opendocument.graphics A31536000
ExpiresByType application/vnd.oasis.opendocument.presentation A31536000
ExpiresByType application/vnd.oasis.opendocument.spreadsheet A31536000
ExpiresByType application/vnd.oasis.opendocument.text A31536000
ExpiresByType audio/ogg A31536000
ExpiresByType application/pdf A31536000
ExpiresByType image/png A31536000
ExpiresByType application/vnd.ms-powerpoint A31536000
ExpiresByType audio/x-realaudio A31536000
ExpiresByType image/svg+xml A31536000
ExpiresByType application/x-shockwave-flash A31536000
ExpiresByType application/x-tar A31536000
ExpiresByType image/tiff A31536000
ExpiresByType application/x-font-ttf A31536000
ExpiresByType audio/wav A31536000
ExpiresByType audio/wma A31536000
ExpiresByType application/vnd.ms-write A31536000
ExpiresByType application/vnd.ms-excel A31536000
ExpiresByType application/zip A31536000
</IfModule>
Expires headers can be set on all major and legitimate web servers.
Reducing Server Response Time
Server response time, often known by time to first byte (TTFB), is the time it takes the web server to respond to a browser’s request, which includes the HTML, CSS, JavaScript, font files, and any other assets requested. Reducing the amount of time this takes is a fundamental principle of improving page speed. It will improve all facets of page speed, including Core Web Vitals metrics — Largest Contentful Paint (LCP), First Input Delay (FID), and First Contentful Paint (FCP).
Many improvements can enhance server response times, including page caching, enabling keep-alive, and compressing transferred data. We do a deep dive into server optimizations in our article on how to improve server response times.
Code Coverage
In terms of page speed for websites, code coverage is all of the styles (CSS) and JavaScript required for a page. In an ideal web world, the CSS and JavaScript embedded or referenced on a page would be nothing more than what is needed. Accomplishing this is very difficult, especially for larger complex sites that use a content management system (CMS) or e-commerce application. Additionally, common JavaScript and CSS frameworks like Bootstrap or Foundation introduce bloat that slows downloads and, more important, rendering time. They’re performance killers on even the speediest mobile devices.
Analyzing and reducing bloat in your CSS and JavaScript can go a long way to improving page speed scores. We go into greater detail in our article about code coverage analysis.
Minify
On the web, minify means removing any unnecessary spaces, line breaks, and tabs. It also removes comments. These may be invisible to us, but they’re still characters, and removing them makes a difference.
Here’s a version of jquery.js, un-minified. It’s 260kb:
Here it is, minified. It’s 32kb:

Minifying JavaScript, CSS, and HTML can shave a lot off a page.
Lazy loading
Usually, a browser loads every asset on the page, all at once. So, if you visit a page with lots of below-the-fold images, you download every image upon visiting that page. The typical visitor only sees the information above the red line (the fold) when they visit eigene-homepage-erstellen.net:
But the default loading behavior would deliver every image, even below the fold.
Lazy loading more efficiently uses the pipe and improves the browsing experience. Here’s how it works:
- You visit a web page
- The page loads visible, above-the-fold images first
- The page loads the remaining content only when you scroll down
It used to require some serious programming expertise to build out your own lazy loading solution. That is no longer necessary. As of 2020, all major browsers now support native lazy loading of images. By adding loading=”lazy” to image elements, browsers know to lazy load them.
Full example:
<img loading="lazy" src="https://www.eigene-homepage-erstellen.net/images/2020/11/Services_SEO-Components-01-1024x1020.png" alt="SEO is comprised of three different areas: technical SEO, on-page SEO, and off-page SEO." width="1024" height="1020" />
Conclusion
Implementing the topics discussed in this article will improve FID and FCP scores, enhance the user experience, and contribute to site conversion goals. When combined with best practices for quickening server response time, improving Largest Contentful Paint (LCP), and reducing Cumulative Layout Shift (CLS), the performance results will be enterprise level.