ওয়েবপ্যাকে আমি কীভাবে কোনও স্ক্রিপ্ট মূল্যায়ন না করে আমদানি করতে পারি?


9

আমি সম্প্রতি কয়েকটি ওয়েবসাইট অপ্টিমাইজেশনের কাজ করে যাচ্ছি এবং ওয়েবপ্যাকে কোড বিভাজনগুলি এই জাতীয় আমদানি বিবৃতি ব্যবহার করে শুরু করব:

import(/* webpackChunkName: 'pageB-chunk' */ './pageB')

কোনটি সঠিকভাবে তৈরি pageB-chunk.js , এখন এর আমি দিতে চান সে বিষয়ে আনয়ন করা pageA এই খণ্ড, আমি এটা করতে পারেন pageA মধ্যে এই বিবৃতি যোগ করুন:

import(/* webpackChunkName: 'pageB-chunk' */ /* webpackPrefetch: true */ './pageB')

যার ফলাফল ক

<link rel="prefetch" href="pageB-chunk.js">

এইচটিএমএল এর মাথায় সংযোজন করা হচ্ছে, তারপরে ব্রাউজারটি এটিকে উপস্থাপন করবে, এতদূর ভাল।

সমস্যাটি আমি এখানে যে আমদানি বিবৃতিটি ব্যবহার করি তা কেবল জেএস ফাইলটিকে উপস্থাপন করে না, জেএস ফাইলটিও মূল্যায়ন করে, তার মানে সেই জেএস ফাইলের কোডটি পার্স করা হয়েছে এবং বাইটকোডে সংকলন করা হয়েছে, সেই জেএসের শীর্ষ স্তরের কোডটি কার্যকর করা হয়েছে।

এটি একটি মোবাইল ডিভাইসে খুব সময়সাপেক্ষ অপারেশন এবং আমি এটি অনুকূল করতে চাই, আমি কেবল প্রিফেট অংশ চাই, আমি মূল্যায়ন ও সম্পাদনকারী অংশটি চাই না , কারণ পরে যখন কিছু ব্যবহারকারীর ইন্টারঅ্যাকশন ঘটে তখন আমি পার্সিংটি ট্রিগার করব & নিজেকে মূল্যায়ন

এখানে চিত্র বর্ণনা লিখুন

↑↑↑↑↑↑↑↑ আমি কেবলমাত্র প্রথম দুটি পদক্ষেপটি ট্রিগার করতে চাই, চিত্রগুলি https://clara.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/ থেকে এসেছে ↑↑↑↑↑↑↑ ↑↑

অবশ্যই আমি নিজেই প্রিফেচ লিঙ্কটি যুক্ত করে এটি করতে পারি, তবে এর অর্থ আমার জানতে হবে যে প্রিফেচ লিঙ্কে আমার কোন ইউআরএল রাখা উচিত, ওয়েবপ্যাকটি অবশ্যই এই ইউআরএলটি জানে, কীভাবে আমি ওয়েবপ্যাক থেকে এটি পেতে পারি?

ওয়েবপ্যাকের এ অর্জনের কোনও সহজ উপায় আছে?


if (false) import(…)- আমি সন্দেহ করি ওয়েবপ্যাকটি কি ডেড কোড বিশ্লেষণ করে?
বার্গি

কোথায় / যখন না আপনি আসলে মডিউল মূল্যায়ন করতে চান? ডায়নামিক importকোডটি সেখানেই যেতে হবে।
বার্গি

আমি এখন খুব বিভ্রান্ত। মূল্যায়ন কেন গুরুত্বপূর্ণ? কারণ শেষ পর্যন্ত, জেএস ফাইলটি ক্লায়েন্ট ব্রাউজার ডিভাইস দ্বারা মূল্যায়ন করা উচিত। অথবা আমি প্রশ্নটি সঠিকভাবে বুঝতে পারি না।
আমেরেলিকা

@ আমেরেলিকাএ শেষ পর্যন্ত হ্যাঁ জেএসগুলির মূল্যায়ন করা উচিত, তবে এই ক্ষেত্রেটি বিবেচনা করুন: আমার ওয়েবসাইট এ, বি দুটি পৃষ্ঠা পেয়েছে, পৃষ্ঠায় দর্শনার্থীরা পৃষ্ঠায় 'এ' পৃষ্ঠায় কিছু কাজ করার পরে প্রায়ই পৃষ্ঠাগুলি বি পরিদর্শন করে থাকে তবে বি পৃষ্ঠার প্রিফেট করা যুক্তিসঙ্গত হয় জেএস, তবে আমি যদি এই বি এর জেএস মূল্যায়ন করার সময়টি নিয়ন্ত্রণ করতে পারি, তবে আমি 100% নিশ্চিত করতে পারি যে আমি যখন প্রধান পৃষ্ঠায় ভিজিটর "তাদের কাজগুলি সম্পন্ন" করার চেষ্টা করছেন তখন গ্লিটগুলি তৈরি করে না তবে আমি মূল্যায়ন করতে পারি বি এর জেএস পরে পৃষ্ঠার বি'র দিকে নির্দেশিত একটি লিঙ্কে ক্লিক করুন, কিন্তু সেই সময়ে বি এর জেএস সম্ভবত ডাউনলোড করা হয়েছে, এটি মূল্যায়নের জন্য আমার কেবল একটু সময় ব্যয় করা প্রয়োজন।
মিজকোডার

অবশ্যই ক্রোম ভি 8 এর ব্লগ অনুসারে: v8.dev/blog/cost-of- javascript-2019 , তারা জ্বলজ্বলে দ্রুত জেএস পার্সিংয়ের সময় অর্জন করতে প্রচুর অপ্টিমাইজেশন করেছে, এখানে ওয়ার্কার থ্রেড এবং আরও অনেক প্রযুক্তি ব্যবহার করে, বিশদটি এখানে youtube.com / ঘড়ি? v = D1UJgiG4_NI । তবে অন্যান্য ব্রাউজারগুলি এখনও এই ধরনের অপ্টিমাইজেশন প্রয়োগ করে না।
মাইগকোডার

উত্তর:


2

হালনাগাদ

আপনি এইচটিএমএল -ওয়েবপ্যাক-প্লাগইন সহ প্রিলোড-ওয়েবপ্যাক-প্লাগইন ব্যবহার করতে পারেন এটি আপনাকে কনফিগারেশনে প্রিলোডটি নির্ধারণ করতে দেবে এবং এটি স্বয়ংক্রিয়ভাবে আপনার খণ্ডটি প্রিললোড করার জন্য ট্যাগগুলি সন্নিবেশ করবে

আপনি যদি এখন অবধি ওয়েবপ্যাক ভি 4 ব্যবহার করে থাকেন তবে আপনাকে এই প্লাগইনটি ব্যবহার করে ইনস্টল করতে হবে preload-webpack-plugin@next

উদাহরণ

plugins: [
  new HtmlWebpackPlugin(),
  new PreloadWebpackPlugin({
    rel: 'preload',
    include: 'asyncChunks'
  })
]

প্রজেক্টের জন্য গতিশীলভাবে উত্পন্ন নাম সহ দুটি অ্যাসিঙ্ক স্ক্রিপ্ট তৈরি করা হয় chunk.31132ae6680e598f8879.jsএবং যেমন chunk.d15e7fdfc91b34bb78c4.js, নীচের প্রিলোডগুলি নথিতে ইনজেকশনের ব্যবস্থা করা হবেhead

<link rel="preload" as="script" href="chunk.31132ae6680e598f8879.js">
<link rel="preload" as="script" href="chunk.d15e7fdfc91b34bb78c4.js">

আপডেট 2

আপনি যদি সমস্ত অ্যাসিঙ্ক অংশটি প্রিললোড করতে না চান তবে একবার নির্দিষ্ট করে আপনি এটি করতে পারেন

হয় আপনি মাইগকোডার বাবেল প্লাগইন ব্যবহার করতে পারেন বা এর preload-webpack-pluginমতো নিম্নলিখিতগুলি ব্যবহার করতে পারেন

  1. প্রথমে আপনাকে সেই অ্যাসিঙ্ক অংশটির webpack magic commentউদাহরণ দিতে হবে

    import(/* webpackChunkName: 'myAsyncPreloadChunk' */ './path/to/file')
  2. এবং তারপরে প্লাগইন কনফিগারেশনে সেই নামটি ব্যবহার করুন

    plugins: [
      new HtmlWebpackPlugin(),   
      new PreloadWebpackPlugin({
        rel: 'preload',
        include: ['myAsyncPreloadChunk']
      }) 
    ]
    

প্রথমে ব্রাউজারের আচরণটি দেখা যাক যখন আমরা স্ক্রিপ্টটি লোড করার জন্য scriptট্যাগ বা linkট্যাগ নির্দিষ্ট করি

  1. যখনই কোনও ব্রাউজার কোনও scriptট্যাগের মুখোমুখি হয় এটি এটিকে পার্স করে লোড করে সঙ্গে সঙ্গে এটিকে কার্যকর করে
  2. আপনি কেবল ইভেন্টের আগ পর্যন্ত কেবল সহায়তার সাথে ট্যাগ asyncএবং পার্সিং এবং মূল্যায়ন বিলম্ব করতে পারেনdeferDOMContentLoaded
  3. আপনি যদি স্ক্রিপ্ট ট্যাগটি সন্নিবেশ না করেন তবে আপনি কার্যকর করতে (মূল্যায়ন) বিলম্ব করতে পারেন (কেবল এটির সাথে প্রিলোড করুন link)

এখন প্রস্তাবিত হ্যাকির মতো আরও কিছু উপায় রয়েছে যা আপনি সম্পূর্ণ স্ক্রিপ্টটি প্রেরণ করেন এবং stringবা comment(কারণ মন্তব্য বা স্ট্রিংয়ের মূল্যায়নের সময়টি প্রায় নগণ্য) এবং যখন আপনি কার্যকর করতে পারেন যে আপনি ব্যবহার করতে পারেন Function() constructorবা evalউভয়ই প্রস্তাবিত নয়


আরেকটি পদ্ধতির পরিষেবা কর্মী: (এটি পৃষ্ঠা পুনরায় লোড করার পরে বা ক্যাশে লোড হওয়ার পরে ব্যবহারকারী অফলাইনে যাওয়ার পরে আপনাকে ক্যাশে ইভেন্ট সংরক্ষণ করবে)

আধুনিক ব্রাউজারে আপনি service workerএকটি পুনরুদ্ধার (জাভাস্ক্রিপ্ট, চিত্র, সিএসএস কিছু) আনতে এবং ক্যাশে করতে ব্যবহার করতে পারেন এবং যখন এই পুনরুদ্ধারের মূল থ্রেড অনুরোধ আপনি সেই অনুরোধটিকে বাধা দিতে পারেন এবং ক্যাশে থেকে এই পথটি ফেরত দিতে পারেন আপনি যখন স্ক্রিপ্টটিকে বিশ্লেষণ এবং মূল্যায়ন করছেন না তখন the আপনি এটিকে ক্যাশে লোড করছেন এখানে পরিষেবা কর্মীদের সম্পর্কে আরও পড়ুন

উদাহরণ

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      ]);
    })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(caches.match(event.request).then(function(response) {
    // caches.match() always resolves
    // but in case of success response will have value
    if (response !== undefined) {
      return response;
    } else {
      return fetch(event.request).then(function (response) {
        // response may be used only once
        // we need to save clone to put one copy in cache
        // and serve second one
        let responseClone = response.clone();

        caches.open('v1').then(function (cache) {
          cache.put(event.request, responseClone);
        });
        return response;
      }).catch(function () {
        // any fallback code here
      });
    }
  }));
});

যেহেতু আপনি দেখতে পাচ্ছেন এটি কোনও ওয়েবপ্যাক নির্ভর বিষয় নয় এটি ওয়েবপ্যাকের সুযোগের বাইরে নয় তবে ওয়েবপ্যাকের সাহায্যে আপনি নিজের বান্ডিলটি বিভক্ত করতে পারেন যা পরিষেবা কর্মীকে আরও ভালভাবে ব্যবহার করতে সহায়তা করবে


তবে এখনও আমার ব্যথার বিষয়টি হ'ল আমি ওয়েবপ্যাক থেকে সহজেই ফাইলটির ইউআরএল পেতে পারি না, এমনকি আমি এসডাব্লুয়ের সাথেও যাই, এখনও এসডাব্লুকে জানাতে হবে যে ফাইলগুলি প্রাক-ক্যাশে হওয়া উচিত তা ... একটি ওয়েবপ্যাক ম্যানিফেস্ট প্লাগইন এতে ম্যানিফেস্ট তথ্য উত্পন্ন করতে পারে এসডাব্লু, তবে এটি সবই চালু রয়েছে, এর অর্থ
এসডাব্লু এর

আদর্শভাবে, আমি আশা করি যে ওয়েবপ্যাকটি / * ওয়েবপ্যাকঅনলিপ্রিফেটের মতো আরও একটি যাদু মন্তব্য যুক্ত করতে পারে: সত্য * /, সুতরাং আমি প্রতিটি অলস লোডযোগ্যযোগ্য অংশের জন্য দু'বার আমদানি বিবৃতিটি কল করতে পারি, একটি প্রিফেচের জন্য, একটি কোড মূল্যায়নের জন্য, এবং চাহিদা অনুসারে সবকিছু ঘটে।
মাইগকোডার

1
@ মিগকোডার এটি একটি বৈধ পয়েন্ট (আপনি ফাইল নামটি পেতে পারেন না কারণ এটি রানটাইমের সময় ডায়নামিকভাবে উত্পন্ন হয়েছে) আমি যে কোনও সমাধান পেতে পারলে যে কোনও সমাধান দেখা যাবে
ত্রিপুরারী শঙ্কর

@ মিগকোডার আমি উত্তরটি আপডেট করে দিয়েছি দয়া করে এটি দেখুন যা আপনার সমস্যার সমাধান করে
ত্রিপুরারী শঙ্কর

এটি সমস্যার অংশটি সমাধান করে, এটি ভাল যে অ্যাসিঙ্ক খণ্ডগুলি ফিল্টার করতে পারে, তবে আমার চূড়ান্ত লক্ষ্যটি কেবলমাত্র পূর্বসূচী হিসাবে দাবি করা হয়েছে অ্যাসিঙ্ক অংশগুলি। আমি বর্তমানে এই প্লাগইনটি github.com/sebastian-software/babel-plugin-smart-webpack-importদেখছি , এটি আমাকে দেখায় যে কীভাবে সমস্ত আমদানি বিবৃতি সংগ্রহ করতে হবে এবং যাদু মন্তব্যের উপর কিছু কোড পরিবর্তন বেস করতে পারি, সম্ভবত আমি তৈরি করতে পারি 'ওয়েবপ্যাকঅনলিপ্রিফেট: ট্রু' ম্যাজিক মন্তব্য সহ আমদানির বিবৃতিগুলিতে প্রিফেক কোড সন্নিবেশ করার জন্য একটি অনুরূপ প্লাগইন।
মাইগকোডার

1

আপডেটগুলি: আমি সমস্ত কিছু এনপিএম প্যাকেজে অন্তর্ভুক্ত করেছি, এটি দেখুন! https://www.npmjs.com/package/webpack-prefetcher


কয়েক দিন গবেষণার পরে, আমি একটি কাস্টমাইজ বাবেল প্লাগইন লিখে শেষ করছি ...

সংক্ষেপে, প্লাগইন এটির মতো কাজ করে:

  • কোডে সমস্ত আমদানি (আরোগ) বিবৃতি সংগ্রহ করুন
  • যদি আমদানি (আর্টস) এ / * প্রিফেচ থাকে: সত্য * / মন্তব্য
  • আমদানি () বিবৃতি থেকে chunkId সন্ধান করুন
  • এটিকে Prefetcher.fetch (chunkId) দিয়ে প্রতিস্থাপন করুন

প্রিফেটচার হেল্পার ক্লাস যা ওয়েবপ্যাক আউটপুটের ম্যানিফেস্ট ধারণ করে এবং প্রিফেচ লিঙ্কটি সন্নিবেশ করায় আমাদের সহায়তা করতে পারে:

export class Prefetcher {
  static manifest = {
    "pageA.js": "/pageA.hash.js",
    "app.js": "/app.hash.js",
    "index.html": "/index.html"
  }
  static function fetch(chunkId) {
    const link = document.createElement('link')
    link.rel = "prefetch"
    link.as = "script"
    link.href = Prefetcher.manifest[chunkId + '.js']
    document.head.appendChild(link)
  }
}

একটি ব্যবহারের উদাহরণ:

const pageAImporter = {
  prefetch: () => import(/* prefetch: true */ './pageA.js')
  load: () => import(/* webpackChunkName: 'pageA' */ './pageA.js')
}

a.onmousehover = () => pageAImporter.prefetch()

a.onclick = () => pageAImporter.load().then(...)

এই প্লাগইনটির বিশদটি এখানে পাওয়া যাবে:

প্রিফেচ - ওয়েবপ্যাক থেকে নিয়ন্ত্রণ নিন

আবার, এটি একটি সত্যই হ্যাকি উপায় এবং আপনি এটি পছন্দ করেন না, আপনি যদি ওয়েবপ্যাক দল এটি প্রয়োগ করতে চান তবে দয়া করে এখানে ভোট দিন:

বৈশিষ্ট্য: চাহিদা অনুসারে প্রিফেট গতিশীল আমদানি


0

ধরে নিলাম আপনি কী অর্জন করতে চাইছেন তা আমি বুঝতে পেরেছি, আপনি কোনও নির্দিষ্ট ইভেন্টের পরে মডিউলটিকে বিশ্লেষণ এবং সম্পাদন করতে চান (যেমন একটি বোতামে ক্লিক করুন)। আপনি কেবল সেই ইভেন্টের অভ্যন্তরে আমদানি বিবৃতি দিতে পারেন:

element.addEventListener('click', async () => {
  const module = await import("...");
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.