Lala Code

Lala 的前端大補帖,歡迎一起鑽研前端技術😊

0%

【DAY 13】React 引入圖片檔案,圖片懶加載與預加載

cover

[情境任務]

小當家:客人點了一大桌的桌菜,真是累死我了!

解師傅:哇~這些菜看起來太美味了!看看那個醬汁!讓我拍個照先~

解師傅拍的照片真漂亮,我們把它們放在菜單上吧!


設置外部圖片

1
<img src="https://picsum.photos/200/300?random=1" alt=""/>

要放圖片其實很簡單,如果是外部的圖片,可以直接像平常 HTML 的方式 src="圖片網址" 設置



引入內部圖片檔案

如果是引入在專案中的圖片,有兩種方式

  • 使用 require 將圖檔引入
  • 使用 import 將圖檔引入


1. 使用 require 將圖檔引入

1
<img src={require('./images/logo.jpg')} alt=""/>

require 方法是 CommonJs 推出的,NodeJs 自帶了這個功能



2.使用 import 將圖檔引入

1
2
3
4
5
6
7
8
9
import Img from "./images/react.jpg";

function App() {
return (
<img src={Img} alt=""/>
);
}

export default App;

import 是 ES6 的語法,透過 Babel 轉譯後還是會使用 CommonJS 加載,也就是如果你寫了 import 最後還是會被轉成 require,import 的寫法等同於第一種的 require 方法





兩種方法效能上基本上沒區別,因為轉譯過後還是一樣的東西




不過以 require / exports 來說,只有簡單的寫法

1
2
3
const demo = require('demo')
exports.demo = demo
module.exports = demo

而 import / export 的寫法就很多樣了

1
2
3
4
5
6
7
8
9
10
11
12
import demo from 'demo'
import { default as demo } from 'demo'
import * as demo from 'demo'
import { readFile } from 'demo'
import { readFile as read } from 'demo'
import demo, { readFile } from 'demo'

export default demo
export const demo
export function readFile
export { readFile, read }
export * from 'demo'

import 屬於靜態編譯,所以沒辦法動態加載,但 require 可以

1
2
3
4
const url = "a" + "b"

import url // X 錯誤
require(url) // OK



圖片懶加載(Lazy load)

講完如何載入圖片,來談談圖片的懶加載。

有些網站載入時,一開始圖片會有一個佔位符,可能是一個色塊或是一個佔位符圖片,當滾輪往下移動時,真正的圖片才顯示出來,像 unsplash 就是一個例子

unsplash

圖片懶加載可以節省一堆圖片的運算,滾到需要顯示的圖片才載入,頁面的加載速度會比較快,不占用後台資源,頁面的速度也利於 SEO,適用在圖片較多的地方,如電商、圖片素材庫等

缺點

  • 因要監聽圖片是否顯示,較耗瀏覽器效能
  • 如網路不好,圖片會很慢才顯示,會有一段空白時間

推薦一個簡易就可以達到圖片懶加載的套件 React Lazy Load Image Component





React Lazy Load Image 使用方法

  • 安裝 React Lazy Load Image Component
  • 載入 LazyLoadImage 組件
  • 使用 LazyLoadImage 組件
  • 添加佔位符圖片
  • 添加佔位符模糊效果


1. 安裝 React Lazy Load Image Component

1
2
3
4
5
// Yarn
$ yarn add react-lazy-load-image-component

// NPM
$ npm i --save react-lazy-load-image-component

你可以用 npm 或 yarn 來安裝 react-lazy-load-image-component





2. 載入 LazyLoadImage 組件

1
2
import Image from "../images/dog.jpg";
import { LazyLoadImage } from "react-lazy-load-image-component";

載入 LazyLoadImage 就可以使用此組件





3. 使用 LazyLoadImage 組件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Image from "../images/dog.jpg";
import { LazyLoadImage } from "react-lazy-load-image-component";

export default function App() {
return (
<div>
<LazyLoadImage
src={Image}
width={500}
height={500}
alt=""
/>
</div>
);
}

img 的標籤改為 LazyLoadImage 組件,並明確加上寬高,以避免累積佈局偏移(CLS)問題,到這邊已經可以有 lazy load 的效果




4. 添加佔位符圖片

1
2
3
4
5
6
7
8
9
10
11
import Image from "../images/dog.jpg";
import PlaceholderImage from "../images/placeholder.jpg";
import { LazyLoadImage } from 'react-lazy-load-image-component';

<LazyLoadImage
src={Image}
width={600}
height={400}
placeholdersrc={PlaceholderImage}
alt=""
/>

可以準備一張低解析的佔位符圖片,是用來滾下卷軸前顯示的圖片,並指向 placeholdersrc 屬性





5. 添加佔位符模糊效果

1
2
3
4
5
6
7
8
9
10
11
12
13
import Image from "../images/dog.jpg";
import PlaceholderImage from "../images/placeholder.jpg";
import { LazyLoadImage } from 'react-lazy-load-image-component';
import 'react-lazy-load-image-component/src/effects/blur.css';

<LazyLoadImage
src={Image}
width={600}
height={400}
placeholdersrc={PlaceholderImage}
effect="blur"
alt=""
/>

佔位符圖片也可以有模糊效果,顯示圖片前會將圖片模糊,需載入 css,並加入屬性 effect="blur"

可以打開 Network 看看 Img 的變化,在滾動之前 Img 會是空的,直到滾到圖片的地方才載入,將 Network 調到 Slow 3G 效果會更明顯

network

這邊附上 Demo,一起觀察看看吧!





圖片預加載

有懶加載就會有預加載,預加載跟懶加載相反,頁面一進來就先把圖片都先載入,將圖片存入緩存,圖片就不會有延遲的效果,可以享受無需等待直接預覽的效果,適用的地方如漫畫、圖片畫廊等不希望讓用戶看到加載時空白的場景

缺點

  • 預加載會占用較多後台資源
  • 頁面一開始載入的時間較長
1
2
3
4
5
6
7
8
9
10
import image1 from "../images/image1.jpg";
import image2 from "../images/image2.jpg";
import image3 from "../images/image3.jpg";

useEffect(() => {
const imageList = [image1, image2, image3]
imageList.forEach((image) => {
new Image().src = image
});
}, [])

[任務解題]

圖片的部分,這邊用了 Lorem Picsum 的 random 圖片作替代,也加上了 lazy-load 的效果

菜單的圖片也完成囉!



結語

圖片載入的方法可以用 require 或 import,個人是比較喜歡用 ES6 import 的寫法,我們也學到了懶加載和預加載使用方法,可以依據需求或適用情境去做加載,一起練習看看吧!!

Reference

JavaScript 中 require, import 的差別及效能
如何在React 中實現圖片懶加載
超詳細的圖片預加載和懶加載教程


本文為 IT 鐵人賽系列文 你 React 了嗎? 30 天解鎖 React 技能




Hey!想學習更多前端知識嗎?

最近 Lala 開了前端課程 👉【實地掌握RWD - 12小時新手實戰班】👈
無論您是 0 基礎新手,又或是想學 RWD 的初學者,
我們將帶你從零開始,深入了解並掌握 RWD 響應式網頁設計的核心技術,快來一起看看吧 😊



🚀線上課程分享

線上課程可以加速學習的時間,省去了不少看文件的時間XD,以下是我推薦的一些課程
想學習更多關於前後端的線上課程,可以參考看看。

Hahow

Hahow 有各式各樣類型的課程,而且是無限次數觀看,對學生或上班族而言,不用擔心被時間綁住



六角學院

如果你是初學者,非常推薦六角學院哦!
剛開始轉職也是上了六角的課,非常的淺顯易懂,最重要的是,隨時還有線上的助教幫你解決問題!


Udemy

Udemy 裡的課程非常的多,品質普遍不錯,且價格都滿實惠的,CP值很高!
也是很多工程師推薦的線上課程網站。
❤️