Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

The introduction

What are Sprite, pixel and vector graphics?

  • Sprite: A Sprite is a Sprite that combines a large number of images into a single image so that you only need one image to request. Page if you need to use, just need to locate to the corresponding image position on the line. The number of HTTP requests can be greatly reduced to optimize performance.
  • Pixel image: An image drawn in pixels, enlarged and distorted (blurred)
  • Vector: Does not blur when zoomed in

Img tag events:

  1. Onerror: Triggered when the image fails to load
  2. Onload: Triggered after the image is loaded
  1. Onabort: Triggered when image loading is canceled

A lazy image loading implementation:

In fact, it is very simple, nothing more than to slide the window to pull new data or images, namely:

  1. The drop-down window => Scroll event
  2. Request data => Ajax request

Effect preview:

1. Html and Css code

There’s nothing to say about HTML and CSS code, it’s all the same.

<style> *{ margin: 0px; padding:0px; } .img{ height: 1000px; padding: 10px; }.img ul{/* flex */ display: flex; /* Flex is evenly distributed, and child elements are the same distance */ justify-content: space-between; /* flex-wrap: wrap; /* align-content:flex-start; } .img ul li{ list-style: none; } .img ul li img{ width: 100px; height: 150px; display: inline-block; } < / style > < div class = "img" > < ul > / * * / picture < / ul > < / div >Copy the code

2. Implement drop-down events

The window.onscroll event is used to trigger the dropdown event. And then use Windows. ScrollY with window. InnerHeight and document body. ScrollHeight respectively to get the scroll bar and the top of the height, the height of the visible area, the actual height of the page.

Add a judgment if the height of the scroll bar plus the height of the visible area is greater than the actual height of the page to request a new one

The data.

Onscroll = function(){var page = 0 // 1. Let scrollTop = window.scrolly // 2. Let h = window.innerheight // 3. Page actual height let totalH = document. Body. ScrollHeight / / whether scroll bar height + visible region height is greater than or equal to actual height if page (scrollTop + h > = totalH) {/ / GetData (page++)}} getData(page++)}Copy the code

3. Data request

Native Ajax requests are used, and jSON-Server is used to simulate the background service as usual. If you haven’t, check out the following article.

For language content of finches card here, click on the links to view: www.yuque.com/go/doc/3135…

Set up db. Json file, set up 1-5 lines of analog paging data

Implementation approach

Declare a getData function to request the background, and then convert the data into a JS array and determine whether the number of pages obtained is greater than or equal to 5, that is, whether it is the last data. If so, zero and start the request again from the first page of data.

After the successful request to the data, the data to the previous page will be taken out and traversed to add to the page, and set the picture displayed when the picture fails to load. Here I’ll put the first page

The Url address of the second image is set to the wrong address to show the effect of its loading error.

Effect:

Specific code:

Var page = 0 var pageSize = 16 var STR = ""; Function getData(){const XML = new XMLHttpRequest(); Normal request the background should be / / url/pages/article number = > http://localhost:3000/img/page/pageSize XML. Open (" get ", "http://localhost:3000/img") / / transfer value, Get does not need to pass xml.send () // set the callback function, Xml.onreadystatechange = function(){if(xml.readyState == 4 &&xml.status == 200){// Convert json string to JS object let Parse (xml.responseText) // Since I only have 5 pieces of data, in order to better display the effect, If (page >= 5){page = 0} // fetch data; Because JSON-server does not emulate paging data, Data = data[page][page+1] // forEach((v, v, v, v) K) = > {/ / loading animation path.. / img/loding. GIF STR + = ` < li > < img class = "imgError" SRC = "${v.u rl}" width = "100" height = "150" > < / li > `}) // Insert data into the document document.querySelector(".img ul").innerhtml = STR Document. QuerySelectorAll (" imgError ") / / to each label traversal img. ForEach ((v, K) => {// Set the default image to display when the image fails to load './img/52309309923771554251581445296815.jpg' } }) } } }Copy the code

Effect display:


Two, image preloading:

Image preloading is actually much easier, much less code than lazy loading. It’s easy to understand how this works: you add the default image to the IMG tag (loading animated GIFs), then initialize the image and add the actual image that will be displayed to the IMG tag.

1. Use Css to complete simple image preloading

Loading the img DOM element with loading. Loading. GIF is the background image of the img element. Then add the image Url to the img SRC attribute.

.img ul li img{ width: 100px; height: 150px; display: inline-block; /* Background-image: url('./img/loding.gif'); background-size: 107px 150px; }Copy the code

Effect :(loading relatively fast, the effect is not very obvious, I slowed down the GIF to show the effect) column 1, row 3

2. Use JS

Effect preview:

1. The HTML code

The default path to load the animation is fine

<body>
    <img id="img1" src="./img//loding.gif" width="100" height="150" />
    <img id="img2" src="./img//loding.gif" width="100" height="150" />
    <img id="img3" src="./img//loding.gif" width="100" height="150" />
    <img id="img4" src="./img//loding.gif" width="100" height="150" />
    <img id="img5" src="./img//loding.gif" width="100" height="150" />
</body>
Copy the code

2. Preloading implementation

The principle is very simple: declare an IMG object for the browser to cache the image, and then put the correct image Url into the IMG object and insert it into the page according to the tag ID.

Function Imagess(Url, Img = new Image() const img = new Image() const img = new Image() const img = new Image() SetTimeout (() => {document.getelementById (imgId).src = img.src}, 2000) / / picture loaded failure shows the default picture img. The onerror = function () {/ / set the default picture img. The SRC = ".. / img / 52309309923771554251581445296815 JPG" Document.getelementbyid (imgId).src = img.src}, 500)}}Copy the code

3. Complete code

As with CSS background images, the img tag is rendered with an initial image, making it a transition, not a blank, until the correct image is requested and loaded.

U1s1, however, I find it easier to use CSS background images directly. You don’t have to write so much JS code, and you have to have the default IMG tag in the page.

You might want to combine this preloaded JS code with the lazy loading js code to create a set of preloaded and lazy loaded JS code that dynamically adds img tags instead of the default IMG tags. But I thought about that, but I didn’t think it was worth it, because when you add it up, I thought it was too much code. And more code is executed, which means less performance. It is better to preload images by adding CSS background images directly.

<img id="img1" SRC ="./img//loding.gif" width="100" height="150" /> <img id="img2" src="./img//loding.gif" width="100" height="150" /> <img id="img3" src="./img//loding.gif" width="100" height="150" /> <img id="img4" src="./img//loding.gif" width="100" height="150" /> <img id="img5" src="./img//loding.gif" width="100" Height ="150" /> </body> Img = new Image() const img = new Image() const img = new Image() const img = new Image() SetTimeout (() => {document.getelementById (imgId).src = img.src}, 2000) / / picture loaded failure shows the default picture img. The onerror = function () {/ / set the default picture img. The SRC = ".. / img / 52309309923771554251581445296815 JPG" SetTimeout (() => {document.getelementById (imgId).src = img.src}, 500)}} Window.onload = function () {// Correct path: http://hiphotos.baidu.com/lovebyakuya/pic/item/01cf20088f9506f063d98653.jpg Imagess (address / / pictures "http://hiphotos.badu.com/lovebyakuya/pic/item/01cf20088f9506f063d98653.jpg", / / picture id "img1") Imagess (" http://hiphotos.badu.com/lovebyakuya/pic/item/7b7b19c70d62f4fdd0006050.jpg ", "img2") Imagess("http://hiphotos.badu.com/lovebyakuya/pic/item/7b7b19c70d62f4fdd0006050.jpg", "Img3 ") // All the above three paths are wrong Imagess("https://img2.huashi6.com/images/resource/2020/11/19/85h761730p0.jpg?imageView2/3/q/100/interlace/1/w/1600/h/160 0/format/webp", "img4") Imagess("https://img2.huashi6.com/images/resource/2020/06/18/8240999h9p0.jpg?imageView2/3/q/100/interlace/1/w/1600/h/160 0/format/webp", "img5") } </script>Copy the code

Effect display:


Iii. Source code

  1. Image lazy loading: 📎 March 12 front end performance optimization.zip
  2. Image preloading: 📎cs.html