{"id":15893809,"url":"https://github.com/chinanf-boy/react-worker-image-explain","last_synced_at":"2025-04-02T18:16:13.353Z","repository":{"id":90548499,"uuid":"120755683","full_name":"chinanf-boy/react-worker-image-explain","owner":"chinanf-boy","description":"explain : react-worker-image use worker fetch img 用 worker 加载图片❤️","archived":false,"fork":false,"pushed_at":"2018-02-08T11:58:41.000Z","size":1823,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T08:47:13.216Z","etag":null,"topics":["explain","react","react-worker-image","worker"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chinanf-boy.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-08T11:58:27.000Z","updated_at":"2018-02-09T08:09:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"c9e0c961-5916-4414-a814-c5638fb4a3e2","html_url":"https://github.com/chinanf-boy/react-worker-image-explain","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2Freact-worker-image-explain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2Freact-worker-image-explain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2Freact-worker-image-explain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chinanf-boy%2Freact-worker-image-explain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chinanf-boy","download_url":"https://codeload.github.com/chinanf-boy/react-worker-image-explain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246866100,"owners_count":20846496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["explain","react","react-worker-image","worker"],"created_at":"2024-10-06T08:13:47.042Z","updated_at":"2025-04-02T18:16:13.334Z","avatar_url":"https://github.com/chinanf-boy.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-worker-image\n\n「 React组件通过web worker获取图像资源 」\n\n[![explain](http://llever.com/explain.svg)](https://github.com/chinanf-boy/Source-Explain)\n\nExplanation\n\n\u003e \"version\": \"1.0.0\"\n\n[github source](https://github.com/nitish24p/react-worker-image)\n\n~~[english](./README.en.md)~~\n\n---\n\nreact-worker-image是一个用于通过web worker加载图像的React组件。从而不会阻塞主线程并加快页面加载时间。\n\n---\n\n## \b示例展示\n\n在两种情况下, 可以留意加载时间\n\n1. 第一个是通过webworker\n\n2. 第二个是\u003cimg \n\n![demo 展示](./screen.gif)\n\n---\n\n# 目录\n\n- [package](#package)\n\n- [flow-类型验证插件](#类型验证插件)\n\n- [react-import](#react-import)\n\n- [worker-js web worker 定义](#worker-js)\n\n- [js-flow-类型定义](#类型定义)\n\n- [高阶组件](#高阶组件)\n\n- [ImageWorker-Component](#ImageWorker-Component)\n\n- [重点🧡ImageWorker-react组件周期](#ImageWorker-react组件周期)\n\n- [重点🌟web-worker-信息传递](#web-worker-信息传递)\n\n---\n\n## package\n\n``` js\n\"main\": \"index.js\",\n```\n\n主文件 ·index.js·\n\n但是源代码中看不到·index.js· 再看\n\n``` js\n  \"scripts\": {\n    \"build\": \"NODE_ENV=production babel lib/ImageWorker.js --out-file index.js\", // 原来在这里, 看来真正的文件是\n    //lib/ImageWorker.js\n    \"prepublish\": \"npm run build\",\n    \"eslint\": \"node_modules/.bin/eslint -c ./.eslintrc.json ./lib/*\"\n  },\n```\n## ImageWorker\n\n本次解释的例子\n\n``` js\n\u003cImageWorker src='http://image-url' /\u003e\n```\n\n### 类型验证插件\n\n代码 1\n\n```\n/* @flow */\n```\n\n### react-import\n\n代码 3\n\n``` js\nimport React, { Component } from 'react'; // 导入 react\n\n```\n\n### worker-js\n\n代码 5-16\n\n``` js\n// worker-函数\nconst webWorkerScript = ` \n  self.addEventListener('message', event =\u003e {\n    const url = event.data;\n    fetch(url, {\n        method: 'GET',\n        mode: 'no-cors',\n        cache: 'default'\n    }).then(response =\u003e {\n        return response.blob();\n    }).then(_ =\u003e postMessage(url));\n  })\n`;\n```\n\n### 类型定义\n\n代码 19-30 \n\n``` js\ntype ImageWorkerProps = {\n  src: string,\n  placeholder?: string | Function,\n  style?: Object,\n  imageClass?: string,\n  containerClass?: string,\n}\n\ntype ImageWorkerState = {\n  isLoading: boolean,\n  imgSrc: string\n}\n```\n\n### 高阶组件\n\n高阶组件是，输入一个组件`input`, `return`一个带有-`input`组件变量的-\u003e `output`组件\n\n代码 33-35\n\n``` js\nconst wrappedComponent = WrappedComponent =\u003e props =\u003e {\n  return \u003cWrappedComponent {...props} /\u003e;\n};\n```\n\n### ImageWorker-Component\n\n继承react组件-的主组件\n\n代码 37\n\n``` js\nclass ImageWorker extends Component\u003cImageWorkerProps, ImageWorkerState\u003e {\n\n// 用 es6 语法 继承 react.Component\n// \u003e 记得用语法转为通用js,比如 babel\n// 并加以类型约束\n```\n\n#### ImageWorker-react组件周期\n\n代码 38-46\n\n``` js\n// 定义局部变量和类型\n  image: HTMLImageElement;\n  worker = new Worker(URL.createObjectURL(\n    new Blob([webWorkerScript], { type: 'application/javascript' })\n  )) // 启动以-webWorkerScript-的 Web worker\n\n  state = {\n    isLoading: true,\n    imgSrc: ''\n  }\n  // 局部存储\n```\n\n在 **ImageWorker Class** 中\n\n第一次运行顺序\n\n`constructor` -\u003e `render` -\u003e `componentDidMount` \n\n\u003e 分别是 初始化 -\u003e 载入 -\u003e 已载入后\n\n如果 `ImageWorker` 不再挂载\n\n -\u003e `componentWillUnmount`\n\n\u003e componentWillUnmount == 去除组件之前\n\n---\n\n4. componentWillUnmount 先搞定这里\n\n代码 58-64\n\n去除局部变量 去掉web worker\n\n``` js\n  componentWillUnmount() {\n    if (this.image) {\n      this.image.onload = null;\n      this.image.onerror = null;\n    }\n    this.worker.terminate();\n  }\n```\n---\n\n1. constructor\n\n代码 47-52\n\n``` js\n  constructor(props: ImageWorkerProps) {\n    super(props); // 父类初始化\n    // this.worker == 上面定义的worker\n    // 因为初始实例化 ImageWorker\n    this.worker.onmessage = (event: Object) =\u003e {\n      this.loadImage(event.data);\n    };\n    // 从 webWorkerScript 返回信息 - 获取信息后 - 处理\n  }\n```\n\n在这里, 就需要注意一下 `props`, 默认 react\n\n``` js\n\u003cImageWorker src='http://image-url' /\u003e // jsx\n// jsx -\u003e js\nImageWorker({src:'http://image-url'}) // js\n// props == {src:'http://image-url'}\n\n// constructor(props: ImageWorkerProps) \n```\n\n\u003e 获得的用户定义变量-放入-\u003e props -变量对象中\n\n---\n\n\n2. render\n\n代码 92-103\n\n``` js\n  render() {\n    const { style, imageClass, containerClass } = this.props;\n    return (\n      // jsx 用 HTML格式写 函数运行 的语法糖\n      \u003cdiv className={containerClass}\u003e\n        {\n          // 三元写法在，react的表达中很普遍\n          // something? true : false\n\n          // isLoading == true\n          this.state.isLoading ? this.renderPlaceholder() :\n            \u003cimg src={this.state.imgSrc}\n              style={{ ...style }} className={imageClass} alt='worker' /\u003e\n        }\n      \u003c/div\u003e\n    );\n  }\n```\n\n- this.renderPlaceholder\n\n``` js\n  renderPlaceholder() {\n    const { placeholder, style } = this.props; \n    // 没有定义, 本次例子中\n    if (typeof placeholder === 'function') { \n      const PlaceholderComponent = wrappedComponent(placeholder);\n      return \u003cPlaceholderComponent /\u003e;\n    } else if (typeof placeholder === 'string') {\n      return \u003cimg src={placeholder} style={{ ...style }} alt='placeholder' /\u003e;\n    } else {\n      return null; // \u003c---- 到这里，接下来-\u003ecomponentDidMount\n    }\n  }\n```\n\n---\n\n3. componentDidMount\n\n``` js\n  componentDidMount() {\n    this.worker.postMessage(this.props.src); // 传递图片路径 \n  }\n```\n\n---\n\n回顾一下 web worker 信息的传递顺序-第一步\n\n\u003e 1. `this.worker.postMessage` -\u003e \n\n\u003e 2. `webWorkerScript` 里面的 监听 `message`函数变量 e.data -\u003e\n\n\u003e 3. `webWorkerScript` 里面的 监听 message函数 `postMessage`(url) -\u003e\n\n\u003e 4. `this.worker.onmessage`\n\n### web-worker-信息传递\n\n\n1. 上面说了\n\n2. webWorkerScript\n\n``` js\n// worker-js-函数\nconst webWorkerScript = ` \n  self.addEventListener('message', event =\u003e {\n    const url = event.data;\n    fetch(url, {\n        method: 'GET',\n        mode: 'no-cors',\n        cache: 'default'\n    }).then(response =\u003e {\n        return response.blob();\n    }).then(_ =\u003e postMessage(url));\n  })\n`;\n```\n\n- [self.addEventListener worker的API]()\n\n监听获取信息的-函数\n\n将-`图片路径url`- 用 - `fetch` - 获取 - `blob 化` - `返回postMessage`-\u003e `this.worker.onmessage`\n\n3. postMessage 上面说了\n\n4. this.worker.onmessage\n\n``` js\n    this.worker.onmessage = (event: Object) =\u003e {\n      this.loadImage(event.data);\n    };\n  }\n```\n\n- this.loadImage\n\n代码 78-83\n\n``` js\n  loadImage = (url: string) =\u003e {\n    const image = new Image();\n    this.image = image;\n    image.onload = this.onLoad; // 加载后\n    image.src = url;\n  }\n```\n\n- this.onLoad\n\n代码 85-90\n\n``` js\n  onLoad = () =\u003e {\n    this.setState({\n      imgSrc: this.image.src,\n      isLoading: false\n    }); \n  }\n```\n\n`this.setState 改变了局部变量` 会推动 [render 重新运行](#render)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchinanf-boy%2Freact-worker-image-explain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchinanf-boy%2Freact-worker-image-explain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchinanf-boy%2Freact-worker-image-explain/lists"}