แบไต๋ประสิทธิภาพภาพเว็บ
เผยแพร่แล้ว: 2022-03-10เนื่องจากเบราว์เซอร์ปรับปรุงความสามารถในการแสดงผลกราฟิกอย่างต่อเนื่อง ความสามารถในการออกแบบภายในตัวเบราว์เซอร์อย่างแท้จริงจึงกลายเป็นความจริงมากขึ้น โค้ดไม่กี่บรรทัดสามารถแสดงผลได้อย่างรวดเร็วและน่าทึ่ง และ ช่วยให้มีความสอดคล้องกันโดยไม่ต้องใช้ความพยายาม มากนัก และเช่นเดียวกับส่วนใหญ่ในการพัฒนาเว็บ มักจะมีหลายวิธีที่จะบรรลุผลเช่นเดียวกัน
ในโพสต์นี้ เราจะมาดูเอฟเฟกต์ภาพยอดนิยม ระดับสีเทา และประเมินทั้งความง่ายในการใช้งานและผลกระทบด้านประสิทธิภาพของผ้าใบ HTML, SVG, ตัวกรอง CSS และโหมดผสมผสาน CSS อันไหนจะชนะ?
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- แบไต๋ประสิทธิภาพภาพเว็บ
- HTML5: ข้อเท็จจริงและตำนาน
- การปรับขนาดรูปภาพอย่างมีประสิทธิภาพด้วย ImageMagick
- เทคนิคการเพิ่มประสิทธิภาพ JPEG อย่างชาญฉลาด
ฟิลเตอร์บนเว็บทำงานเหมือนกับเลนส์ที่วางทับรูปภาพ สิ่งเหล่านี้ถูกนำไปใช้กับรูปภาพหลังจากที่เบราว์เซอร์แสดงเลย์เอาต์และสีเริ่มต้น ในเบราว์เซอร์ที่รองรับ สามารถใช้ตัวกรองแยกกันหรือวางทับซ้อนกันได้ เนื่องจากสามารถใช้เป็นการปรับเปลี่ยนภาพหลังจากการเรนเดอร์ครั้งแรก และมีแนวโน้มว่าจะเป็นการเพิ่มประสิทธิภาพ ตัวกรองจะลดระดับลงอย่างงดงามโดยเพียงไม่ปรากฏในเบราว์เซอร์ที่ไม่สนับสนุนตัวกรองเหล่านี้
ตัวกรอง CSS
มาเริ่มกันด้วยวิธีที่ตรงไปตรงมาที่สุดในการสร้างเอฟเฟกต์ระดับสีเทา: ตัวกรอง CSS ที่เรียบง่ายแต่ทรงพลัง

เพื่อให้บรรลุผลนี้ เราเพิ่ม CSS: filter: grayscale(1)
บรรทัดเดียว ตัวกรองนี้ทำให้ภาพดูจืดชืด และสามารถใช้ได้กับค่าตัวเลขหรือค่าเปอร์เซ็นต์ใดๆ ระหว่าง 0 ถึง 1 (หรือ 0% ถึง 100%) หมายเหตุ: ปัจจุบัน ตัวกรองสำหรับเบราว์เซอร์ที่ใช้ WebKit จะต้องนำหน้าด้วย -webkit-
อย่างไรก็ตาม โซลูชันเช่น Autoprefixer จะขจัดความจำเป็นในการเพิ่มด้วยตนเอง
การสาธิตสด – ตัวกรอง CSS
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
โหมดผสมผสานพื้นหลัง
โหมดผสมผสาน CSS มอบตัวเลือกที่หลากหลายไม่รู้จบสำหรับการผสมผสานเอฟเฟกต์ภาพ มีสองวิธีในการใช้โหมดผสมผสาน: คุณสมบัติ mix-blend-mode
background-blend-mode
-
mix-blend-mode
เป็นคุณสมบัติที่อธิบายว่าองค์ประกอบจะผสมผสานกับเนื้อหาที่อยู่เบื้องหลังได้อย่างไร -
background-blend-mode
ใช้สำหรับองค์ประกอบที่มีพื้นหลังหลายอัน และอธิบายความสัมพันธ์ระหว่างพื้นหลังเหล่านี้
เราจะใช้ background-blend-mode: luminosity
เพื่อดึงช่องความส่องสว่างเหนือพื้นหลังสีเทาในตัวอย่างของเรา ส่งผลให้ได้ภาพระดับสีเทา สิ่งหนึ่งที่ควรทราบคือลำดับพื้นหลังจะคงที่: ต้องเรียงลำดับภาพพื้นหลังก่อนสีทึบหรือพื้นหลังแบบไล่ระดับสีเสมอเพื่อให้เอฟเฟกต์แสดงผลได้อย่างเหมาะสม สีต้องเป็นเลเยอร์พื้นหลังสุดท้าย นี่เป็นการป้องกันเบราว์เซอร์รุ่นเก่าที่ไม่สนับสนุน background-blend-mode
- รูปภาพจะยังคงแสดงผลโดยไม่มีผลกระทบ
ความแตกต่างเพียงอย่างเดียวของโหมดผสมผสานและตัวกรอง CSS คือตอนนี้เรามีพื้นหลังหลายแบบ และกำลังใช้ background-blend-mode: luminosity
ซึ่งดึงค่าความส่องสว่างจากภาพด้านบน (โปรแกรมทดสอบนก) และจัดเลเยอร์ค่าความสว่างเหล่านั้นทับ พื้นหลังสีเทาที่สอง
การสาธิตสด – โหมดผสมผสานพื้นหลัง
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
ในขณะนี้ นี่เป็นตัวเลือกใหม่ล่าสุดและได้รับการสนับสนุนน้อยที่สุด แม้ว่าจะยังคงทำงานได้ดีใน Chrome และ Firefox และมีการรองรับ Safari บางส่วน หมายเหตุ: Safari รองรับโหมดผสมผสานทั้งหมด ยกเว้นโหมดการผสมแบบ HSL: เฉดสี ความอิ่มตัวของสี และความส่องสว่าง
ผ้าใบ HTML5
HTML5 <canvas>
ให้ความยืดหยุ่นมากมายในการจัดการภาพ เนื่องจากเรามีสิทธิ์เข้าถึงข้อมูลของแต่ละพิกเซล (โดยเฉพาะผ่าน canvasContext.getImageData
) และสามารถจัดการแต่ละพิกเซลได้ผ่าน JavaScript อย่างไรก็ตาม วิธีนี้ซับซ้อนที่สุดและมีค่าใช้จ่ายสูงที่สุด นอกจากนี้ยังมีความแตกต่างเล็กน้อยในประเด็นข้ามที่มาเนื่องจากปัญหาด้านความปลอดภัย
ในการแก้ไขข้อผิดพลาด cross-origin ใน Chrome รูปภาพของคุณจะต้องโฮสต์บนไซต์ที่เป็นมิตรต่อการแบ่งปันทรัพยากรข้ามแหล่งที่มา (CORS) เช่น GitHub Pages หรือ Dropbox และระบุ crossOrigin="Anonymous"
ดูตัวอย่างสดสำหรับการสาธิต
วิธีเพื่อให้ได้เอฟเฟกต์โทนสีเทาด้วย <canvas>
คือการตัดส่วนประกอบสีแดง สีเขียว และสีน้ำเงินออกจากค่าที่อยู่นอกสุดในค่าพิกเซลโดยที่ยังคงระดับความสว่าง (ความสว่าง) ไว้ วิธีหนึ่งในการทำเช่นนี้คือการหาค่าเฉลี่ยของค่า RGB เช่น: grayscale = (red + green + blue) / 3;
.

ในตัวอย่างด้านล่าง เรากำลังใช้ค่า RGBa ในรูปแบบ (R,G,B,a)
ในข้อมูลภาพ ช่องสีแดงคือ data[0]
ช่องสีเขียวคือ data[1]
เป็นต้น จากนั้นเราจะได้ระดับความส่องสว่างของแต่ละช่องสัญญาณเหล่านี้ (ความสว่าง) และหาค่าเฉลี่ยเพื่อเปลี่ยนระดับสีเทาของภาพ
การสาธิตสด – HTML5 Canvas
ตัวกรอง SVG
ตัวกรอง SVG มีการรองรับที่กว้างที่สุด (แม้ใน Internet Explorer และ Edge!) และ (เกือบ) ใช้งานง่ายพอๆ กับตัวกรอง CSS โดยตรง คุณสามารถใช้คุณสมบัติ filter
เดียวกันได้ อันที่จริง ตัวกรอง CSS เกิดจากตัวกรอง SVG เช่นเดียวกับผ้าใบ ตัวกรอง SVG ช่วยให้คุณก้าวข้ามระนาบเรียบของเอฟเฟกต์สองมิติได้ เนื่องจากคุณสามารถใช้การแรเงา WebGL เพื่อสร้างผลลัพธ์ที่ซับซ้อนยิ่งขึ้น
มีสองสามวิธีในการใช้ตัวกรอง SVG แต่ในกรณีนี้ เราจะยังคงใช้คุณสมบัติ filter
บนรูปภาพพื้นหลัง เช่นเดียวกับตัวอย่างตัวกรอง CSS เพื่อความสอดคล้อง ความแตกต่างที่ใหญ่ที่สุดของตัวกรอง SVG คือ เราต้องระวังในการรวมและเชื่อมโยงไปยังตัวกรองนี้ด้วยเส้นทางที่เหมาะสม ซึ่งหมายความว่าเราจำเป็นต้อง นำเข้า SVG บนหน้าเหนือองค์ประกอบที่เราใช้อยู่ (ซึ่งสามารถทำได้ง่ายขึ้นโดยใช้เครื่องมือสร้างเทมเพลตและรวมข้อความสั่ง)
การสาธิตสด – ตัวกรอง SVG
<svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
.svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }
ประสิทธิภาพการกรอง
ดังนั้นสิ่งเหล่านี้จะซ้อนกันได้อย่างไรเมื่อพูดถึงประสิทธิภาพการเรนเดอร์เริ่มต้น? ฉันสร้างหน้าทดสอบสำหรับแต่ละหน้าและใช้คุณลักษณะการเปรียบเทียบ WebPagetest ใน Chrome 47 โปรดทราบว่าการทดสอบแต่ละครั้งให้ผลลัพธ์ที่แตกต่างกันเล็กน้อย แนวโน้มโดยรวมสามารถสรุปได้ดังนี้:
ตัวกรอง CSS, ตัวกรอง SVG และเมธอดโหมดผสมผสาน CSS ทั้งหมดโหลดในกรอบเวลาที่ใกล้เคียงกัน บางครั้งตัวกรอง SVG นั้นเร็วกว่าโหมดผสมผสาน CSS (แต่แทบไม่มีเลย) และในทางกลับกัน โดยทั่วไปแล้ว ตัวกรอง CSS นั้นโหลดได้เร็วที่สุด และ <canvas>
นั้นช้าที่สุดเสมอ นี่คือข้อมูลเชิงลึกที่สำคัญที่สุดที่รวบรวมได้ <canvas>
มักจะล้าหลังวิธีการอื่นๆ ในการแสดงภาพอยู่เสมอ
เพื่อความเป็นธรรม ฉันต้องการเปรียบเทียบเวลาในการโหลดภาพหลายภาพด้วย ฉันสร้างการแสดงแต่ละครั้งสิบครั้ง (แทนที่จะเป็นเพียงฉบับเดียว) และทำการทดสอบอีกครั้ง:
ผลลัพธ์มีความคล้ายคลึงกัน (โปรดทราบว่าการทดสอบแต่ละครั้งมีความแตกต่างกันเล็กน้อย) ในกรณีนี้ ตัวกรอง CSS ช้าลง 0.1 มิลลิวินาที ซึ่งแสดงให้เห็นว่าระหว่างตัวกรอง CSS, โหมดผสมผสาน และตัวกรอง SVG ผลลัพธ์นั้นไม่สามารถสรุปได้สำหรับวิธีที่รวดเร็วที่สุด อย่างไรก็ตาม HTML5 <canvas>
ล้าหลังอย่างเห็นได้ชัดเมื่อเปรียบเทียบ
การพิจารณาเวลาในการโหลดหน้าเว็บให้ลึกซึ้งยิ่งขึ้นผ่านการแสดงผล JavaScript และเวลาในการแสดงสี คุณจะเห็นว่าแนวโน้มนี้ยังคงดำเนินต่อไป

ประเภทตัวกรอง | เวลาแสดงผล | ได้เวลาลงสี |
---|---|---|
ตัวกรอง CSS | 12.94ms | 4.28ms |
โหมดผสมผสาน CSS | 12.10ms | 4.45ms |
ตัวกรอง SVG | 14.77ms | 5.80ms |
ตัวกรองผ้าใบ | 15.23ms | 10.73ms |
อีกครั้ง <canvas>
ใช้เวลาในการเรนเดอร์นานที่สุดและระบายสีนานที่สุด ในขณะที่ตัวเลือก CSS สองตัวเลือกนั้นรวดเร็วที่สุด โดย SVG จะอยู่ตรงกลาง
ผลลัพธ์เหล่านี้สมเหตุสมผล เพราะ <canvas>
กำลังรับแต่ละพิกเซลและดำเนินการกับพิกเซลนั้นก่อนที่เราจะสามารถเห็นภาพใดๆ ได้เลย ต้องใช้พลังในการประมวลผลมากในขณะที่เรนเดอร์ แม้ว่าปกติแล้ว SVG จะใช้สำหรับกราฟิกแบบเวกเตอร์ แต่ฉันก็ยังขอแนะนำมากกว่า <canvas>
เมื่อต้องรับมือกับเอฟเฟกต์ภาพแรสเตอร์ ไม่เพียงแต่ SVG จะเร็วขึ้นเท่านั้น แต่ยังจัดการได้ง่ายกว่าและมีความยืดหยุ่นมากขึ้นภายใน DOM โดยทั่วไปแล้ว ตัวกรอง CSS จะได้รับการปรับให้เหมาะสมมากกว่าตัวกรอง SVG เนื่องจากในอดีตเป็นทางลัดที่โผล่ออกมาจากตัวกรอง SVG และด้วยเหตุนี้จึงปรับให้เหมาะสมในเบราว์เซอร์
#ไม่มีตัวกรอง
แล้วถ้าไม่ใช้ฟิลเตอร์ล่ะ? ฉันเปรียบเทียบวิธีการที่รวดเร็วที่สุดโดยรวมของเรา (เพิ่มตัวกรอง CSS) กับการแก้ไขภาพของคุณในซอฟต์แวร์แก้ไขรูปภาพก่อนอัปโหลด (ฉันใช้การแสดงตัวอย่างบน Mac OS X เพื่อลบความอิ่มตัว) เมื่อแก้ไขรูปภาพล่วงหน้า ฉันพบว่าการทดสอบมีการปรับปรุงประสิทธิภาพ 0.1ms อย่างสม่ำเสมอ:
บทสรุป
ฟิลเตอร์รูปภาพเป็นวิธีที่สนุกและมีประสิทธิภาพในการมอบความสามัคคีและความสวยงามของภาพบนเว็บ โปรดทราบว่าสิ่งเหล่านี้มาพร้อมกับประสิทธิภาพที่ลดลงเล็กน้อย แต่ยังมีประโยชน์จากการออกแบบที่รวดเร็วในเบราว์เซอร์และโอกาสในการออกแบบการโต้ตอบด้วย
สำหรับเอฟเฟกต์รูปภาพอย่างง่าย ให้ใช้ฟิลเตอร์ CSS เนื่องจากมีการสนับสนุนที่กว้างที่สุดและการใช้งานที่ง่ายที่สุด สำหรับเอฟเฟกต์ภาพที่ซับซ้อนยิ่งขึ้น ให้ดูตัวกรอง SVG หรือโหมดผสมผสาน CSS เอฟเฟกต์ฟิลเตอร์ SVG นั้นดีเป็นพิเศษเนื่องจากความสามารถในการจัดการช่องสัญญาณและ feColorMatrix
โหมดผสมผสาน CSS ยังนำเสนอเอฟเฟกต์ภาพที่สวยงามด้วยองค์ประกอบที่ทับซ้อนกันบนหน้า คุณสามารถใช้โหมดผสมผสานที่คล้ายกันภายใน SVG (เช่น feBlend
) ได้ แม้ว่าจะคล้ายกับ background-blend-mode
CSS ในแง่ที่ว่าการโต้ตอบนั้นเกี่ยวข้องกับ SVG เอง ไม่ใช่กับองค์ประกอบโดยรอบ เช่น mix-blend-mode
อนุญาต อย่าใช้ <canvas>
สำหรับฟิลเตอร์