Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> ซอฟต์แวร์ >> เบราว์เซอร์

ทำไมต้องรองรับ Browser เก่า?: คู่มือสมัยใหม่สำหรับนักพัฒนา Frontend

การรองรับ 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 ระดับ)

  1. ทุกอย่างต้องเหมือนกันทุก Browser (Looks & Works Same)
  2. หน้าตาเหมือนกัน แต่ Functionality อาจต่างกัน
  3. Functionality เหมือนกัน แต่หน้าตาอาจต่างกัน
  4. หน้าตาและ Functionality ต่างกันก็ได้

คุณให้ระดับไหน? ทำไม?

รองรับ Browser เก่า — CSS

2 วิธีให้ Fallback:

  1. Property Fallbacks
  2. 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

  1. Manual: หา Polyfill มาใส่เอง (Google หาได้ทุกอย่าง)
  2. 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 ยังไง?

  1. caniuse.com — พิมพ์ Feature Name ดู Support Table
  2. 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.