Smart Bundling: วิธีให้บริการรหัสดั้งเดิมกับเบราว์เซอร์รุ่นเก่าเท่านั้น

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ในขณะที่การรวมกลุ่มของทรัพยากรบนเว็บอย่างมีประสิทธิภาพได้รับการแบ่งปันความคิดอย่างมากในช่วงไม่กี่ครั้งที่ผ่านมา วิธีที่เราจัดส่งทรัพยากรส่วนหน้าไปยังผู้ใช้ของเรายังคงเหมือนเดิม น้ำหนักเฉลี่ยของทรัพยากรจาวาสคริปต์และรูปแบบที่เว็บไซต์จัดส่งให้นั้นเพิ่มขึ้น แม้ว่าเครื่องมือสร้างเพื่อเพิ่มประสิทธิภาพเว็บไซต์ไม่เคยดีไปกว่านี้แล้ว ด้วยส่วนแบ่งการตลาดของเบราว์เซอร์ที่เติบโตอย่างรวดเร็วและเบราว์เซอร์ที่เปิดตัวรองรับคุณสมบัติใหม่ในการล็อก ถึงเวลาแล้วหรือยังที่เราจะคิดใหม่เกี่ยวกับการส่งมอบทรัพย์สินสำหรับเว็บสมัยใหม่?

เว็บไซต์ในปัจจุบันได้รับปริมาณการใช้งานจำนวนมากจากเบราว์เซอร์ที่ใช้งานได้ยาวนาน ซึ่งส่วนใหญ่รองรับ ES6+, มาตรฐาน JavaScript ใหม่, API แพลตฟอร์มเว็บใหม่ และแอตทริบิวต์ CSS ได้ดี อย่างไรก็ตาม เบราว์เซอร์รุ่นเก่ายังคงต้องได้รับการสนับสนุนในอนาคตอันใกล้ — ส่วนแบ่งการใช้งานมีขนาดใหญ่พอที่จะไม่ถูกละเว้น ขึ้นอยู่กับฐานผู้ใช้ของคุณ

การดูตารางการใช้งานของ caniuse.com อย่างรวดเร็วเผยให้เห็นว่าเบราว์เซอร์ที่เขียวชอุ่มตลอดปีครอบครองส่วนแบ่งตลาดเบราว์เซอร์อย่างมาก — มากกว่า 75% ถึงแม้ว่าสิ่งนี้ จะเป็นบรรทัดฐานคือการเติมคำนำหน้า CSS, transpile ของ JavaScript ทั้งหมดของเราเป็น ES5 และรวม polyfills เพื่อรองรับผู้ใช้ทุกคนที่เราใส่ใจ

แม้ว่าสิ่งนี้สามารถเข้าใจได้จากบริบททางประวัติศาสตร์ — เว็บเป็นเรื่องเกี่ยวกับการปรับปรุงที่ก้าวหน้ามาโดยตลอด — คำถามยังคงอยู่: เรากำลังทำให้เว็บช้าลงสำหรับผู้ใช้ส่วนใหญ่ของเราหรือไม่เพื่อรองรับชุดเบราว์เซอร์รุ่นเก่าที่ลดน้อยลง

การแปลงไฟล์เป็น ES5, โพลีฟิลสำหรับแพลตฟอร์มเว็บ, โพลีฟิล ES6+, คำนำหน้า CSS
เลเยอร์ความเข้ากันได้ต่างๆ ของเว็บแอป (ดูรุ่นใหญ่)

ค่าใช้จ่ายในการสนับสนุนเบราว์เซอร์รุ่นเก่า

มาทำความเข้าใจกันว่าขั้นตอนต่างๆ ในไปป์ไลน์การสร้างทั่วไปสามารถเพิ่มน้ำหนักให้กับทรัพยากรส่วนหน้าของเราได้อย่างไร:

กำลังถ่ายโอนไปยัง ES5

ในการประมาณการว่าทรานสพิลน้ำหนักสามารถเพิ่มไปยังบันเดิล JavaScript ฉันได้นำไลบรารี JavaScript ยอดนิยมสองสามตัวที่เขียนด้วย ES6+ มาแต่แรก และเปรียบเทียบขนาดบันเดิลก่อนและหลัง transpilation:

ห้องสมุด ขนาด
(ลดขนาด ES6)
ขนาด
(ลดขนาด ES5)
ความแตกต่าง
TodoMVC 8.4 KB 11 KB 24.5%
ลากได้ 53.5 KB 77.9 KB 31.3%
Luxon 75.4 KB 100.3 KB 24.8%
Video.js 237.2 KB 335.8 KB 29.4%
PixiJS 370.8 KB 452 KB 18%

โดยเฉลี่ย บันเดิลที่ไม่มีการขนถ่ายจะเล็กกว่ามัดที่ทรานสไพล์ลงเป็น ES5 ประมาณ 25% ไม่น่าแปลกใจเลยที่ ES6+ ให้วิธีการที่กระชับและชัดเจนมากขึ้นในการแสดงตรรกะที่เทียบเท่า และการถ่ายทอดคุณลักษณะบางอย่างเหล่านี้ไปยัง ES5 อาจต้องใช้โค้ดจำนวนมาก

โพลีฟิล ES6+

แม้ว่า Babel จะใช้การเปลี่ยนรูปแบบวากยสัมพันธ์กับโค้ด ES6+ ของเราได้ดี แต่ฟีเจอร์ในตัวที่นำมาใช้ใน ES6+ — เช่น Promise , Map and Set และวิธีการอาร์เรย์และสตริงแบบใหม่ — ยังคงต้องมีโพลีฟิล การลดลงใน babel-polyfill ตามที่เป็นอยู่สามารถเพิ่มได้เกือบ 90 KB ไปยังบันเดิลที่ย่อเล็กสุดของคุณ

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

Polyfills แพลตฟอร์มเว็บ

การพัฒนาเว็บแอปพลิเคชันสมัยใหม่ง่ายขึ้นเนื่องจากมี API เบราว์เซอร์ใหม่มากมายเหลือเฟือ สิ่งที่ใช้กันทั่วไปคือ fetch สำหรับการขอทรัพยากร IntersectionObserver สำหรับการสังเกตการมองเห็นองค์ประกอบและข้อกำหนด URL อย่างมีประสิทธิภาพ ซึ่งทำให้การอ่านและการจัดการ URL บนเว็บง่ายขึ้น

การเพิ่มโพลีฟิลที่เป็นไปตามข้อกำหนดสำหรับแต่ละคุณลักษณะเหล่านี้สามารถมีผลกระทบอย่างเห็นได้ชัดต่อขนาดบันเดิล

CSS Prefixing

สุดท้ายนี้ มาดูผลกระทบของคำนำหน้า CSS แม้ว่าคำนำหน้าจะไม่เพิ่มน้ำหนักให้กับการรวมกลุ่มมากเท่ากับการเปลี่ยนรูปแบบบิลด์อื่น ๆ โดยเฉพาะอย่างยิ่งเนื่องจากบีบอัดได้ดีเมื่อ Gzip'd แต่ก็ยังมีเงินออมอยู่บ้าง

ห้องสมุด ขนาด
(ย่อเล็กสุด นำหน้าสำหรับ 5 เบราว์เซอร์เวอร์ชันล่าสุด)
ขนาด
(ย่อเล็กสุด นำหน้าสำหรับเบราว์เซอร์เวอร์ชันล่าสุด)
ความแตกต่าง
Bootstrap 159 KB 132 KB 17%
บูลมา 184 KB 164 KB 10.9%
รากฐาน 139 KB 118 KB 15.1%
UI ความหมาย 622 KB 569 KB 8.5%

คู่มือปฏิบัติในการจัดส่งรหัสที่มีประสิทธิภาพ

มันอาจจะชัดเจนว่าฉันจะไปกับเรื่องนี้ หากเราใช้ประโยชน์จากไพพ์ไลน์ของบิลด์ที่มีอยู่เพื่อจัดส่งเลเยอร์ความเข้ากันได้เหล่านี้ไปยังเบราว์เซอร์ที่ต้องการเท่านั้น เราสามารถมอบประสบการณ์ที่เบากว่าให้กับผู้ใช้ที่เหลือของเรา — ผู้ที่เป็นคนส่วนใหญ่ — ในขณะที่ยังคงความเข้ากันได้สำหรับเบราว์เซอร์รุ่นเก่า

บันเดิลสมัยใหม่มีขนาดเล็กกว่าบันเดิลดั้งเดิมเนื่องจากข้ามบางเลเยอร์ที่เข้ากันได้
การฟอร์กการรวมกลุ่มของเรา (ดูรุ่นใหญ่)

ความคิดนี้ไม่ใช่เรื่องใหม่ทั้งหมด บริการต่างๆ เช่น Polyfill.io เป็นการพยายามสร้างสภาพแวดล้อมเบราว์เซอร์แบบ polyfill แบบไดนามิก ณ รันไทม์ แต่วิธีการเช่นนี้ประสบข้อบกพร่องบางประการ:

  • การเลือกโพลีฟิลจะจำกัดเฉพาะรายการที่ระบุไว้ในบริการ เว้นแต่คุณจะโฮสต์และดูแลรักษาบริการด้วยตัวเอง
  • เนื่องจาก polyfilling เกิดขึ้นที่รันไทม์และเป็นการดำเนินการบล็อก เวลาในการโหลดหน้าเว็บจึงสูงขึ้นอย่างมากสำหรับผู้ใช้ในเบราว์เซอร์รุ่นเก่า
  • การให้บริการไฟล์ polyfill แบบกำหนดเองแก่ผู้ใช้ทุกคนจะแนะนำเอนโทรปีให้กับระบบ ซึ่งทำให้การแก้ไขปัญหายากขึ้นเมื่อมีสิ่งผิดปกติเกิดขึ้น

นอกจากนี้ ยังไม่สามารถแก้ปัญหาเรื่องน้ำหนักที่เพิ่มโดยการทรานสพิลของโค้ดแอปพลิเคชัน ซึ่งบางครั้งอาจมีขนาดใหญ่กว่าโพลิฟิลเอง

มาดูกันว่าเราจะแก้ปัญหาที่มาของอาการบวมได้อย่างไรที่เราเคยพบมาจนถึงตอนนี้

เครื่องมือที่เราต้องการ

  • เว็บแพ็ค
    นี่จะเป็นเครื่องมือสร้างของเรา แม้ว่ากระบวนการจะยังคงคล้ายกับเครื่องมือสร้างอื่นๆ เช่น Parcel และ Rollup
  • รายการเบราว์เซอร์
    ด้วยเหตุนี้ เราจะจัดการและกำหนดเบราว์เซอร์ที่เราต้องการสนับสนุน
  • และเราจะใช้ ปลั๊กอินสนับสนุน Browserslist บางตัว

1. การกำหนดเบราว์เซอร์ที่ทันสมัยและดั้งเดิม

อันดับแรก เราต้องการทำให้ชัดเจนว่าเบราว์เซอร์ "ทันสมัย" และ "ดั้งเดิม" หมายถึงอะไร เพื่อความสะดวกในการบำรุงรักษาและทดสอบ การแบ่งเบราว์เซอร์ออกเป็นสองกลุ่มแยกกัน: การเพิ่มเบราว์เซอร์ที่ไม่ต้องการ polyfilling หรือ transpilation เพียงเล็กน้อยหรือไม่มีเลยในรายการที่ทันสมัยของเรา และวางส่วนที่เหลือในรายการเดิมของเรา

ไฟร์ฟอกซ์ >= 53; ขอบ >= 15; โครม >= 58; iOS >= 10.1
เบราว์เซอร์ที่รองรับ ES6+, แอตทริบิวต์ CSS ใหม่ และ API ของเบราว์เซอร์ เช่น Promises and Fetch (ดูรุ่นใหญ่)

การกำหนดค่า Browserslist ที่รูทของโปรเจ็กต์ของคุณสามารถจัดเก็บข้อมูลนี้ได้ ส่วนย่อย "สภาพแวดล้อม" สามารถใช้เพื่อจัดทำเอกสารกลุ่มเบราว์เซอร์สองกลุ่มได้ดังนี้:

 [modern] Firefox >= 53 Edge >= 15 Chrome >= 58 iOS >= 10.1 [legacy] > 1%

รายการที่ระบุในที่นี้เป็นเพียงตัวอย่างเท่านั้น และสามารถปรับแต่งและอัปเดตได้ตามความต้องการของเว็บไซต์และเวลาที่มี การกำหนดค่านี้จะทำหน้าที่เป็นแหล่งที่มาของความจริงสำหรับชุดข้อมูลส่วนหน้าสองชุดที่เราจะสร้างต่อไป ชุดหนึ่งสำหรับเบราว์เซอร์รุ่นใหม่และชุดหนึ่งสำหรับผู้ใช้อื่นๆ ทั้งหมด

2. ES6+ ขนย้ายและโพลีฟิลลิ่ง

เพื่อแปลงจาวาสคริปต์ของเราในลักษณะที่คำนึงถึงสิ่งแวดล้อม เราจะใช้ babel-preset-env

เริ่มต้นไฟล์ .babelrc ที่รูทของโปรเจ็กต์ด้วยสิ่งนี้:

 { "presets": [ ["env", { "useBuiltIns": "entry"}] ] }

การเปิดใช้งานแฟ useBuiltIns ช่วยให้ Babel สามารถเลือกโพลีฟิลแบบบิวท์อินคุณลักษณะที่ได้รับการแนะนำโดยเป็นส่วนหนึ่งของ ES6+ เนื่องจากมันกรองโพลีฟิลให้รวมเฉพาะโพลีฟิลที่สภาพแวดล้อมต้องการ เราจึงลดค่าใช้จ่ายในการขนส่งด้วย babel-polyfill อย่างครบถ้วน

เพื่อให้แฟล็กนี้ใช้งานได้ เราจะต้องนำเข้า babel-polyfill ในจุดเริ่มต้นของเราด้วย

 // In import "babel-polyfill";

การทำเช่นนี้จะแทนที่การนำเข้า babel-polyfill ขนาดใหญ่ด้วยการนำเข้าที่ละเอียด ซึ่งกรองโดยสภาพแวดล้อมของเบราว์เซอร์ที่เรากำหนดเป้าหมาย

 // Transformed output import "core-js/modules/es7.string.pad-start"; import "core-js/modules/es7.string.pad-end"; import "core-js/modules/web.timers"; …

3. คุณสมบัติแพลตฟอร์มเว็บ Polyfilling

ในการจัดส่งคุณสมบัติ polyfills สำหรับแพลตฟอร์มเว็บให้กับผู้ใช้ของเรา เราจะต้องสร้างจุดเริ่มต้นสองจุดสำหรับทั้งสองสภาพแวดล้อม:

 require('whatwg-fetch'); require('es6-promise').polyfill(); // … other polyfills

และนี่:

 // polyfills for modern browsers (if any) require('intersection-observer');

นี่เป็นขั้นตอนเดียวในโฟลว์ของเราที่ต้องมีการบำรุงรักษาด้วยตนเองในระดับหนึ่ง เราสามารถทำให้กระบวนการนี้เกิดข้อผิดพลาดน้อยลงได้โดยการเพิ่ม eslint-plugin-compat ให้กับโปรเจ็กต์ ปลั๊กอินนี้เตือนเราเมื่อเราใช้คุณลักษณะเบราว์เซอร์ที่ยังไม่ได้ polyfilled

4. CSS Prefixing

สุดท้ายนี้ เรามาดูกันว่าเราจะลด CSS นำหน้าสำหรับเบราว์เซอร์ที่ไม่ต้องการได้อย่างไร เนื่องจาก autoprefixer เป็นเครื่องมือแรกในระบบนิเวศที่รองรับการอ่านจากไฟล์การกำหนดค่ารายการ browserslist เราจึงไม่ต้องทำอะไรมาก

การสร้างไฟล์การกำหนดค่า PostCSS อย่างง่ายที่รูทของโปรเจ็กต์ควรเพียงพอ:

 module.exports = { plugins: [ require('autoprefixer') ], }

วางมันทั้งหมดเข้าด้วยกัน

ตอนนี้เราได้กำหนดการกำหนดค่าปลั๊กอินที่จำเป็นทั้งหมดแล้ว เราสามารถรวบรวมการกำหนดค่า webpack ที่อ่านข้อมูลเหล่านี้และส่งออกบิลด์สองส่วนแยกกันในโฟลเดอร์ dist/modern และ dist/legacy

 const MiniCssExtractPlugin = require('mini-css-extract-plugin') const isModern = process.env.BROWSERSLIST_ENV === 'modern' const buildRoot = path.resolve(__dirname, "dist") module.exports = { entry: [ isModern ? './polyfills.modern.js' : './polyfills.legacy.js', "./main.js" ], output: { path: path.join(buildRoot, isModern ? 'modern' : 'legacy'), filename: 'bundle.[hash].js', }, module: { rules: [ { test: /\.jsx?$/, use: "babel-loader" }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'] } ]}, plugins: { new MiniCssExtractPlugin(), new HtmlWebpackPlugin({ template: 'index.hbs', filename: 'index.html', }), }, };

ในการดำเนินการให้เสร็จสิ้น เราจะสร้างคำสั่งบิลด์สองสามคำสั่งในไฟล์ package.json ของเรา:

 "scripts": { "build": "yarn build:legacy && yarn build:modern", "build:legacy": "BROWSERSLIST_ENV=legacy webpack -p --config webpack.config.js", "build:modern": "BROWSERSLIST_ENV=modern webpack -p --config webpack.config.js" }

แค่นั้นแหละ. ตอนนี้งาน yarn build วิ่งควรให้เราสองงานสร้าง ซึ่งเทียบเท่าในหน้าที่การใช้งาน

การให้บริการ Bundle ที่เหมาะสมแก่ผู้ใช้

การสร้างบิลด์ที่แยกจากกันช่วยให้เราบรรลุเป้าหมายเพียงครึ่งแรกเท่านั้น เรายังจำเป็นต้องระบุและให้บริการชุดข้อมูลที่ถูกต้องแก่ผู้ใช้

จำการกำหนดค่า Browserslist ที่เรากำหนดไว้ก่อนหน้านี้หรือไม่ คงจะดีไม่น้อยถ้าเราสามารถใช้การกำหนดค่าเดียวกันเพื่อกำหนดว่าผู้ใช้อยู่ในหมวดหมู่ใด

ป้อน browserslist-usergent ตามชื่อที่แนะนำ browserslist-useragent สามารถอ่านการกำหนดค่า browserslist ของเราแล้วจับคู่ตัวแทนผู้ใช้กับสภาพแวดล้อมที่เกี่ยวข้อง ตัวอย่างต่อไปนี้สาธิตสิ่งนี้กับเซิร์ฟเวอร์ Koa:

 const Koa = require('koa') const app = new Koa() const send = require('koa-send') const { matchesUA } = require('browserslist-useragent') var router = new Router() app.use(router.routes()) router.get('/', async (ctx, next) => { const useragent = ctx.get('User-Agent') const isModernUser = matchesUA(useragent, { env: 'modern', allowHigherVersions: true, }) const index = isModernUser ? 'dist/modern/index.html', 'dist/legacy/index.html' await send(ctx, index); });

ในที่นี้ การตั้งค่าสถานะ allowHigherVersions ช่วยให้มั่นใจได้ว่าหากมีการเปิดตัวเบราว์เซอร์เวอร์ชันใหม่ ซึ่งยังไม่ได้เป็นส่วนหนึ่งของฐานข้อมูลของ Can I Use เบราว์เซอร์เหล่านั้นจะยังรายงานว่าเป็นจริงสำหรับเบราว์เซอร์สมัยใหม่

หนึ่งในหน้าที่ของ browserslist-useragent คือการตรวจสอบให้แน่ใจว่าได้คำนึงถึงความไม่ชอบมาพากลของแพลตฟอร์มในขณะที่จับคู่ตัวแทนผู้ใช้ ตัวอย่างเช่น เบราว์เซอร์ทั้งหมดบน iOS (รวมถึง Chrome) ใช้ WebKit เป็นเอ็นจิ้นพื้นฐาน และจะจับคู่กับการค้นหารายการเบราว์เซอร์เฉพาะของ Safari

อาจไม่รอบคอบที่จะพึ่งพาความถูกต้องของการแยกวิเคราะห์ user-agent ในการผลิตเท่านั้น โดยการย้อนกลับไปใช้กลุ่มเดิมสำหรับเบราว์เซอร์ที่ไม่ได้กำหนดไว้ในรายการสมัยใหม่ หรือมีสตริง user-agent ที่ไม่รู้จักหรือแยกวิเคราะห์ไม่ได้ เรารับรองว่าเว็บไซต์ของเรายังคงใช้งานได้

สรุป: มันคุ้มค่าหรือไม่

เราได้จัดการเพื่อให้ครอบคลุมขั้นตอนแบบ end-to-end สำหรับการจัดส่งชุดรวมที่ปราศจากการบวมไปยังลูกค้าของเรา แต่มีเหตุผลเพียงเท่านั้นที่จะสงสัยว่าค่าใช้จ่ายในการบำรุงรักษาที่เพิ่มขึ้นในโครงการนั้นคุ้มค่ากับผลประโยชน์หรือไม่ มาประเมินข้อดีข้อเสียของวิธีนี้กัน:

1. การบำรุงรักษาและการทดสอบ

จำเป็นต้องมีหนึ่งรายการเพื่อรักษาการกำหนดค่า Browserslist เดียวที่ขับเคลื่อนเครื่องมือทั้งหมดในไปป์ไลน์นี้ การอัปเดตคำจำกัดความของเบราว์เซอร์รุ่นเก่าและรุ่นใหม่สามารถทำได้ทุกเมื่อในอนาคต โดยไม่ต้องปรับโครงสร้างใหม่เพื่อรองรับการกำหนดค่าหรือโค้ด ฉันขอยืนยันว่าสิ่งนี้ทำให้ค่าบำรุงรักษาแทบไม่มีความสำคัญ

อย่างไรก็ตาม มีความเสี่ยงทางทฤษฎีเล็กน้อยที่เกี่ยวข้องกับการใช้ Babel เพื่อสร้างชุดโค้ดที่แตกต่างกันสองชุด ซึ่งแต่ละชุดต้องทำงานได้ดีในสภาพแวดล้อมที่เกี่ยวข้อง

แม้ว่าข้อผิดพลาดอันเนื่องมาจากความแตกต่างในกลุ่มอาจพบได้ยาก การตรวจสอบตัวแปรเหล่านี้เพื่อหาข้อผิดพลาดควรช่วยในการระบุและบรรเทาปัญหาอย่างมีประสิทธิภาพ

2. เวลาสร้างเทียบกับรันไทม์

ต่างจากเทคนิคอื่นๆ ที่แพร่หลายในปัจจุบัน การปรับให้เหมาะสมทั้งหมดเหล่านี้เกิดขึ้นในเวลาสร้างและลูกค้าจะมองไม่เห็น

3. ความเร็วที่เพิ่มขึ้นเรื่อย ๆ

ประสบการณ์ของผู้ใช้บนเบราว์เซอร์รุ่นใหม่จะเร็วขึ้นอย่างมาก ในขณะที่ผู้ใช้บนเบราว์เซอร์รุ่นเก่ายังคงได้รับบริการชุดเดียวกันเช่นเดิม โดยไม่มีผลกระทบด้านลบใดๆ

4. การใช้คุณลักษณะเบราว์เซอร์สมัยใหม่อย่างง่ายดาย

เรามักหลีกเลี่ยงการใช้คุณลักษณะใหม่ของเบราว์เซอร์เนื่องจากขนาดของโพลีฟิลที่จำเป็นต่อการใช้งาน ในบางครั้ง เรายังเลือกโพลีฟิลที่ไม่เป็นไปตามข้อกำหนดที่มีขนาดเล็กกว่าเพื่อประหยัดขนาด วิธีการใหม่นี้ช่วยให้เราใช้โพลีฟิลที่เป็นไปตามข้อกำหนดโดยไม่ต้องกังวลเกี่ยวกับผลกระทบกับผู้ใช้ทั้งหมดมากนัก

ชุดส่วนต่างที่ให้บริการในการผลิต

ด้วยข้อได้เปรียบที่สำคัญ เราจึงนำขั้นตอนการสร้างนี้มาใช้ในการสร้างประสบการณ์การชำระเงินผ่านมือถือสำหรับลูกค้าของ Urban Ladder ซึ่งเป็นหนึ่งในผู้ค้าปลีกเฟอร์นิเจอร์และของประดับตกแต่งที่ใหญ่ที่สุดในอินเดีย

ในชุดรวมที่ปรับให้เหมาะสมแล้ว เราสามารถบีบการประหยัดได้ประมาณ 20% สำหรับทรัพยากร CSS และ JavaScript ของ Gzip ที่ส่งไปยังผู้ใช้มือถือยุคใหม่ เนื่องจากมากกว่า 80% ของผู้เข้าชมรายวันของเราใช้เบราว์เซอร์ที่เป็นมิตรกับสิ่งแวดล้อมเหล่านี้ ความพยายามจึงคุ้มค่ากับผลกระทบ

แหล่งข้อมูลเพิ่มเติม

  • “การโหลด Polyfills เมื่อจำเป็นเท่านั้น”, Philip Walton
  • @babel/preset-env
    ที่ตั้งไว้ล่วงหน้า Babel ที่ชาญฉลาด
  • รายการเบราว์เซอร์ "เครื่องมือ"
    ระบบนิเวศของปลั๊กอินที่สร้างขึ้นสำหรับ Browserslist
  • ฉันสามารถใช้
    ตารางส่วนแบ่งการตลาดของเบราว์เซอร์ปัจจุบัน