Reference article
The Psychology of Web Performance
Front-end performance optimization best practices
Front-end performance optimization
If you find that the first screen loading time is too long, how will you analyze and optimize it?
I usually analyze it from the perspective of "three-layer inspection + two types of optimization":
🧩Three layers of investigation
The first layer: loading layer (Network layer)
📋 Tools and practices:
Open the Network panel of your browser,
- Check whether any large-volume resources (such as main.js, vendor.js, images) are loading slowly;
- Check whether there are unloaded/duplicately loaded resources;
- See if HTTP/2, gzip or brotli compression is enabled.
📈 Optimization direction:
- Load routing components on demand (dynamic import);
- Chunking strategy (utilizing
build.rollupOptions.manualChunksofvite.config.js); - Static resource compression and caching strategy (gzip + CDN).
Second layer: Rendering layer (Performance layer)
📋 Tools and practices:
Using Chrome Performance/Lighthouse, analyze:
- Which scripts take a long time to execute;
- Which phase (parsing, script execution, rendering) takes the most time;
- Whether there is a long task (Long Task > 50ms).
📈 Optimization direction:
- Delay loading of non-first-screen logic;
- Use skeleton screen/loading animation to optimize user perception;
- Component-level cache (
keep-alive,v-memo); - Reduce unnecessary DOM updates and use computed + watch to optimize rendering logic.
The third layer: monitoring layer (real user data)
📋 Tools and practices:
- Add the performance monitoring system you mentioned (such as PFS/Web Vitals/self-built management);
- Statistics
FCP(first screen rendering time),LCP(maximum content rendering time),TTI(interactive time); - Combine logs to analyze performance under different network conditions and devices.
📈 Optimization direction:
- Layered loading for different user environments (low-end machines use simplified resources);
- Cache critical resources (Service Worker + Cache API).
💬Summary
I usually check in three steps: First, check the resource loading status in the Network panel, such as which files are large, uncompressed or loaded repeatedly; Then use Lighthouse/Performance to see the time spent in the script execution and rendering phases; Finally, bury some points in the project, such as using PFS or Web Vitals to monitor the first screen time of real users.
Optimization methods include: on-demand routing loading, packaging and sharding, static resource compression, skeleton screens to improve perceived performance, and caching of key resources. This allows for systematic analysis and optimization of above-the-fold performance.
🧩 Two types of optimization
👉 Rendering layer optimization and Code layer optimization (also known as "runtime optimization" and "build-time optimization")
The first type of optimization: Runtime/rendering layer optimization
👉 Goal: Make the "page seen by the user" render faster and interact more smoothly.
This is an optimization for the browser rendering phase (runtime). Mainly focused on "Vue component rendering logic" and "DOM update mechanism".
🎯 Common optimization directions:
| Optimization points | Description |
|---|---|
| Component optimization | Use keep-alive, v-once and v-memo (Vue 3.2+) to reduce rerendering |
| Virtual scroll | Only display the visible area when rendering a large list (such as vue-virtual-scroller) |
| Reduce watchers and dependency tracking | Avoid excessive data updates and repeated dependency triggers |
| DOM operation optimization | Merge read and write operations, use requestAnimationFrame, and avoid frequent reflows |
| Lazy loading / delayed rendering | Lazy loading of images, lazy loading of asynchronous components, sharded rendering |
| Performance Monitoring | Use Performance, Web Vitals to analyze LCP, INP, CLS indicators |
📌 Summary in one sentence:
Runtime optimization is an optimization for user experience, reducing the frequency of rendering, reflow, and redrawing, making the page smoother.
The second type of optimization: build-time/engineering layer optimization
👉 Goal: Make "code loading and building" faster and the packaging size smaller.
This is an optimization done during the project construction phase (packaging, loading), Mainly affects the first screen speed, packaging performance and resource loading efficiency.
🎯 Common optimization directions:
| Optimization points | Description |
|---|---|
| Packaging volume optimization | Tree shaking, code splitting, on-demand import (Element Plus automatic import) |
| Depends on pre-building | Vite uses esbuild to pre-build node_modules to improve cold start speed |
| Resource Compression | Enable gzip/Brotli, image compression, remove sourceMap |
| Caching and CDN | Static resource caching, browser caching, CDN acceleration |
| Lazy loading and preloading | Routing lazy loading, <link rel="prefetch"> |
| SSR / Pre-rendering | Use Nuxt or vite-ssr to improve first screen rendering speed |
📌 Summary in one sentence:
Build-time optimization is aimed at loading and building efficiency, reducing packaging time, volume and first-screen blank time.
💬Summary:
In terms of performance optimization, I will start with "three-layer inspection + two types of optimization". Three-layer troubleshooting locates problems in the three stages of construction, rendering, and loading; The two types of optimizations are runtime optimization (rendering level, such as component caching, virtual scrolling, reducing reflow) and Build-time optimization (engineering level, such as dependency pre-building, lazy loading, code splitting). This ensures that the performance of the entire link from development to launch is supported by data and actually improved.
General optimization:
Page content
- Reduce the number of HTTP requests, the number of resources, and the size of resources
- Reduce DNS queries
- avoid redirects
- Caching Ajax requests
- Lazy loading
- preload
- Lazy loading of resources
- Reduce the number of DOM elements
- Caching DOM queries
- Merge DOM insertion
- Divide content into different domain names
- Avoid 404 errors
server
- Use CDN
- Add Expires or Cache-Control response header
- Enable Gzip, brotli
- Configure Etag
- Early output buffering
- Ajax requests using the GET method
- Avoid image src being empty
Cookie
- Reduce cookie size
- Static resources use cookieless domain names
- Set the validity period reasonably, divide subdomains to reduce cookie transmission, and use different domain names for static resources and cookies.
- Use localStorage to store some static files
- sessionStorage session level can be used to transfer values between pages
- The indexDB browser stores data locally, and one file can store dozens of megabytes.
html
- Semantic HTML code is clear and conducive to search engines and team development.
- Declaring the character encoding in advance allows the browser to quickly determine how to render page content
<meta charset="utf-8"/> - Reduce html nesting and reduce the number of dom nodes
- Remove extra spaces, blank lines, comments, and useless attributes
- Minimize the use of iframe (iframe will block the onload event, and iframe can be loaded dynamically)
- Avoid using table layout, which has a large amount of code and confusing structure; the label semantics are unclear and unfriendly to search engines.A small change may cause the entire table to be rearranged.
CSS
- Put the style sheet in
<head> - Don't use CSS expressions
- Use
<link>instead of@importbecause@importuses serial loading - Don't use filter
- Reduce pseudo-class selectors, reduce the number of style layers, and reduce the use of wildcards
- Avoid legacy IE CSS script expressions such as
background-color: expression((new Date()).getHours() % 2 ? 'green': 'red'); modern calc is different and should not be avoided merely because it performs calculations - Delete blank lines, comments, reduce meaningless units, and compress CSS
- External CSS enables cache reuse; response headers determine whether revalidation is needed, and a cache hit does not eliminate parsing or style calculation
- Use media conditions to control whether styles apply, such as
<link href="xx.css" rel="stylesheet" media="screen and (min-width: 1024px)">; a nonmatching stylesheet may still download, but does not block rendering for the current media - css contain attribute isolates elements
- FOUT (Flash of Unstyled Text) waits for a period of time. If the loading is not completed, it will be displayed by default.Switch after loading.
- FOIT (Flash of Invisible Text) is displayed after the font is loaded, and the downgraded font (white screen) is displayed after the loading is completed.
- Put the style sheet in
JavaScript
- Put the script at the bottom of the page
- Use external JavaScript and CSS
- JS can block rendering and parsing, and you can use async and defer to asynchronously load files. Async means that the code will be executed immediately after downloading and the execution is out of order and will block DOM parsing when executed. Defer will be executed after the parsing is completed, and the execution is orderly.
- Minify JavaScript and CSS
- Remove duplicate scripts
- Reduce DOM operations and cache the visited DOM.Don’t operate on the real DOM every time. Apply it to the virtual DOM first and then render it to the real DOM at once.
- Use efficient event processing and use event delegation to reduce the number of bound events
- Try to use canvas animation and css animation
- Use webworker to solve program blocking problems
- Use virtual scrolling to only display content within the visible area
- Try to avoid eval, otherwise it will consume more time
- Use intersectionObserver to implement image loading
js// 只加载可视区域的图片 const observer = new IntersectionObserver(function(changes){ changes.forEach(function(element, index){ if(element.intersectionRatio > 0 ){ observer.unobserve(element.target); element.target.src = element.target.dataset.src; } }) }) function initObserver(){ const listItems = document.querySelectorAll('img'); listItems.forEach(function(item){ observer.observe(item); }); } <html> <img src="a.jpg" data-src="b.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="c.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="c.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="f.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="e.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="g.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="h.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="i.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="j.jpg" style="width:200px; height:300px;"> <img src="a.jpg" data-src="k.jpg" style="width:200px; height:300px;"> </html>- requrestAnimationFrame、requestIdleCallback
jsconst element = document.getElementById('box'); let start; function step(timestamp){ if(start === undefined){ start = timestamp; const elapsed = timestamp - start; element.style.transform = `translateX(${Math.min(0.1 * elapsed, 800)}px)`; if(elapsed < 2000){ window.requestAnimationFrame(step); } } } window.requestAnimationFrame(step);pictures
- Set alt on the img tag to improve user experience when the image fails to load.
- Optimize CSS sprites
- Don't scale images in HTML
- Use small, cacheable favicon.ico
- Add loading:lazy to the image to lazily load the image and delay acquisition of resources.
- Larger pictures can use progressive pictures, and choose continuous when storing pictures jpej in ps
- Use base64 to reduce requests
- Load images of different sizes and pixels in different environments through srcset
// Media Conditions describe properties of the viewport, not of the image. For example, (max-height: 500px) 1000px proposes to use a source of 1000px width, if the viewport is not higher than 500px.
// 资源尺寸的值被用来指定图像的预期尺寸。当 srcset 中的资源使用了宽度描述符 w 时,用户代理会使用当前图像大小来选择 srcset 中合适的一个图像 URL。被选中的尺寸影响图像的显示大小 (en-US)(如果没有影响大小的 CSS 样式被应用的话)。如果没有设置 srcset 属性,或者没有属性值,那么 sizes 属性也将不起作用。
<img src="http://img.jpj" sizes="(max-width:500px) 100px, (max-width:600px) 200px" srcset="./1.jpg 100w, 3.jpg 200w">- Mobile terminal
- Keep individual files smaller than 25 KB
- The packaged content is a multipart document
- pwa increases user experience
- web App Manifest: Add a website to your desktop for a native-like experience
- Service worker offline cache content cooperates with cache API
- Push Api & Notification API message push and reminder
- App shell & App Skelton App shell, skeleton screen.
- Analysis using lightHouse Can be optimized according to the tips in lighthouse
npm install lighthouse -g
lighthouse http://taobao.comPage content
Reduce the number of HTTP requests
80% of the response time of the web front-end is spent downloading resources such as images, styles, scripts, etc.The browser has a limit on the number of connections for each domain name. Reducing the number of requests is the key to shortening the response time.
Reduce the resources required by the page through concise design, thereby reducing HTTP requests. This is the most direct way, provided that your boss and designer colleagues do not beat you to death.So, let’s find another way:
- Merge
JavaScript,CSSand other files;- Server-side (CDN) automatic merging
- There are a lot of file merging tools based on
Node.js
- Use CSS Sprite: merge background images into one file, and control the display through background-image and background-position;
- Sprite Cow
- Spritebox
Gradually replaced by Icon Font and SVG Sprite.
- Image Map: Merge images and then use coordinates to map different areas (demo).
Disadvantages: Only works with connected images; tedious and error-prone process of setting coordinates; accessibility issues.The use of this outdated technology is deprecated.
- Inline Assets: Use the Data URI scheme to embed images into HTML or CSS; or embed CSS,
JS, and images directly into HTML.It will increase the file size and may also cause browser compatibility and other performance issues (to be compiled and supplemented).
The future trend is to use inline SVG.
- Content fragmentation divides requests into different domain names.
HTTP/2 greatly reduces the overhead of multiple requests through multiplexing.Through the data framing layer, only one TCP connection needs to be established between the client and the server to send and receive multiple files at the same time. Moreover, the connection remains open (persistent) for a long period of time for reuse.
The new features of HTTP/2 mean that the above optimization practices no longer apply, but considering the client's support coverage of HTTP/2, it needs to be weighed based on actual data.
Reduce DNS queries
After the user enters the URL, the browser first queries the IP address of the server corresponding to the domain name (hostname), which generally takes 20-120 milliseconds.The browser cannot download any data from the server until the DNS query is completed.
Based on performance considerations, ISPs, LANs, operating systems, and browsers will all have corresponding DNS caching mechanisms.
- IE caches for 30 minutes, which can be set through the DnsCacheTimeout item in the registry;
- Firefox caches for 1 minute, configured through network.dnsCacheExpiration;
- (TODO: Supplement other browser cache information)
When accessing for the first time and there is no corresponding DNS cache, the more domain names there are, the longer the query time will be.Therefore, the number of domain names should be reduced as much as possible.However, based on parallel download considerations, resources are distributed to 2 domain names (no more than 4).This is a compromise to reduce DNS queries while ensuring parallel downloads.
avoid redirects
HTTP redirects are implemented via 301/302 status codes.
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/htmlAfter receiving the redirect response from the server, the client will send the request again based on the Location address in the response header.Redirects will affect the user experience, especially when redirected multiple times, the user will not be able to see any content for a period of time, and will only see the browser progress bar being refreshed.
Sometimes redirects are unavoidable, which is better than throwing a 404 at worst.Although it can also be achieved through HTML meta refresh and JavaScript, HTTP 3xx jumps are preferred to ensure that the browser's "back" function works properly (also good for SEO).
- The most wasteful redirect occurs frequently and is easily overlooked: a / should be added to the end of the URL but is not.For example, visit http://astrology.yahoo.com/astrology will be 301 redirected to http://astrology.yahoo.com/astrology/(注意末尾的 /).If using Apache, you can use Alias or mod_rewrite Or DirectorySlash solves this problem.
- Website domain name change: CNAME is combined with Alias or mod_rewrite or other similar functions of the server to achieve jump.
Caching Ajax requests
Ajax can improve user experience.But "asynchronous" does not mean "timely". Optimizing Ajax response speed and improving performance is still a topic that needs attention.
The most important optimization method is to cache the response results. For details, see Adding Expires or Cache-Control response headers.
The following rules also relate to Ajax response speed:
- Enable Gzip
- Reduce DNS queries
- Minify JavaScript and CSS
- avoid redirects
- Configure Etag
Lazy loading
What content is absolutely required when the page initially loads?Resources not listed in the answer can be lazy loaded.For example:
- Data, styles, scripts, pictures, etc. used outside the first screen;
- Content that will only be displayed when the user interacts with it.
<img id = "img1" src="preview.png" data-realsrc="abc.png">
<script type="text/javascript">
var imag1 = document.getElementById("img1");
img1.src = img1.getAttribute("data-realsrc")
</script>Websites developed following the concept of "progressive enhancement": JavaScript is used to enhance the user experience, but it can work normally without (not supported) JavaScript, and JavaScript can be loaded lazily.
delayed rendering
Place HTML beyond the first screen in non-rendered elements, such as hidden
<textarea>, or<script>tags whose type attribute is non-executable script, to reduce the number of DOM elements initially rendered and improve speed.Wait until the first screen is loaded or the user operates, then render the remaining page content.
preload
Preloading uses the browser's idle time to request resources for future use, allowing for faster response when the user visits the next page.
- Unconditional preloading: After the page is loaded (load), other resources are obtained immediately.Taking google.com as an example, a Sprite image will be downloaded immediately after the homepage is loaded. This image is not needed on the homepage, but is used on the search results page.
- Conditional preloading: Predict the user's whereabouts based on user behavior and preload relevant resources.For example, search.yahoo.com will have additional resources loaded when you start typing.
The address bar of browsers such as Chrome also has a similar mechanism.
- There is "conspiracy" pre-loading: the new version of the page is pre-loaded before the new version is launched.After the website is revised, due to caching, usage habits, etc., there will be faster and smoother feedback from the old version of the website.In order to alleviate this problem, before the new version goes online, the old version can use its free time to load some new version resources and cache them on the client in advance, so that the new version can be loaded faster after it is officially launched (what a "scheming ape" 😱).
Before promotional days such as "Double Eleven" and "Black Friday" come, you can also pre-download some relevant resources to the client (browser, app, etc.) to effectively use browser cache and local storage to reduce request pressure on the day of the event and improve user experience.
Pre-resolved DNS
For domain names starting with https, many browsers turn off pre-resolution by default.Need to join
<meta http-equiv="x-dns-prefetch-controll" content="on">
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">cache dom query
// BAD 未缓存
var i ;
for (i=0; i< document.getElementsByTagName('p').length; i++){
// todo
}
// GOOD 缓存
var pList = document.getElementsByTagName('p')
var i ;
for (i=0; i< pList.length; i++){
// todo
}Reduce the number of DOM elements
Complex pages not only download more bytes, but JavaScript DOM operations are also slower.For example, if you add an event handler, there will be a big difference in page speed between 500 elements and 5000 elements.
Consider removing unnecessary tags from the following perspectives:
- Are you still using table layout?
- Cramming in more
<div>just to deal with layout issues?Maybe there is better, more semantic markup. - For functions that can be achieved through pseudo-elements, there is no need to add additional elements, such as clearing floats. Enter the following code in the browser console to calculate how many DOM elements there are in the page:
document.getElementsByTagName('*').length;Compare well-marked websites to see what the difference is.
Why not use table layout?
- More tags increase file size;
- It is not easy to maintain and cannot adapt to responsive design;
- For performance reasons, the default table layout algorithm produces a large number of redraws (see Table Layout Algorithm).
Merge DOM insertion
var listNode = document.getElementById('list');
var frag = docuemanager.createDocumentFragment();
var x, li;
for(x=0; x< 10; x++){
li = document.createElement('li');
li.innerHTML =' list Item ' + x;
frag.appendChild(li);
}
listNode.appendChild(frag)Divide content into different domain names
Browsers generally limit parallel threads per domain (generally 6, or even less). Using different domain names can maximize download threads, but be careful to keep it within 2-4 domain names to avoid DNS query loss.
For example, dynamic content is placed on csspod.com and static resources are placed on static.csspod.com.This can also disable cookies in the static resource domain and reduce data transmission. For details, see Cookie Optimization.
For more information, refer to Maximizing Parallel Downloads in the Carpool Lane
Minimize iframe use
Using iframes allows you to embed HTML documents in pages, but there are pros and cons.
<iframe> Advantages:
- Can be used to load slower third-party resources, such as advertisements and badges;
- Can be used as a security sandbox;
- Scripts can be downloaded in parallel.
<iframe> Disadvantages:
- Expensive to load, even for empty pages;
- Block the page load event from being triggered;
After the Iframe is completely loaded, the parent page will trigger the load event.This problem can be avoided by dynamically setting the iframe src through JavaScript in Safari and Chrome.
- Lack of semantics.
Avoid 404 errors
HTTP requests are expensive, and returning invalid responses (such as 404 Not Found) is completely unnecessary, degrades the user experience, and provides no benefit.
Some websites design cool 404 pages with prompt information, which helps improve user experience, but it still wastes server resources.What's especially bad is that external scripts return 404, which not only blocks the downloading of other resources, but the browser will also try to parse the 404 page content as JavaScript, consuming more resources.
Additional Rules:
Define the character set and place it at the top of <head>.Most browsers pause page rendering until a character set definition is found.
server
For server-related optimization settings, please refer to H5BP related projects:
Nginx HTTP server boilerplate configsApache HTTP server boilerplate configsIIS Web.Config Boilerplates
Use CDN
80-90% of the website's response time is consumed in resource downloading. Reducing resource download time is the golden rule of performance optimization.
Compared with the complexity and huge investment of distributed architecture, static content distribution network (CDN) can effectively improve the loading speed with lower investment.
Add Expires or Cache-Control response header
- Static content: Set the Expires response header to a time far in the future to implement the "never expires" strategy;
- Dynamic content: Set the appropriate Cache-Control response header to let the browser make conditional requests.
The Cache-Control header is defined in the HTTP/1.1 specification and replaces the headers previously used to define response caching policies (e.g. Expires, Pragma).All current browsers support Cache-Control, so using it is enough. In view of the different caching strategies for static content and dynamic content, in practice they are generally deployed on different servers (domain names) to facilitate management.
Reference links:
HTTP Caching | Web Fundamentals - Google DevelopersH5BP - Server Configs
Enable Gzip
Gzip compression typically reduces response size by 70%, and may be as high as 90% for some files, making it more efficient than Deflate.Major web servers have corresponding modules, and most browsers support gzip decoding.Therefore, compression should be enabled for text type content such as HTML, CSS, JS, XML, JSON, etc.
Note, do not use gzip for images and PDF files.They are already compressed, and using gzip compression not only wastes CPU resources, but may also increase the file size.
For user agents that do not support Gzip, return uncompressed data by setting the Vary response header:
Vary: *Configure Etag
Etag uses file version identification to facilitate the server to determine whether the requested content has been updated. If not, it will respond with 304 to avoid re-downloading.
Of course, enabling Etag may cause other problems, and judgment needs to be made based on the specific situation.(TODO: add relevant content)
Output (flush) buffer as early as possible
When a user requests a page, the server typically takes 200 to 500 milliseconds to assemble the HTML page.During this time, the browser is idle, waiting for data.Using the flush() function in PHP, you can send part of the prepared HTML to the browser so that the browser can start obtaining resources in advance while the server is still busy processing the remaining pages.
You can consider outputting a buffer after </head>. HTML head is generally easier to generate. It is sent first so that the browser can start to obtain resources such as CSS referenced in <head>.
Example:
<!-- css, js -->
</head>
<?php flush(); ?>
<body>
<!-- content -->Choose the Ajax request method by its semantics
HTTP methods do not specify TCP segment counts. GET does not always use one packet, and POST does not always use two; segmentation depends on data size, protocol implementations, and network conditions, so it is not a basis for choosing a request method.
Choose by HTTP semantics: GET usually retrieves a resource, while POST submits content for resource-specific processing. Caching also depends on response headers and implementations.
URL length limits depend on browsers, servers, and proxies; design parameters and request bodies according to the API semantics and verify limits along the actual request path.
Avoid image src being empty
The image src attribute value is an empty string and may appear in the following two forms:
HTML:
<img src="" />JavaScript:
var img = new Image();
img.src = "";Although the src attribute is an empty string, the browser still initiates an HTTP request to the server:
- IE sends a request to the directory where the page is located;
- Safari, Chrome, and Firefox send requests to the page itself;
- Opera does nothing.
The above data is relatively old, and the current mainstream version may change.
The consequences of empty src requests cannot be underestimated:
- Cause unexpected traffic burden to the server, especially when the PV is large;
- Waste server computing resources;
- An error may occur. Of course, browsers implement this in accordance with RFC 3986 - Uniform Resource Identifiers. When an empty string appears as a URI, it is treated as a relative URI. For the specific algorithm, see Section 5.2 of the specification.
Reference links:
A similar problem exists with empty href attributes.When a user clicks on an empty link, the browser will also send an HTTP request to the server. The default behavior of empty links can be prevented through JavaScript.
Cookie
Reduce cookie size
Cookies are used for identity authentication, personalization, and many other purposes.Cookies are sent back and forth between the server and the browser via HTTP headers, and reducing the size of the cookie can reduce its impact on response speed.
- Remove unnecessary cookies;
- Try to compress cookie size as much as possible;
- Pay attention to setting the domain level of the cookie. If necessary, do not affect the sub-domain;
- Set an appropriate expiration time.
For more details refer to When the Cookie Crumbles。
HTTP/2 header compression uses "header tables" on the client and server to track and store previously sent key-value pairs. The same data is no longer sent with each request and response.
Static resources use cookieless domain names
Static resources generally do not need to use cookies. They can be placed on a cookie-less server using a second-level domain name or a specialized domain name to reduce the waste of traffic caused by cookie transmission and improve response speed.
CSS
Put the style sheet in <head>
Placing the style sheet in <head> allows the page to render progressively, present visual feedback as early as possible, and give users the feeling of fast loading.
This is especially important for pages with a lot of content. Users can view the downloaded and rendered content first instead of staring at a white screen and waiting.
If the style sheet is placed at the bottom of the page, in order to reduce redrawing, some browsers will render the page after the CSS is loaded. The user can only face a white screen, and the user experience is extremely poor.
White screen optimization can use inline css and inline js.Pre-rendering, SSR.
Don't use CSS expressions
CSS expressions can execute JavaScript in CSS. They are only supported by IE5-IE7. IE8 standards mode has been abandoned.
CSS expressions are executed more frequently than expected. They are continuously executed when the page is scrolled and the mouse is moved, causing great performance losses.
IE7 and lower browsers are gradually becoming a thing of the past, forget about it.
Use <link> instead of @import
For some versions of IE, @import behaves the same as <link> placed at the bottom of the page.So, don't use it.
Don't use filter
AlphaImageLoader is a proprietary technology of IE5.5-IE8. Like CSS expressions, it should be put in a museum.
Note:
What is mentioned here is not CSS3 Filter, refer to the article Understanding CSS Filter Effects
JavaScript
Put the script at the bottom of the page
When the browser downloads the script, it will block other resources from being downloaded in parallel, even resources from different domain names.Therefore, it is better to place the script at the bottom to increase the page loading speed.
In some special scenarios where the script cannot be placed at the bottom of the page, you can consider the following attributes of <script>:
defer will be executed after the HTML is parsed. If there are multiple, they will be executed in the order of loading.
- HTML5’s new async attribute.
async is executed immediately after loading. If there are multiple, the execution order has nothing to do with the loading order.
Use external JavaScript and CSS
External JavaScript and CSS files can be cached by the browser and reused across different pages, also reducing page size.
Of course, in practice, the degree of code reuse also needs to be considered.If the code is only used on a certain page, you can consider embedding it in the page to reduce the number of HTTP requests.In addition, you can pre-load the resources of sub-pages after the home page is loaded.
Minify JavaScript and CSS
Compressing code can remove non-functional characters (comments, spaces, blank lines, etc.), reduce file size, and increase loading speed.
Thanks to the popularity of
Node.js, many efficient and easy-to-use front-end optimization tools have emerged in the open source community. For JavaScript and CSS compression, it is not an exaggeration to say that there are too many, such as UglifyJS 2, csso, cssnano, etc.
Embedded CSS and
JavaScriptcan also be compressed through tools such as htmlmin.
All of these projects are
Gulp、WebpackCompanion versions of popular build tools.
Remove duplicate scripts
Duplicate scripts not only generate unnecessary HTTP requests, but also waste time and computing resources with repeated parsing and execution.
Reduce DOM operations
JavaScript operates DOM very slowly, especially when there are many DOM nodes.
When using it, you should pay attention to:
- Cache elements that have already been accessed;
- Use DocumentFragment to temporarily store the DOM, and then insert it into the DOM tree after sorting it;
- Manipulate className instead of reading and writing style multiple times;
- Avoid using JavaScript to fix layouts.
Use efficient event handling
- Reduce the number of nodes bound to event listening, such as through event delegation;
- Handle events as early as possible, right after DOMContentLoaded, without waiting for load.
For events with extremely high trigger frequency such as resize and scroll, the handler execution frequency should be reduced through mechanisms such as debounce.
TODO: Supplement related content http://demo.nimius.net/debounce_throttle/
pictures
Optimize images
YDN Related tools listed lacks ease of use, it is recommended to refer to the following tools.
TODO:
- PNG ultimate optimization;
- Webp related content;
- SVG related content.
PNG ultimate optimization:
Optimize CSS sprites
- Arrange the images in the sprite horizontally, and vertical arrangement will increase the image size;
- In Spirite, grouping colors that are close together can reduce the number of colors, ideally below 256 colors to accommodate the PNG8 format;
- Don't leave large gaps in the middle of Spirite's images.Although reducing gaps does not affect the file size, it can reduce the memory consumption of the user agent when decompressing the image into a pixel image, making it more friendly to mobile devices.
Serve appropriately sized images
Serve images sized for their display dimensions and device pixel ratio, avoiding unnecessarily large originals; still set <img> width and height to reserve layout space.
Many CMS and CDNs offer image cropping capabilities.
Use small, cacheable favicon.ico
Favicon.ico is generally stored in the root directory of the website. Regardless of whether it is set in the page, the browser will try to request this file.
So make sure this icon:
- exists (avoids 404);
- Keep it as small as possible, preferably less than 1K;
- Set a longer expiration time.
- For newer browsers, you can use the favicon in PNG format.
Reference links:
Picture related supplements
Set image dimensions or an aspect ratio to reserve space and reduce layout shifts after loading; this primarily improves layout stability rather than merely avoiding repaints.
Mobile terminal
Content related to mobile terminal optimization needs to be further compiled and supplemented.