การรองรับ Browser เก่า
วันนี้ไม่ต้องกังวลมากนัก Browser เก่าใช้ได้ดีตั้งแต่ IE8 ตายไปแล้ว
แต่คำถามคือ: ควรรองรับ IE9 และ Browser เก่าอื่นๆ ยังไง? หรือควรละทิ้งเลย?
คิดในแง่ Features ไม่ใช่ Browsers
แทนที่จะเช็ค Browser (if Browser A ... if Browser B ...) ให้เช็ค Feature โดยตรง:
// แทนการเช็ค Browser
if (featureA) {
// ใช้ Feature A
} else {
// Fallback Code
}
โค้ดนี้ทำงาน Browser A ถึง Z ได้หมด ไม่ต้องแก้ทุกครั้งที่มี Browser ใหม่
ตัดสินใจใช้ Feature หรือไม่
หลายคนตัดสินใจจาก "Browser กี่ตัวรองรับ" แต Browser ไม่สำคัญ
สำคัญคือ: เขียน Fallback ได้ง่ายไหม?
- เขียน Fallback ได้ง่าย -> ใช้ Feature ได้เลย
- เขียน Fallback ยาก/ไม่คุ้ม -> อย่าใช้ Feature นั้น
ตัดสิน Browser ไหน ไหนไม่รองรับ
ยังต้องมี Cutoff ดูว่า User จริงใช้ Browser อะไร (Analytics) ตามนั้น
Outlier ใช้ IE6 -> คุ้มไหมที่จะเขียนโค้ดเพิ่มให้คนแทบไม่มี? พลังงานควรไปที่ไหนมากกว่า?
ระดับการรองรับ (4 ระดับ)
- ทุกอย่างต้องเหมือนกันทุก Browser (Looks & Works Same)
- หน้าตาเหมือนกัน แต่ Functionality อาจต่างกัน
- Functionality เหมือนกัน แต่หน้าตาอาจต่างกัน
- หน้าตาและ Functionality ต่างกันก็ได้
คุณให้ระดับไหน? ทำไม?
รองรับ Browser เก่า — CSS
2 วิธีให้ Fallback:
- Property Fallbacks
- Feature Queries (
@supports)
Property Fallbacks
Browser ไม่รู้จัก Property/Value -> ข้ามไป -> ใช้ค่าก่อนหน้า (Cascade)
.layout {
display: block; /* Fallback */
display: grid; /* Modern */
}
Browser รองรับ Grid -> ใช้ display: grid ไม่รองรับ -> Fallback เป็น block
ลด Default Values
ถ้า Element Default เป็น display: block แล้ว ไม่ต้องเขียน Fallback
.layout { display: grid; }
Browser ไม่รองรับ Grid จะอ่าน grid-template-columns ไม่ได้ -> ข้ามไป -> ใช้ Default
Feature Queries (@supports)
เช่น if/else ใน CSS
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 1em;
padding-left: 1em;
padding-right: 1em;
}
}
Padding จะถูกอ่านเฉพาะ Browser ที่รองรับ @supports และ Grid
Support ของ @supports
Browser หลักทุกรุ่นรองรับแล้ว (IE11 ไม่รองรับ แต่ผมไม่รองรับ IE11 แล้ว)
ใช้ Property Fallbacks และ @supports พร้อมกัน
ลำดับการประกาศสำคัญ! CSS Cascade: ตัวหลังทับตัวหน้า
/* ผิด: Padding 2em จะทับ 1em ทุก Browser */
@supports (display: grid) { .layout { padding: 1em; } }
.layout { padding: 2em; }
/* ถูก: Fallback ก่อน Modern หลัง */
.layout { padding: 2em; }
@supports (display: grid) { .layout { padding: 1em; } }
ถ้าใช้ @supports not ให้เขียน @supports not ก่อนเสมอ
เว็บควรหน้าตาเหมือนกันทุก Browser ไหม?
มุมมอง 2 ด้าน: (1) Branding ต้อง Consistent (2) Progressive Enhancement ให้ Browser ดีกว่าได้ประสบการณ์ดีกว่า
มุมมองสำคัญที่สุด: User เว็บให้ User ได้สิ่งที่มาหาไหม? ถ้าได้ -> ไม่ต้องติด Consistent มากเกินไป ให้ Browser ดีกว่าได้ประสบการณ์ดีกว่า!
รองรับ Browser เก่า — JavaScript
ง่ายกว่า CSS: ใช้ Polyfill ส่วนใหญ่
Polyfill คืออะไร?
โค้ดที่บอก Browser ว่า Implement Feature นั้นยังไง เช็คว่ารองรับไหม -> ถ้าไม่ -> เพิ่มโค้ดรองรับ
// Polyfill Array.prototype.find (จาก MDN)
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
if (this == null) throw new TypeError('"this" is null or not defined');
var o = Object(this);
var len = o.length >>> 0;
if (typeof predicate !== 'function') throw new TypeError('predicate must be a function');
var thisArg = arguments[1];
var k = 0;
while (k < len) {
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) return kValue;
k++;
}
return undefined;
},
configurable: true, writable: true
});
}
2 วิธีใช้ Polyfill
- Manual: หา Polyfill มาใส่เอง (Google หาได้ทุกอย่าง)
- Library: ES6-shim (รองรับ ES6 ทั้งหมด) หรือ core-js
Cutting-edge JS Features
ใช้ Babel ใน Build Process: Compile JS, 加 Polyfill/Shim, แปลง Preprocessors (TypeScript, Flow) -> JS ที่ Browser อ่านได้
ถ้า Polyfill ไม่พอ?
พิจารณา: จำเป็นต้องมี Feature นี้ไหม? Progressive Enhancement ดีกว่า? เขียนแบบไม่ใช้ Feature นี้ได้ไหม?
เช็ค Browser Support ยังไง?
- caniuse.com — พิมพ์ Feature Name ดู Support Table
- MDN — ดู Browser Support ท้ายบทความ
ระวัง Cost ของ JavaScript
Polyfill = JS มากขึ้น -> (1) Browser เก่า = เครื่องเก่า = ประมวลผลอ่อน (2) Bundle ใหญ่ -> Load ช้าขึ้น (อ่าน "The Cost of JavaScript" by Addy Osmani)
ทำไมต้องดูแล Browser เก่า?
Argument ธุรกิจ: คนใช้ Browser เก่า = เครื่องเก่า = ไม่มีเงิน = ไม่ซื้อของเรา -> ทำไมต้องดูแล?
แต่นักพัฒนาดีๆ ยังคงดูแล เพราะ...
สมมติฐานที่ผิด
"คนใช้ Browser เก่า = เครื่องเก่า = ไม่มีเงิน" -> ผิดหลายกรณี:
- บริษัทไม่อนุมัติอัปเกรด
- พอใจเครื่องเก่า ไม่อยากเปลี่ยน
- ไม่มีความรู้อัปเกรด
- ไม่เข้าถึงเครื่องใหม่ได้
- ผูกมัดกับ Mobile ที่ Browser อ่อน
อย่าสมมติ (Don't Assume)
Wheelchair Accessibility (การเข้าถึงรถเข็น)
สิงคโปร์: ทุกรายทางมีทางลาด/ลิฟต์ ข้างบันได ทำไม? บางคนเดินไม่ได้ ต้องนั่งรถเข็น ลงบันไดไม่ได้
แต่มากกว่านั้น: เข่าอ่อน, จักรยาน/สกูตเตอร์, แม่พ่อลากรถเข็นเด็ก — ทุกคนได้ประโยชน์
ไม่มีรายได้จากลิฟต์/ทางลาดโดยตรง แต่มัน คุ้มค่า (Worth it) — คุ้มค่าอย่างอื่น ไม่ใช่แค่เงิน
Global Warming
บางคนไม่แคร์โลกร้อน บางคนแคร์ อยากให้ลูกหลานมีโลกดีกว่า
คุณจะให้เงินบริษัทที่ทำลายโลกไหม? ไม่ใช่เรื่องเงินอย่างเดียว
Web is for Everyone
"The dream behind the Web is of a common information space in which we communicate by sharing information." — Tim Berners-Lee
เรา Frontend Developers เป็นผู้ดูแล Web Web จะเป็นอย่างไร ขึ้นอยู่กับเรา เราบังคับคนอื่นไม่ได้ แตเราสร้างทางลาด/ลิฟต์ให้เองได้
เลือกอยู่ที่คุณ จะ Care หรือไม่ก็ได้ แต่นักพัฒนาที่ดีส่วนใหญ่... They Care. We Care.